网上大多通过 java 操作 es 使用的都是 TransportClient,而介绍使用 SpringDataElasticSearch 的文章相对比较少,笔者也是摸索了许久,接下来本文介绍 SpringDataElasticSearch 的 api 使用,更加方便的进行查询。

系列文章

环境依赖

本文以及后续 es 系列文章都基于 5.5.3 这个版本的 elasticsearch ,这个版本比较稳定,可以用于生产环境。

本文项目基于 SpringBoot 2.0.4.RELEASE 进行构建,首先引入 Spring Data ElasticSearch 的依赖。

注意:因为是 Spring Boot 项目,所以引入的依赖是 spring-boot-starter-data-elasticsearch,而不是直接引入 spring-data-elasticsearch

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  4. </dependency>

Spring Data ElasticSearch 与 ElasticSearch 有对应关系

spring data elasticsearch elasticsearch
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

而本文使用的 SpringBoot 2.0.4.RELEASE 自动依赖的 Spring Data ElasticSearch 版本是 3.0.9.RELEASE,对应的 elasticsearch 版本是 5.5.x,可知依赖是正确的版本。

创建 Document 类

  1. @Data
  2. @Document(indexName = "novel", type = "book", createIndex = false)
  3. public class Book implements Serializable {
  4. private static final long serialVersionUID = 8504604495927552402L;
  5. /**
  6. * 需要添加 @Id 标识主键
  7. */
  8. @Id
  9. private Integer id;
  10. private Integer words;
  11. private String intro;
  12. private String name;
  13. private Integer sort;
  14. private Boolean vip;
  15. private Integer site;
  16. private String author;
  17. private Integer collection;
  18. private Integer click;
  19. private Integer popularity;
  20. private Integer goods;
  21. private Integer status;
  22. /**
  23. * 需要自定义时间格式化格式,否则会使用默认时间格式化
  24. */
  25. @JsonFormat (shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd HH:mm:ss")
  26. private Date updatetime;
  27. }

这个 Document 类封装了索引的全部字段信息,注意字段名称要与索引类型的字段名称一致。

创建 Repository 接口

  1. public interface BookRepository extends ElasticsearchRepository<Book, Integer> {
  2. }

用过 SpringDataJPA 的朋友都应该知道,ElasticsearchRepository 的两个泛型分别为 Documet 以及 Document 的主键类型。

创建测试类

  1. @Slf4j
  2. @SpringBootTest
  3. @RunWith(SpringRunner.class)
  4. public class BookRepositoryTest {
  5. @Autowired
  6. private BookRepository bookRepository;
  7. }

演示简单查询

匹配查询(MatchQuery)

进行模糊匹配查询,这里演示的是通过 name 这个字段进行查询

  1. @Test
  2. public void findBook() {
  3. MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("name", "火爆娱乐天王");
  4. bookRepository.search(matchQuery)
  5. .forEach(e -> log.info("作品信息:{}", e));
  6. }

项查询(TermQuery)

完全匹配查询,这里演示查询 id 为 2 的数据

  1. @Test
  2. public void findBook() {
  3. TermQueryBuilder termQuery = QueryBuilders.termQuery("id", 2);
  4. bookRepository.search(termQuery)
  5. .forEach(e -> log.info("作品信息:{}", e));
  6. }

范围查询(Range Query)

范围查询,这里演示查询字数在 0-30w 之间的作品

  1. @Test
  2. public void findBook() {
  3. RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("words").gt(0).lt(300000);
  4. bookRepository.search(rangeQuery)
  5. .forEach(e -> log.info("作品信息:{}", e));
  6. }

注意:如果对时间进行范围查询,注意不能传递 Date 对象或者 毫秒值,只能传递 yyyy-MM-dd HH:mm:ss 格式的字符串时间参数。

复合查询

以上演示了几个基本查询,但是如果要实现多筛选条件的查询,就需要把多个基本查询进行组合,这里就用到了 bool 查询



现在来实现这个查询

BookQuery 参数封装

使用 BookQuery 类封装查询参数

  1. @Data
  2. public class BookQuery {
  3. private String queryString;
  4. private Integer page = 1;
  5. private Integer size = 20;
  6. private Integer wordsBegin;
  7. private Integer wordsEnd;
  8. private Integer sort;
  9. private Boolean vip;
  10. private Integer site;
  11. private Integer collection;
  12. private Integer click;
  13. private Integer popularity;
  14. private Integer goods;
  15. private Integer status;
  16. private Date updatetime;
  17. }

查询测试

  1. @Test
  2. public void findBook() {
  3. BookQuery query = new BookQuery();
  4. query.setQueryString("魔");
  5. query.setSite(2);// 1 是男生 2 是女生
  6. query.setSort(29); // 29 是玄幻
  7. query.setVip(true);// 查询 vip 作品
  8. query.setWordsBegin(0); // 查询字数在 0-25w 之间的作品
  9. query.setWordsEnd(500000);
  10. query.setPage(1);// 分页页码
  11. query.setSize(10);// 每页显示数
  12. // 复合查询
  13. BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
  14. // 以下为查询条件, 使用 must query 进行查询组合
  15. MultiMatchQueryBuilder matchQuery = QueryBuilders.multiMatchQuery(query.getQueryString(), "name", "intro", "author");
  16. boolQuery.must(matchQuery);
  17. // 以下为过滤筛选条件,使用 filter 比使用 must query 性能要好
  18. TermQueryBuilder siteQuery = QueryBuilders.termQuery("site", query.getSite());
  19. boolQuery.filter(siteQuery);
  20. TermQueryBuilder sortQuery = QueryBuilders.termQuery("sort", query.getSort());
  21. boolQuery.filter(sortQuery);
  22. TermQueryBuilder vipQuery = QueryBuilders.termQuery("vip", query.getVip());
  23. boolQuery.filter(vipQuery);
  24. RangeQueryBuilder wordsQuery = QueryBuilders.rangeQuery("words").gt(query.getWordsBegin()).lt(query.getWordsEnd());
  25. boolQuery.filter(wordsQuery);
  26. Sort sort = Sort.by(Sort.Direction.DESC, "click");
  27. // 分页 同时根据 点击数 click 进行降序排列
  28. PageRequest pageRequest = PageRequest.of(query.getPage() - 1, query.getSize(), sort);
  29. log.info("{}", boolQuery);
  30. bookRepository.search(boolQuery, pageRequest)
  31. .forEach(e -> log.info("作品信息:{}", e));
  32. }

查出结果:

  1. 2018-09-12 22:33:05.750 INFO 25896 --- [ main] i.g.mosiki.search.BookRepositoryTest : 作品信息:Book(id=7, words=345004, intro= 推荐《寻龙传》《魂摄天下》 作品属玄幻异界大陆风格! 可惜频道不能更改只能在奇幻混! 书友群:292... , name=灭魔成圣, sort=29, vip=true, site=2, author=等待潇湘诗社, collection=13, click=63263, popularity=2314, goods=5353, status=0, updatetime=Tue Sep 04 16:54:15 CST 2018)
  2. 2018-09-12 22:33:05.751 INFO 25896 --- [ main] i.g.mosiki.search.BookRepositoryTest : 作品信息:Book(id=9, words=233000, intro= 一名地球的平凡的少年,因为一场游戏,获得死神的传承,从而穿越到另外一片陌生的大陆,从此开启了一段传奇的人生,九天星河,吾乃死神,掌控生死,判夺罪恶,我从没见过地狱,因为我的名字,便代表地狱,吾乃死神,吾名林天。(PS:单女主,爽文不虐心,主角以杀证道,杀该杀之人,不圣母,略腹黑) 各位书友要是觉得《带着死神去穿越》还不错的话请不要忘记向您QQ群和微博里的朋友推荐哦!带着死神去穿越最新章节,带着死神去穿越无弹窗,带着死神去穿越全文阅读. , name=带着死神去穿越, sort=29, vip=true, site=2, author=梦侍, collection=6326, click=523, popularity=135, goods=34252, status=0, updatetime=Thu Dec 28 04:53:07 CST 2017)
  3. 2018-09-12 22:33:05.751 INFO 25896 --- [ main] i.g.mosiki.search.BookRepositoryTest : 作品信息:Book(id=5, words=490000, intro= 富家子弟墨浞因为发现了村子中的秘密,在良心与亲情的折磨下,逃到了边境小城。因为一个香-艳而又恐怖的梦,墨浞经历了一些诡异的事,从而得知自己的前世与今生的使命。踏上藏地,历经磨难,克服了自己的心魔,战胜了... , name=伏魔, sort=29, vip=true, site=2, author=一叶style, collection=526, click=9, popularity=41516, goods=7687, status=0, updatetime=Thu Sep 06 04:54:05 CST 2018)

最后

SpringDataElasticSearch 入门就到这里了,是不是很简单呢?

本文示例项目地址:https://github.com/Mosiki/SpringDataElasticSearchQuickStartExample

有疑问?

欢迎来信,给我写信

参考

和我一起打造个简单搜索之SpringDataElasticSearch入门的更多相关文章

  1. 和我一起打造个简单搜索之SpringDataElasticSearch关键词高亮

    前面几篇文章详细讲解了 ElasticSearch 的搭建以及使用 SpringDataElasticSearch 来完成搜索查询,但是搜索一般都会有搜索关键字高亮的功能,今天我们把它给加上. 系列文 ...

  2. 和我一起打造个简单搜索之ElasticSearch入门

    本文简单介绍了使用 Rest 接口,对 es 进行操作,更深入的学习,可以参考文末部分. 环境 本文以及后续 es 系列文章都基于 5.5.3 这个版本的 elasticsearch ,这个版本比较稳 ...

  3. 和我一起打造个简单搜索之Logstash实时同步建立索引

    用过 Solr 的朋友都知道,Solr 可以直接在配置文件中配置数据库连接从而完成索引的同步创建,但是 ElasticSearch 本身并不具备这样的功能,那如何建立索引呢?方法其实很多,可以使用 J ...

  4. 和我一起打造个简单搜索之IK分词以及拼音分词

    elasticsearch 官方默认的分词插件,对中文分词效果不理想,它是把中文词语分成了一个一个的汉字.所以我们引入 es 插件 es-ik.同时为了提升用户体验,引入 es-pinyin 插件.本 ...

  5. 和我一起打造个简单搜索之ElasticSearch集群搭建

    我们所常见的电商搜索如京东,搜索页面都会提供各种各样的筛选条件,比如品牌.尺寸.适用季节.价格区间等,同时提供排序,比如价格排序,信誉排序,销量排序等,方便了用户去找到自己心里理想的商品. 站内搜索对 ...

  6. 《ElasticSearch6.x实战教程》之简单搜索、Java客户端(上)

    第五章-简单搜索 众里寻他千百度 搜索是ES的核心,本节讲解一些基本的简单的搜索. 掌握ES搜索查询的RESTful的API犹如掌握关系型数据库的SQL语句,尽管Java客户端API为我们不需要我们去 ...

  7. ElasticSearch 5学习(4)——简单搜索笔记

    空搜索: GET /_search hits: total 总数 hits 前10条数据 hits 数组中的每个结果都包含_index._type和文档的_id字段,被加入到_source字段中这意味 ...

  8. nyoj 284 坦克大战 简单搜索

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=284 题意:在一个给定图中,铁墙,河流不可走,砖墙走的话,多花费时间1,问从起点到终点至少 ...

  9. 分布式搜索ElasticSearch构建集群与简单搜索实例应用

    分布式搜索ElasticSearch构建集群与简单搜索实例应用 关于ElasticSearch不介绍了,直接说应用. 分布式ElasticSearch集群构建的方法. 1.通过在程序中创建一个嵌入es ...

随机推荐

  1. Aria2+WebUI,迅雷倒下之后的代替品

    Aria2+WebUI,迅雷倒下之后的代替品 (2017-07-24 12:56:28) 转载▼   分类: 软件 最近迅雷越来越作死了,砍第三方远程下载,强推迅雷9喂用户的屎,下载资源能砍就砍,以前 ...

  2. 利用python如何实现团队成员动态抓阄?

    解决思路: 1 确定团队成员个数num,然后根据成员个数生成元素非重复的数组: 2 构成一个团队成员字典,键:成员名  值:0, 然后将生成的数组分别赋值给字典键对应的值: 话不多说,看代码便知: # ...

  3. Spring Boot 启动(二) Environment 加载

    Spring Boot 启动(二) Environment 加载 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) 上一节中 ...

  4. python_day13_js

    JavaScript 基础 目录: javascript简介 javascrip历史 ecmascript标准 javascrip基础 js引入方式 js变量.常量.标识符 js数据类型 运算符 流程 ...

  5. php流程控制

    return 例子一: <?php function add($a,$b){ echo "echo"; return $a+$b; //return 一般用于function ...

  6. Windows系统编程之异步I/O和完成端口

    Windows系统编程之异步I/O和完成端口[作者]北极星2003[来源]看雪技术论坛(bbs.pediy.com) [时间]2006年7月1日 一.  同步I/O和异步I/O 在介绍这部分内容之前先 ...

  7. iOS 系统通知

    iOS相当多一部分系统事件实际上都是通过通知来完成的,依赖于通知的广播形式,我们可以在AppDelegate中通过添加空通知来捕捉所有通知: static NSString *const MYNOTI ...

  8. 笔记:Activity的启动过程

    Activity的创建特点 作为四大组件之一的Activity,它不像普通java对像那样,可以new出来,然后去使用.而是调用 startActivity()这样的方式启动.那么Android系统是 ...

  9. Android开发 - 掌握ConstraintLayout(一)传统布局的问题

    在传统的Android开发中,页面布局占用了我们很多的开发时间,而且面对复杂页面的时候,传统的一些布局会显得非常复杂,每种布局都有特定的应用场景,我们通常需要各种布局结合起来使用来实现复杂的页面.随着 ...

  10. js的微观性能

    概述 js的微观性能是指js的某一个表达式或者某一行或者某一块代码的性能.几天前和同事讨论过这方面的内容,今天深入研究了一下,记录下来,供以后开发时参考,相信对其他人也有用. 从一段代码说起 记得以前 ...