ElasticSearch集成Spring之ElasticsearchTemplate
前面几篇我们学习了那么多ES知识,那么怎样运用到实际项目中去呢?本篇讲一讲ES与spring的集成,让ES能投入实际生产中去。
1、Maven依赖
<!-- elasticsearch的spring-data包 --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-elasticsearch</artifactId> <version>x.y.z.RELEASE</version> </dependency> <!-- elasticsearch客户端,version填入本地安装好的ES版本号 --> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>x.y.z</version> </dependency>
spring-data-elasticsearch与elasticsearch的版本对应关系:
spring data elasticsearch | elasticsearch |
---|---|
3.2.x | 6.5.0 |
3.1.x | 6.2.2 |
3.0.x | 5.5.0 |
2.1.x | 2.4.0 |
2.0.x | 2.2.0 |
1.3.x | 1.5.2 |
maven仓库中的spring-data-elasticsearch版本:https://mvnrepository.com/artifact/org.springframework.data/spring-data-elasticsearch
注意:截止到 2018-12-17,一直还没有出3.2.x,如果你使用的elasticsearch是6.5.0以上的版本,建议elasticsearch降低到6.2.2,否则会出现很多未知的错误,这是个坑!
2、添加xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd"> <!-- 扫描包路径 --> <elasticsearch:repositories base-package="com.demo.elasticsearch.*" /> <!-- 声明elasticsearch客户端 --> <elasticsearch:transport-client id="client" cluster-nodes="localhost:9300" cluster-name="home" /> <!-- 声明elasticsearchTemplate --> <bean name="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate"> <constructor-arg name="client" ref="client" /> </bean> </beans>
3、使用elasticsearchTemplate
创建BookEntity实体:
public class BookEntity { private String author; private String name; private String id; }
引用elasticsearchTemplate
@Autowired private ElasticsearchTemplate elasticsearchTemplate;
创建索引
// 1、直接用名称创建 elasticsearchTemplate.createIndex("book"); // 2、填入class对象 elasticsearchTemplate.createIndex(BookEntity.class);
创建数据
单条数据:
BookEntity bookEntity = new BookEntity(); bookEntity.setId("2"); bookEntity.setAuthor("老李"); bookEntity.setName("一起学习es"); IndexQuery indexQuery = new IndexQueryBuilder() .withId(bookEntity.getId()) .withObject(bookEntity) .build(); elasticsearchTemplate.index(indexQuery);
多条数据:
BookEntity bookEntity = new BookEntity(); bookEntity.setId("2"); bookEntity.setAuthor("老李"); bookEntity.setName("一起学习netty"); IndexQuery indexQuery1 = new IndexQueryBuilder() .withId(bookEntity.getId()) .withObject(bookEntity) .build(); // elasticsearchTemplate.index(indexQuery); indexQueries.add(indexQuery1); BookEntity bookEntity2 = new BookEntity(); bookEntity.setId("3"); bookEntity.setAuthor("老刘"); bookEntity.setName("netty菜鸟入门"); IndexQuery indexQuery2 = new IndexQueryBuilder() .withId(bookEntity2.getId()) .withObject(bookEntity) .build(); indexQueries.add(indexQuery2); elasticsearchTemplate.bulkIndex(indexQueries);
单字符串查询
SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.queryStringQuery("菜鸟")) .withPageable(new PageRequest(0, 20)) .build(); List<BookEntity> list = elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
排序
Pageable pageable= new PageRequest(0, 20,new Sort(Sort.Direction.DESC, "name")); SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.queryStringQuery("菜鸟")) .withPageable(pageable) .build(); Page<BookEntity> list = elasticsearchTemplate.queryForPage(searchQuery, BookEntity.class);
注意:如果出现此异常
java.lang.IllegalArgumentException: Fielddata is disabled on text fields by default
官方解释5.x后对排序,聚合这些操作用单独的数据结构(fielddata)缓存到内存里了,需要单独开启(主要是占用资源太多,所以是否开启,需要仔细斟酌)
关于fielddata更多内容:https://www.elastic.co/guide/en/elasticsearch/reference/current/fielddata.html
模糊查询
此模糊查询与mysql中的模糊查询不太一样,此模糊查询类似分词匹配。
比如有两条数据:1、我今天非常高兴 2、他摔倒很高兴
输入:今天高兴
这两条数据都能匹配上。
Pageable pageable = new PageRequest(0, 10); SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.matchQuery("name", "菜鸟")) .withPageable(pageable) .build(); List<BookEntity> list = elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
其余匹配
其余匹配类似mysql中like "%word%"的模糊匹配
Pageable pageable = new PageRequest(0, 10); SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.matchPhraseQuery("name", "菜鸟")) .withPageable(pageable) .build(); List<BookEntity> list = elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
Term全等查询
Pageable pageable = new PageRequest(0, 10); SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.termQuery("name", "菜鸟")) .withPageable(pageable) .build(); List<BookEntity> list = elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
组合查询
即boolQuery,可以设置多个条件的查询方式。它的作用是用来组合多个Query,有四种方式来组合,must,mustnot,filter,should。
must代表返回的文档必须满足must子句的条件,会参与计算分值;
filter代表返回的文档必须满足filter子句的条件,但不会参与计算分值;
should代表返回的文档可能满足should子句的条件,也可能不满足,有多个should时满足任何一个就可以,通过minimum_should_match设置至少满足几个。
mustnot代表必须不满足子句的条件。
QueryBuilder filterQuery = QueryBuilders .boolQuery() .filter(QueryBuilders.termQuery("name", "菜鸟")) .filter(QueryBuilders.termQuery("author", "小菜")); List<BookEntity> list = elasticsearchTemplate.queryForList(filterQuery, BookEntity.class);
结束
更多关于QueryBuilders的用法,可以看看elasticsearch的QueryBuilders类,或者查看文档:http://xbib.org/elasticsearch/2.1.1/apidocs/org/elasticsearch/index/query/QueryBuilders.html
更多关于ElasticsearchTemplate的用法,可以查看源码,或者查看文档:https://docs.spring.io/spring-data/elasticsearch/docs/current/api/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.html