和我一起打造个简单搜索之SpringDataElasticSearch入门

news/2024/7/1 2:45:42

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

系列文章

  • 一、和我一起打造个简单搜索之ElasticSearch集群搭建
  • 二、和我一起打造个简单搜索之ElasticSearch入门
  • 三、和我一起打造个简单搜索之IK分词以及拼音分词
  • 四、和我一起打造个简单搜索之Logstash实时同步建立索引
  • 五、和我一起打造个简单搜索之SpringDataElasticSearch入门
  • 六、和我一起打造个简单搜索之SpringDataElasticSearch关键词高亮
  • ...

环境依赖

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

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

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

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

Spring Data ElasticSearch 与 ElasticSearch 有对应关系

spring data elasticsearchelasticsearch
3.1.x6.2.2
3.0.x5.5.0
2.1.x2.4.0
2.0.x2.2.0
1.3.x1.5.2

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

创建 Document 类

@Data
@Document(indexName = "novel", type = "book", createIndex = false)
public class Book implements Serializable {private static final long serialVersionUID = 8504604495927552402L;/*** 需要添加 @Id 标识主键*/@Idprivate Integer id;private Integer words;private String intro;private String name;private Integer sort;private Boolean vip;private Integer site;private String author;private Integer collection;private Integer click;private Integer popularity;private Integer goods;private Integer status;/*** 需要自定义时间格式化格式,否则会使用默认时间格式化*/@JsonFormat (shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd HH:mm:ss")private Date updatetime;}

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

创建 Repository 接口

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

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

创建测试类

@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class BookRepositoryTest {@Autowiredprivate BookRepository bookRepository;}

演示简单查询

匹配查询(MatchQuery)

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

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

项查询(TermQuery)

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

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

范围查询(Range Query)

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

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

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

复合查询

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

201809061536241809780.png
现在来实现这个查询

BookQuery 参数封装

使用 BookQuery 类封装查询参数

@Data
public class BookQuery {private String queryString;private Integer page = 1;private Integer size = 20;private Integer wordsBegin;private Integer wordsEnd;private Integer sort;private Boolean vip;private Integer site;private Integer collection;private Integer click;private Integer popularity;private Integer goods;private Integer status;private Date updatetime;
}

查询测试

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

查出结果:

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)
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)
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

有疑问?

欢迎来信,给我写信

参考

  • https://blog.csdn.net/tianyaleixiaowu/article/details/77965257
  • https://tech.youzan.com/search-engine1/#43filteredquery

转载于:https://www.cnblogs.com/vcmq/p/9966688.html


http://lihuaxi.xjx100.cn/news/269964.html

相关文章

精选一套火爆B站的硬核资源,请笑纳!

最近经常有粉丝给我留言求人工智能方向的资源&#xff0c;想要尝试自学人工智能&#xff0c;将自己的一些想法和创意付诸现实&#xff0c;或是想通过自学进入AI领域。细聊之下&#xff0c;大部分人自觉苦于不知从何入手&#xff0c;找不到学习重点。或是止步于晦涩难懂的理论和…

汇总 | 深度学习中图像语义分割基准数据集详解

点击上方“小白学视觉”&#xff0c;选择加"星标"或“置顶”重磅干货&#xff0c;第一时间送达汇总图像语义分割那些质量最好的数据集与常用benchmark数据集前言图像语义分割是计算机视觉最经典的任务之一&#xff0c;早期的图像分割主要有以下几种实现方法。基于像素…

自从上线了 Prometheus 监控告警,真香!

点击上方蓝色“方志朋”&#xff0c;选择“设为星标”回复“666”获取独家整理的学习资料&#xff01;对很多人来说&#xff0c;未知、不确定、不在掌控的东西&#xff0c;会有潜意识的逃避。当我第一次接触 Prometheus 的时候也有类似的感觉。对初学者来说&#xff0c; Promet…

常用浏览器插件

modify headers &#xff1a;firefox的IP伪造插件 httpRequester&#xff1a;firefox的模拟http请求插件JSON-handle&#xff1a;chrome格式化json插件firebug&#xff1a;firefox查看http请求工具firepath&#xff1a;firefox中获取元素路径转载于:https://www.cnblogs.com/xx…

es dsl java api_ElasticSearch 系列 - RestFulAPI(DSL)

前言DSL全称 Domain Specific language&#xff0c;即特定领域专用语言1.全局操作1.1 查询集群健康情况GET /_cat/health?v ?v表示显示头信息集群的健康状态有红、黄、绿三个状态&#xff1a;绿 – 一切正常(集群功能齐全)黄 – 所有数据可用&#xff0c;但有些副本尚未分配(…

性能超越最新序列推荐模型,华为诺亚方舟提出记忆增强的图神经网络

作者 | Chen Ma, Liheng Ma等译者 | Rachel出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;用户-商品交互的时间顺序可以揭示出推荐系统中用户行为随时间演进的序列性特征。用户与之交互的商品可能受到用户曾经接触的商品的影响。但是&#xff0c;用户和商…

混合云备份利用自定义Workflow保护MySQL的实践

众所周知数据库的保护面临着诸多问题&#xff0c;其中之一就是维护数据底层文件的一致性。除了与数据库应用的深度集成的备份方案&#xff08;如SAP HANA Backint等&#xff09;&#xff0c;松耦合的通用备份软件较难做到完美的数据库的一致性保护。 为了解决该项痛点&#xff…

使用Nginx做前端服务器时让Apache得到真实IP的方法

一&#xff1a;nginx.conf proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 其实这个proxy.conf里面默认都有&#xff0c;在nginx.conf使用include proxy.conf就可以 二&#xff1a;apa…