参考:https://docs.spring.io/spring-data/elasticsearch/docs/3.2.0.RC3/reference/html/#preface.versions
Spring Data Elasticsearch、Elasticsearch 对应版本
Spring Data Elasticsearch | Elasticsearch |
---|---|
3.2.x | 6.8.1 |
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 |
Spring Boot、Spring Data Elasticsearch、Elasticsearch 对应版本
Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Boot |
---|---|---|---|
Neumann[1] | 4.0.x[1] | 7.6.2 | 2.3.x[1] |
Moore | 3.2.x | 6.8.6 | 2.2.x |
Lovelace | 3.1.x | 6.2.2 | 2.1.x |
Kay[2] | 3.0.x[2] | 5.5.0 | 2.0.x[2] |
Ingalls[2] | 2.1.x[2] | 2.4.0 | 1.5.x[2] |
dome参考:https://github.com/spring-projects/spring-data-examples/tree/master/elasticsearch
官方推荐:https://www.elastic.co/guide/en/elasticsearch/client/index.html
- Transport Client 不推荐
- Java High Level REST Client 推荐
- Reactive REST Client 不推荐
默认 High Level REST Client
pom.xml
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>3.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.8.5</version>
</dependency>
*.yml
spring:
data:
elasticsearch:
repositories:
enabled: true # 启用 ElasticsearchTemplate
properties:
path:
logs: ./elasticsearch/log # ES日志存储目录
data: ./elasticsearch/data # ES数据存储目录
cluster-name: my-cluster # ES集群名称,在elasticsearch.yml中配置 默 elasticsearch
cluster-nodes: 127.0.0.1:9300 # ES集群节点 用逗号分隔 , java连接默9300,http连接默9200
实体类
@Data
@Document(indexName = "book_index", type = "book_type", indexStoreType = "fs", shards = 5, replicas = 1, refreshInterval = "-1")
public class BookEntity {
@Id
private String id;
private String title;
private String content;
private int userId;
private int weight;
}
Repository接口
@Component
public interface BookRepository extends ElasticsearchRepository<BookEntity, String> {
}
controller层
package com.zja.controller;
import com.zja.dao.BookRepository;
import com.zja.entity.BookEntity;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.web.bind.annotation.*;
import static org.elasticsearch.index.query.QueryBuilders.*;
/**
* @author [email protected]
* @data 2020/07/17 11:41
*/
@RestController
@Api(tags = {"BookElasticsearchController"}, description = "全文检索")
public class BookElasticsearchController {
@Autowired
ElasticsearchTemplate elasticsearchTemplate;
@Autowired
BookRepository bookRepository;
@ApiOperation(value = "添加索引", httpMethod = "POST")
@PostMapping(value = "v1/book/add/{id}")
public Object addbook(@ApiParam(defaultValue = "50") @PathVariable String id) {
//创建索引
// 1、直接用名称创建索引
//boolean indexRes = elasticsearchTemplate.createIndex("book_es");
// 2、填入class对象创建索引
//boolean indexRes = elasticsearchTemplate.createIndex(BookEntity.class);
//System.out.println("======创建索引结果:" + indexRes + "=========");
BookEntity bookEntity = new BookEntity();
bookEntity.setId(id);
bookEntity.setTitle("浣溪沙");
bookEntity.setContent("宋·李清照 莫许杯深琥珀浓,未成沉醉意先融。疏钟已应晚来风。瑞脑香消魂梦断");
bookEntity.setUserId(51);
bookEntity.setWeight(100);
IndexQuery indexQuery = new IndexQueryBuilder()
.withId(bookEntity.getId())
.withObject(bookEntity)
.build();
String index = elasticsearchTemplate.index(indexQuery);
//BookEntity document = bookRepository.save(bookEntity);
return index;
}
@ApiOperation(value = "查询全部内容", httpMethod = "GET")
@GetMapping(value = "v1/book/srarch/all")
public Object srarch() {
return bookRepository.findAll();
}
@ApiOperation(value = "根据id查询内容", httpMethod = "GET")
@GetMapping(value = "v1/book/srarch/id")
public Object srarch(@ApiParam(defaultValue = "50") @RequestParam String id) {
return bookRepository.findById(id);
}
@ApiOperation(value = "根据id更新内容", httpMethod = "PUT")
@PutMapping(value = "v1/book/srarch/updete")
public Object updete(@ApiParam(defaultValue = "50") @RequestParam String id) {
BookEntity bookEntity = new BookEntity();
bookEntity.setId(id);
bookEntity.setTitle("浣溪沙2");
bookEntity.setContent("宋·李清照 莫许杯深琥珀浓,未成沉醉意先融。疏钟已应晚来风。瑞脑香消魂梦断");
bookEntity.setUserId(55);
bookEntity.setWeight(102);
return bookRepository.save(bookEntity);
}
@ApiOperation(value = "单字符串全文模糊查询Ex", httpMethod = "GET")
@GetMapping(value = "v1/book/srarch/ex")
public Object srarchEx(@ApiParam(value = "查询内容", defaultValue = "浣溪沙") @RequestParam String content,
@ApiParam(value = "当前页", defaultValue = "0") @RequestParam int page,
@ApiParam(value = "显示多少条", defaultValue = "20") @RequestParam int size) {
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.queryStringQuery(content)).withPageable(PageRequest.of(page, size)).build();
return bookRepository.search(searchQuery);
}
@ApiOperation(value = "多字段的匹配查询Ex", httpMethod = "GET")
@GetMapping(value = "v1/book/srarch/queryBuilder")
public Object srarchQueryBuilder(@ApiParam(value = "查询内容", defaultValue = "浣溪沙") @RequestParam String title) {
MultiMatchQueryBuilder queryBuilder = multiMatchQuery(title, "title", "content");
return bookRepository.search(queryBuilder);
}
@ApiOperation(value = "单字符串全文模糊查询", notes = "查询全部字段内容", httpMethod = "GET")
@GetMapping(value = "v1/book/srarch")
public Object srarch(@ApiParam(value = "查询内容", defaultValue = "浣溪沙") @RequestParam String content,
@ApiParam(value = "当前页", defaultValue = "0") @RequestParam int page,
@ApiParam(value = "显示多少条", defaultValue = "20") @RequestParam int size) {
//使用queryStringQuery完成单字符串查询
//单字符串默认模糊查询,默认排序。将从所有字段中查找包含传来的content分词后字符串的数据集
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.queryStringQuery(content)).withPageable(PageRequest.of(page, size)).build();
return elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
}
@ApiOperation(value = "某字段字符串模糊查询", notes = "将从所有字段中查找包含传来的content分词后字符串的数据集", httpMethod = "GET")
@GetMapping(value = "v1/book/srarch/matchQuery")
public Object srarchMatchQuery(@ApiParam(value = "查询内容", defaultValue = "浣溪沙") @RequestParam String content,
@ApiParam(value = "当前页", defaultValue = "0") @RequestParam int page,
@ApiParam(value = "显示多少条", defaultValue = "20") @RequestParam int size) {
//某字段(content)字符串模糊查询
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("content", content)).withPageable(PageRequest.of(page, size)).build();
return elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
}
@ApiOperation(value = "短语匹配", notes = "短语必须是连续的 不知归路 不归路", httpMethod = "GET")
@GetMapping(value = "v1/book/srarch/PhraseQuery")
public Object srarchPhraseQuery(@ApiParam("查询内容") @RequestParam String content,
@ApiParam(value = "当前页", defaultValue = "0") @RequestParam int page,
@ApiParam(value = "显示多少条", defaultValue = "20") @RequestParam int size) {
// PhraseMatch查询,短语匹配,单字段对某短语进行匹配查询,短语分词的顺序会影响结果
//类似于数据库里的 %落日熔金%
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchPhraseQuery("content", content)).withPageable(PageRequest.of(page, size)).build();
return elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
}
@ApiOperation(value = "完全匹配查询", notes = "最严格的匹配,不进行分词", httpMethod = "GET")
@GetMapping(value = "v1/book/srarch/TermQuery")
public Object srarchTermQuery(@ApiParam(value = "id", defaultValue = "5") @RequestParam int userId,
@ApiParam(value = "当前页", defaultValue = "0") @RequestParam int page,
@ApiParam(value = "显示多少条", defaultValue = "10") @RequestParam int size) {
//term一般适用于做过滤器filter的情况,譬如我们去查询title中包含“浣溪沙”且userId=1时,那么就可以用termQuery(“userId”, 1)作为查询的filter
//不对传来的值分词,去找完全匹配的
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("userId", userId)).withPageable(PageRequest.of(page, size)).build();
return elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
}
@ApiOperation(value = "多字段的匹配查询", httpMethod = "GET")
@GetMapping(value = "v1/book/srarch/MultiMatchQuery")
public Object srarchMultiMatchQuery(@ApiParam("查询内容") @RequestParam String title,
@ApiParam(value = "当前页", defaultValue = "0") @RequestParam int page,
@ApiParam(value = "显示多少条", defaultValue = "10") @RequestParam int size) {
//MultiMatchQuery: 多字段匹配 "title","content" ,只要任何一个字段包括该字符串即可
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.multiMatchQuery(title, "title", "content"))
.withPageable(PageRequest.of(page, size))
.build();
//MultiMatchQueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery(title, "title", "content");
//构建查询对象
/*SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(multiMatchQuery)
.withIndices("book_es") //索引名
.withPageable(PageRequest.of(page, size, new Sort(Sort.Direction.DESC, "id")))
.build();*/
//执行查询
return elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
}
@ApiOperation(value = "多字段合并查询", httpMethod = "GET")
@GetMapping(value = "v1/book/srarch/BoolQuery")
public Object srarchBoolQuery(@ApiParam(value = "userId", defaultValue = "2") @RequestParam String userId,
@ApiParam(value = "weight", defaultValue = "14") @RequestParam String weight,
@ApiParam(value = "title", defaultValue = "浣溪沙") @RequestParam String title) {
//boolQuery 可以设置多个条件的查询方式,用来组合多个Query,组合方式有四种:must,mustnot,filter,should
/*must代表返回的文档必须满足must子句的条件,会参与计算分值;
filter代表返回的文档必须满足filter子句的条件,但不会参与计算分值;
should代表返回的文档可能满足should子句的条件,也可能不满足,有多个should时满足任何一个就可以,通过minimum_should_match设置至少满足几个。
mustnot代表必须不满足子句的条件。*/
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.boolQuery().must(termQuery("userId", userId))
.should(rangeQuery("weight").lt(weight)).must(matchQuery("title", title))).build();
return elasticsearchTemplate.queryForList(searchQuery, BookEntity.class);
}
@ApiOperation(value = "删除索引", httpMethod = "DELETE")
@DeleteMapping(value = "v1/book/delete")
public void deleteIndex(@ApiParam("id") @RequestParam String id) {
//删除索引
BookEntity bookEntity = new BookEntity();
bookEntity.setId(id);
//bookRepository.delete(bookEntity);
//根据id删除
bookRepository.deleteById(id);
//删除所有
//bookRepository.deleteAll();
}
@ApiOperation(value = "删除所有索引", httpMethod = "DELETE")
@DeleteMapping(value = "v1/book/delete/all")
public void deleteAllIndex() {
//删除所有
bookRepository.deleteAll();
}
}
InitBookData 初始化数据
/**
* Email: [email protected]
* Desc:只初始化一次测试数据
*/
@Component
public class InitBookData {
@Autowired
BookRepository bookRepository;
@PostConstruct
public void init() {
//只初始化一次
Iterable<BookEntity> posts = bookRepository.findAll();
if (posts.iterator().hasNext()) {
return;
}
for (int i = 0; i < 40; i++) {
BookEntity book = new BookEntity();
book.setTitle(getTitle().get(i));
book.setContent(getContent().get(i));
book.setWeight(i);
book.setUserId(i % 10);
bookRepository.save(book);
}
}
private List<String> getTitle() {
List<String> list = new ArrayList<>();
list.add("《如梦令·常记溪亭日暮》");
list.add("《醉花阴·薄雾浓云愁永昼》");
list.add("《声声慢·寻寻觅觅》");
list.add("《永遇乐·落日熔金》");
list.add("《如梦令·昨夜雨疏风骤》");
list.add("《渔家傲·雪里已知春信至》");
list.add("《点绛唇·蹴[1]罢秋千》");
list.add("《点绛唇·寂寞深闺》");
list.add("《蝶恋花·泪湿罗衣脂粉满》");
list.add("《蝶恋花 离情》");
list.add("《浣溪沙》");
list.add("《浣溪沙》");
list.add("《浣溪沙》");
list.add("《浣溪沙》");
list.add("《浣溪沙》");
list.add("《减字木兰花·卖花担上》");
list.add("《临江仙·欧阳公作《蝶恋花》");
list.add("《临江仙·庭院深深深几许》");
list.add("《念奴娇·萧条庭院》");
list.add("《菩萨蛮·风柔日薄春犹早》");
list.add("《菩萨蛮·归鸿声断残云碧》");
list.add("《武陵春·风住尘香花已尽》");
list.add("《一剪梅·红藕香残玉蕈秋》");
list.add("《渔家傲·天接云涛连晓雾》");
list.add("《鹧鸪天·暗淡轻黄体性柔》");
list.add("《鹧鸪天·寒日萧萧上锁窗》");
list.add("《一剪梅·红藕香残玉簟秋》");
list.add("《如梦令·常记溪亭日暮》");
list.add("《浣溪沙》");
list.add("《浣溪沙》");
list.add("《浣溪沙》");
list.add("《蝶恋花·泪湿罗衣脂粉满》");
list.add("《蝶恋花·暖日晴风初破冻》");
list.add("《鹧鸪天·寒日萧萧上锁窗》");
list.add("《醉花阴·薄雾浓云愁永昼》");
list.add("《鹧鸪天·暗淡轻黄体性柔》");
list.add("《蝶恋花·永夜恹恹欢意少》");
list.add("《浣溪沙》");
list.add("《浣溪沙》");
list.add("《如梦令·谁伴明窗独坐》");
return list;
}
private List<String> getContent() {
List<String> list = new ArrayList<>();
list.add("初中 宋·李清照 常记溪亭日暮,沉醉不知归路,兴尽晚回舟,误入藕花深处。争渡,争渡");
list.add("重阳节 宋·李清照 薄雾浓云愁永昼,瑞脑消金兽。佳节又重阳,玉枕纱厨,半夜凉初透。东");
list.add("闺怨诗 宋·李清照 寻寻觅觅,冷冷清清,凄凄惨惨戚戚。乍暖还寒时候,最难将息。三杯两");
list.add("元宵节 宋·李清照 落日熔金,暮云合璧,人在何处。染柳烟浓,吹梅笛怨,春意知几许。元");
list.add("婉约诗 宋·李清照 昨夜雨疏风骤,浓睡不消残酒,试问卷帘人,却道海棠依旧。知否,知否");
list.add("描写梅花 宋·李清照 雪里已知春信至,寒梅点缀琼枝腻,香脸半开娇旖旎,当庭际,玉人浴出");
list.add(" 宋·李清照 蹴罢秋千,起来慵整纤纤手。露浓花瘦,薄汗轻衣透。见客入来,袜刬金");
list.add("闺怨诗 宋·李清照 寂寞深闺,柔肠一寸愁千缕。惜春春去。几点催花雨。倚遍阑干,只是无");
list.add("婉约诗 宋·李清照 泪湿罗衣脂粉满。四叠阳关,唱到千千遍。人道山长水又断。萧萧微雨闻");
list.add("描写春天 宋·李清照 暖雨晴风初破冻,柳眼梅腮,已觉春心动。酒意诗情谁与共?泪融残粉花");
list.add("寒食节 宋·李清照 淡荡春光寒食天,玉炉沈水袅残烟,梦回山枕隐花钿。海燕未来人斗草,");
list.add(" 宋·李清照 髻子伤春慵更梳,晚风庭院落梅初,淡云来往月疏疏,玉鸭薰炉闲瑞脑,");
list.add(" 宋·李清照 莫许杯深琥珀浓,未成沉醉意先融。疏钟已应晚来风。瑞脑香消魂梦断,");
list.add("闺怨诗 宋·李清照 小院闲窗春已深,重帘未卷影沉沉。倚楼无语理瑶琴,远岫出山催薄暮。");
list.add("爱情诗 宋·李清照 绣幕芙蓉一笑开,斜偎宝鸭亲香腮,眼波才动被人猜。一面风情深有韵,");
list.add("描写春天 宋·李清照 卖花担上,买得一枝春欲放。泪染轻匀,犹带彤霞晓露痕。怕郎猜道,奴");
list.add("》 宋·李清照 欧阳公作《蝶恋花》,有“深深深几许”之句,予酷爱之。用其语作“庭");
list.add("描写梅花 宋·李清照 庭院深深深几许,云窗雾阁春迟,为谁憔悴损芳姿。夜来清梦好,应是发");
list.add("寒食节 宋·李清照 萧条庭院,又斜风细雨,重门须闭。宠柳娇花寒食近,种种恼人天气。险");
list.add("思乡诗 宋·李清照 风柔日薄春犹早,夹衫乍著心情好。睡起觉微寒,梅花鬓上残。故乡何处");
list.add("描写春天 宋·李清照 归鸿声断残云碧,背窗雪落炉烟直。烛底凤钗明,钗头人胜轻。角声催晓");
list.add("闺怨诗 宋·李清照 风住尘香花已尽,日晚倦梳头。物是人非事事休,欲语泪先流。闻说双溪");
list.add(" 宋·李清照 红藕香残玉蕈秋,轻解罗裳,独上兰舟。云中谁寄锦书来?雁字回时,月");
list.add("豪放诗 宋·李清照 天接云涛连晓雾。星河欲转千帆舞。仿佛梦魂归帝所。闻天语。殷勤问我");
list.add("描写花 宋·李清照 暗淡轻黄体性柔。情疏迹远只香留。何须浅碧深红色,自是花中第一流。");
list.add("描写秋天 宋·李清照 寒日萧萧上琐窗,梧桐应恨夜来霜。酒阑更喜团茶苦,梦断偏宜瑞脑香。");
list.add("闺怨诗 宋·李清照 红藕香残玉簟秋。轻解罗裳,独上兰舟。云中谁寄锦书来?雁字回时,月");
list.add(" 宋·李清照 常记溪亭日暮。沈醉不知归路。兴尽晚回舟,误入藕花深处。争渡。争渡");
list.add(" 宋·李清照 莫许杯深琥珀浓。未成沈醉意先融。已应晚来风。瑞脑香消魂梦断,");
list.add(" 宋·李清照 小院闲窗春色深。重帘未卷影沈沈。倚楼无语理瑶琴。远岫出山催薄暮,");
list.add(" 宋·李清照 淡荡春光寒食天。玉炉沈水袅残烟。梦回山枕隐花钿。海燕未来人斗草,");
list.add(" 宋·李清照 泪湿罗衣脂粉满。四叠阳关,唱到千千遍。人道山长山又断。萧萧微雨闻");
list.add(" 宋·李清照 暖日晴风初破冻。柳眼眉腮,已觉春心动。酒意诗情谁与共。泪融残粉花");
list.add(" 宋·李清照 寒日萧萧上锁窗。梧桐应恨夜来霜。酒阑更喜团茶苦,梦断偏宜瑞脑香。");
list.add(" 宋·李清照 薄雾浓云愁永昼。瑞脑消金兽。佳节又重阳,玉枕纱厨,半夜凉初透。东");
list.add(" 宋·李清照 暗淡轻黄体性柔。情疏迹远只香留。何须浅碧深红色,自是花中第一流。");
list.add(" 宋·李清照 永夜恹恹欢意少。空梦长安,认取长安道。为报今年春色好。花光月影宜");
list.add(" 宋·李清照 髻子伤春慵更梳。晚风庭院落梅初。淡云来往月疏疏。玉鸭熏炉闲瑞脑,");
list.add(" 宋·李清照 绣面芙蓉一笑开。斜飞宝鸭衬香腮。眼波才动被人猜。一面风情深有韵,");
list.add(" 宋·李清照 谁伴明窗独坐,我共影儿俩个。灯尽欲眠时,影也把人抛躲。无那,无那");
return list;
}
}