上一篇中,我们为同学们讲解了如何安装elasticsearch(下面简称es),如果还没有es环境的同学,可以阅读Linux 安装Elasticsearch和配置ik分词器步骤 来将es的环境先都准备好,今天我们要做的是将es融入到我们的java项目中,还是一如既往,我们还是使用springboot来创建一个项目。好了。废话不多说,上流程。
我们在什么情况下会使用到es?搜索引擎当然是搜索的时候啦,一般在电商项目中,我们如果要按照分类或者关键字去搜索某些商品并且关键字还需要有一定的智能性(也就是能根据你的关键字找到关联商品)的话,我们总不能去数据库使用like来解决这种需求吧。
首先性能方面,每次都去查数据库本来效率上就是不高的,不然也就不会出现redis、solr或者es这类技术了,虽说有索引,但也是有一定的效率上的瓶颈的。
其次 like也无法满足我们所谓的智能性这个需求,你总不能说我把拿到的关键字再自己进行拆分吧,这就会面临这如何分词的问题。
考虑到以上的这些问题,此时我们的es闪亮登场了,es的效率自然是没话说,关于分词,虽然他本身自带的分词器并不是很理想,但是在之前的文章中,我们也配置了ik分词器,所以此情此景下,自然是使用es是明智的选择。
那么我们到底该如何将es融入到我们的springboot项目并且如何使用api对es进行增删改查的一系列操作呢?
本次内容的重点在于es,因此不在创建springboot的项目和一些配置上浪费过多的时间了,只做简单的截图,如果有不清楚的同学,可以查看此篇文章来看如何创建一个springboot项目 java 搭建基于springboot的ssh(spring + springmvc + hibernate)的gradle项目(基础篇)
2.2.1 引入gradle依赖
首先我们需要引入es的jar包,在build.gradle中添加依赖
//搜索包
compile(‘org.springframework.boot:spring-boot-starter-data-elasticsearch’)
2.2.2 配置远程连接es地址
其次,我们需要配置es需要远程连接的地址,在application.properties配置文件中添加如下配置
#es的默认名称,如果安装es时没有做特殊的操作名字都是此名称
spring.data.elasticsearch.cluster-name=elasticsearch
#连接的远程地址,端口号一定要是9300,不要写成9200
spring.data.elasticsearch.cluster-nodes=你的ip:9300
management.health.elasticsearch.enabled=false
1.首先在search的entity中创建MyEsEntity类,具体内容如下
package com.beyondli.search.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
/**
* Created by beyondLi
* Date 2017/11/21
* Desc .
*/
//lombok注解(可自己手动创建getset以及有参无参构造来代替)
@Data
@NoArgsConstructor
@AllArgsConstructor
//es注解,设置索引名称以及类型
@Document(indexName = "myes", type = "info")
public class MyEsEntity {
//id(需要添加@Id注解,或会自动识别名称为id的字段为id,其余字段没有限制)
@Id
private Integer id;
//名称
private String name;
//性别
private String sex;
//年龄
private Integer age;
}
2.创建MyEsRepository接口来继承ElasticsearchRepository从而达到拿到连接es的实体类的目的,具体内容如下
package com.beyondli.search;
import com.beyondli.search.entity.MyEsEntity;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
/**
* Created by beyondLi
* Date 2017/11/21
* Desc es的接口
*/
//MyEsEntity为要存的数据的类型,Integer为@id的类型
public interface MyEsRepository extends ElasticsearchRepository<MyEsEntity, Integer> {
}
好了,前期的准备工作已经完成了,现在我们开始对es进行增删改查操作,具体代码解释都会放到注释中,请各位同学仔细阅读。
rest层
package com.beyondli.rest;
import com.beyondli.search.entity.MyEsEntity;
import com.beyondli.service.EsTestService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* Created by beyondLi
* Date 2017/11/21
* Desc .
*/
@RestController
@RequestMapping(value = "/es/test")
public class EsTest {
@Resource
EsTestService esTestService;
@RequestMapping(value = "/add")
public void add() {
//创建类
MyEsEntity myEsEntity = new MyEsEntity();
myEsEntity.setId(1);
//为了后期显示出ik分词器的效果,名字起了一个商品的名称
myEsEntity.setName("五常大米");
myEsEntity.setSex("man");
myEsEntity.setAge(18);
esTestService.add(myEsEntity);
}
}
service层
package com.beyondli.service;
import com.beyondli.search.MyEsRepository;
import com.beyondli.search.entity.MyEsEntity;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Created by beyondLi
* Date 2017/11/21
* Desc .
*/
@Service
public class EsTestServiceImpl implements EsTestService {
@Resource
MyEsRepository myEsRepository;
/**
* 新增
* @param myEsEntity
*/
@Override
public void add(MyEsEntity myEsEntity) {
myEsRepository.save(myEsEntity);
}
}
好了,新增就是如此的容易,因为我们的MyEsRepository 继承了es的ElasticsearchRepository类,所以自带了增删改查的aip,我们只要按照其aip规范进行操作即可。
我们来根据id进行删除操作
rest层
@RequestMapping(value = "/delete")
public void delete() {
esTestService.delete();
}
service层
/**
* 删除
*/
@Override
public void delete() {
//根据id,或者传入查到的entity对象也可以
myEsRepository.delete(1);
}
其实修改的思路 是先将数据查出,然后再调用save也就是保存操作,根据id将其数据覆盖掉即可,所以你会发现aip中并没有类似于update的方法,因为不存在新的aip,所以就不提供demo了,相信各位同学一定是可以举一反三的按照上面的思路来解决修改这个问题的。
重头戏!重头戏!我们为了什么才加的搜索引擎? 查询!!!现在才是重点,相信使用过JPA的同学接受查询这些aip的操作和思路的时候一定会特别顺手特别的快。
es对查询的操作个人感觉支持的还是非常好的,包括模糊查询、排序、分页等等等一般sql能想到的需求你会发现他都有支持的api,好了废话不多说,上demo。
我们先添加一些数据到es中为了我们一会能展现更多的操作,如图所示
我们现在的需求是根据五常米搜索出所有名称带五常和米字的信息并且性别为man年龄从高到底排序且进行一页显示二条的分页操作
rest层
@RequestMapping(value = "/select")
public List select() {
List myEsEntity = esTestService.select();
return myEsEntity;
}
service层(重点)
public List select() {
//创建builder
BoolQueryBuilder builder = QueryBuilders.boolQuery();
//builder下有must、should以及mustNot 相当于sql中的and、or以及not
//设置模糊搜索
builder.must(QueryBuilders.fuzzyQuery("name", "五常米"));
//设置性别必须为man
builder.must(new QueryStringQueryBuilder("man").field("sex"));
//按照年龄从高到低
FieldSortBuilder sort = SortBuilders.fieldSort("age").order(SortOrder.DESC);
//设置分页(拿第一页,一页显示两条)
//注意!es的分页api是从第0页开始的(坑)
PageRequest page = new PageRequest(0, 2);
//构建查询
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
//将搜索条件设置到构建中
nativeSearchQueryBuilder.withQuery(builder);
//将分页设置到构建中
nativeSearchQueryBuilder.withPageable(page);
//将排序设置到构建中
nativeSearchQueryBuilder.withSort(sort);
//生产NativeSearchQuery
NativeSearchQuery query = nativeSearchQueryBuilder.build();
//执行
Page search = myEsRepository.search(query);
//获取总条数(前端分页需要使用)
int total = (int) search.getTotalElements();
//获取查询到的数据内容
List content = search.getContent();
//为了方便我就不显示总条数了,只在控制台给各位同学打印总条数看一下了
System.out.println(total);
return content;
分页总条数
好了,以上就是springboot结合es的一些基本操作api,灵活运用已经可以完成大部分的需求,希望可以对各位同学有所帮助。
源码地址献上
http://download.csdn.net/download/liboyang71/10127429