elasticsearch 实战

文章目录

      • 项目介绍
      • 导入项目
  • Elasticsearch Java API 查询文档
    • 快速入门
      • 发起查询请求
      • 解析响应
      • 完整代码
    • match查询
    • 精确查询
    • 布尔查询
    • 排序、分页
    • 高亮
      • 高亮请求构建
      • 高亮结果解析

项目介绍

本项目是一个由spring boot 3.0.2在gradle 8.4和java 21的环境下搭建的elasticsearch项目demo,这个项目是基于新版的Elasticsearch Java API 制作的,符合最新的框架要求,由于是运用了Elasticsearch新版的java jar包,所以在查询的时候使用了大量的Stream流式编程和闭包,亦可以作为流式编程的巩固。

导入项目

项目可以使用文章绑定的资源,或者去底部的GitHub地址下载

Elasticsearch Java API 查询文档

快速入门

我们以match_all查询为例

发起查询请求

在这里插入图片描述

代码解读
上面的代码使用了流式编程的思想,首先选择用search表示是选择查询模式,然后用index决定搜索的索引库,然后用query构建查询索引,然后选择查询模式matchAll。

es中的查询语句

GET hotel/_search
{"query": {"match_all": {}}
}

解析响应

elasticsearch返回的结果是一个JSON字符串,结构包含:

  • hits:命中的结果
    • total:总条数,其中的value是具体的总条数值
    • max_score:所有结果中得分最高的文档的相关性算分
    • hits:搜索结果的文档数组,其中的每个文档都是一个json对象
      • source:文档中的原始数据,也是json转化成实体类的对象

因此,我们解析响应结果,就是逐层解析JSON字符串,流程如下:

  • HitsMetadata:通过response.hits()获取,就是JSON中的最外层的hits,代表命中的结果
    • HitsMetadata.total().value():获取总条数信息
    • SearchHits#getHits():获取SearchHit数组,也就是文档数组

完整代码

完整代码如下:

    @Testvoid testMatchAll() throws IOException {
//进行查询SearchResponse<HotelDoc> response = esClient.search(s -> s.index("hotel").query(q -> q.matchAll(m->m)),HotelDoc.class);handleResponse(response);}private void handleResponse( SearchResponse<HotelDoc> response) {HitsMetadata<HotelDoc> searchHits = response.hits();// 4.1.总条数long total = searchHits.total().value();System.out.println("总条数:" + total);// 4.2.获取文档数组List<Hit<HotelDoc>>  hits = searchHits.hits();// 4.3.遍历hits.forEach(i->{// 4.4 自动序列化HotelDoc hotelDoc = i.source();// 4.6.处理高亮结果// 1)获取高亮字段和高亮数据的mapMap<String, List<String>>  map = i.highlight();if (map!=null){// 2)根据字段名,获取高亮结果List<String> name = map.get("name");if (name!=null){// 3)获取高亮结果字符串数组中的第1个元素String hName= name.get(0);// 4)把高亮结果放到HotelDoc中hotelDoc.setName(hName);}}System.out.println(hotelDoc);
//            System.out.println(i.highlight());});}

match查询

全文检索的match和multi_match查询与match_all的API基本一致。差别是查询条件,也就是query的部分。

在这里插入图片描述

因此,Java代码上的差异主要是request.source().query()中的参数了。同样是利用QueryBuilders提供的方法:

而结果解析代码则完全一致,可以抽取并共享。

完整代码如下:

    @Testvoid testMatch() throws IOException {SearchResponse<HotelDoc> response = esClient.search(i->i.index("hotel").query(q->q.match(t->t.field("all")//设置请求字段.query("如家")//设置请求参数)),HotelDoc.class);handleResponse(response);}

精确查询

精确查询主要是两者:

  • term:词条精确匹配
  • range:范围查询

与之前的查询相比,差异同样在查询条件,其它都一样。

es语句

GET /hotel/_search
{"query": {"match": {"all": "如家"}}
}

查询条件构造的API如下:

SearchResponse<HotelDoc> response = esClient.search(s -> s.index("hotel").query(q->q.term(t->t.field("city").value("上海"))),

布尔查询

布尔查询是用must、must_not、filter等方式组合其它查询,代码示例如下:

es语句

GET /hotel/_search
{"query": {"match": {"all": "如家"}}
}

完整代码如下:

    @Testvoid testMatch() throws IOException {SearchResponse<HotelDoc> response = esClient.search(i->i.index("hotel").query(q->q.match(t->t.field("all")//设置请求字段.query("如家")//设置请求参数)),HotelDoc.class);handleResponse(response);}

排序、分页

es语句

GET hotel/_search
{"query": {"match_all": {}},"from": 0,"size": 5,"sort": [{"price": {"order": "desc"}}]}

完整代码示例:

@Test
void testPageAndSort() throws IOException {// 页码,每页大小int page = 1, size = 5;// 1.准备RequestSearchRequest request = new SearchRequest("hotel");// 2.准备DSL// 2.1.queryrequest.source().query(QueryBuilders.matchAllQuery());// 2.2.排序 sortrequest.source().sort("price", SortOrder.ASC);// 2.3.分页 from、sizerequest.source().from((page - 1) * size).size(5);// 3.发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 4.解析响应handleResponse(response);}

高亮

高亮的代码与之前代码差异较大,有两点:

  • 查询的DSL:其中除了查询条件,还需要添加高亮条件,同样是与query同级。
  • 结果解析:结果除了要解析_source文档数据,还要解析高亮结果

高亮请求构建

es语句

GET /hotel/_search
{"query": {"match": {"all": "如家"}},"highlight": {"fields": {"name": {"require_field_match": "false"}}}
}

上述代码省略了查询条件部分,但是大家不要忘了:高亮查询必须使用全文检索查询,并且要有搜索关键字,将来才可以对关键字高亮。

完整代码如下:

    @Testvoid testHighlight() throws IOException {SearchResponse<HotelDoc> response = esClient.search(s->s.index("hotel").query(q->q.match(t->t.field("all")//设置请求字段.query("如家")//设置请求参数)).highlight(h->h.fields("name",f->f.requireFieldMatch(false))),HotelDoc.class);handleResponse(response);}

高亮结果解析

高亮的结果与查询的文档结果默认是分离的,并不在一起。

代码解读:

  • 第一步:从结果中获取source。hit.getSourceAsString(),这部分是非高亮结果,json字符串。还需要反序列为HotelDoc对象
  • 第二步:获取高亮结果。hit.getHighlightFields(),返回值是一个Map,key是高亮字段名称,值是HighlightField对象,代表高亮值
  • 第三步:从map中根据高亮字段名称,获取高亮字段值对象HighlightField
  • 第四步:从HighlightField中获取Fragments,并且转为字符串。这部分就是真正的高亮字符串了
  • 第五步:用高亮的结果替换HotelDoc中的非高亮结果

完整代码如下:

private void handleResponse(SearchResponse response) {// 4.解析响应SearchHits searchHits = response.getHits();// 4.1.获取总条数long total = searchHits.getTotalHits().value;System.out.println("共搜索到" + total + "条数据");// 4.2.文档数组SearchHit[] hits = searchHits.getHits();// 4.3.遍历for (SearchHit hit : hits) {// 获取文档sourceString json = hit.getSourceAsString();// 反序列化HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);// 获取高亮结果Map<String, HighlightField> highlightFields = hit.getHighlightFields();if (!CollectionUtils.isEmpty(highlightFields)) {// 根据字段名获取高亮结果HighlightField highlightField = highlightFields.get("name");if (highlightField != null) {// 获取高亮值String name = highlightField.getFragments()[0].string();// 覆盖非高亮结果hotelDoc.setName(name);}}System.out.println("hotelDoc = " + hotelDoc);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/180985.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JSP forEach 标签遍历map集合

之前我们说了 普通list 单纯按数量循环 bean类型list的遍历方式 那么 我们forEach标签 也能循环map语法非常简单&#xff0c;和循环list基本是一样的 我们直接上jsp代码 <% page import"java.util.Map" %> <% page import"java.util.HashMap" %…

JAVA基础进阶(十)

一、File类常用的API File类的对象可以用来表示文件或者文件夹,下面是File类常用的API。 1.1、File类判断文件类型、获取文件信息功能 代码中的体现: 1.2、File类的创建和删除方法 代码中的体现: 1.3、文件夹遍历方法 代码中的体现: 二、字符集 字符集&#xff08;Character…

C#常用运算符的优先级

前言 运算符在C#编程语言中扮演着重要的角色&#xff0c;用于执行各种计算和操作。了解运算符的优先级是编写高效和正确代码的关键。本文将深入探讨C#中38个常用运算符的优先级划分和理解&#xff0c;并提供详细的说明和示例&#xff0c;以帮助读者更好地理解运算符的使用。 目…

Stable Video Diffusion重磅发布:基于稳定扩散模型的AI生成视频

最近&#xff0c;stability.ai发布了稳定视频扩散&#xff0c;这是stability.ai第一个基于图像模型稳定扩散的生成视频基础模型。现在可以在研究预览中看到&#xff0c;这个最先进的生成人工智能视频模型代表着stability.ai在为每种类型的人创建模型的过程中迈出了重要的一步。…

Python高级数据结构——树(Tree)

Python中的树&#xff08;Tree&#xff09;&#xff1a;高级数据结构解析 树是一种非常重要且常用的数据结构&#xff0c;它的层次结构使得在其中存储和检索数据变得高效。在本文中&#xff0c;我们将深入讲解Python中的树&#xff0c;包括树的基本概念、表示方法、常见类型、…

ES6的迭代器(Iterator)和生成器(Generator)

ES6引入了迭代器和生成器的概念&#xff0c;这两个特性为JavaScript带来了更强大的迭代和异步编程能力。本文将深入探讨ES6的迭代器和生成器&#xff0c;介绍它们的概念、用法以及在实际开发中的应用。 迭代器&#xff08;Iterator&#xff09; 迭代器&#xff08;Iterator&a…

FFA 2023|字节跳动 7 项议题入选

Flink Forward 是由 Apache 官方授权的 Apache Flink 社区官方技术大会&#xff0c;作为最受 Apache Flink 社区开发者期盼的年度峰会之一&#xff0c;FFA 2023 将持续集结行业最佳实践以及 Flink 最新技术动态&#xff0c;是中国 Flink 开发者和使用者不可错过的的技术盛宴。 …

中小型工厂如何进行数字化转型

随着科技的快速发展和市场竞争的日益激烈&#xff0c;中小型工厂面临着诸多挑战。为了提高生产效率、降低成本、优化资源配置&#xff0c;数字化转型已成为中小型工厂发展的必经之路。中小型工厂如何进行数字化转型呢&#xff1f; 一、明确数字化转型目标 在进行数字化转型之前…

怎么把dwg格式转换pdf?

怎么把dwg格式转换pdf&#xff1f;DWG是一种由AutoCAD开发的二维和三维计算机辅助设计&#xff08;CAD&#xff09;文件格式&#xff0c;它的名称是“绘图&#xff08;Drawing&#xff09;”的缩写。DWG文件通常包含了设计图纸、模型和元数据等信息&#xff0c;并且被广泛用于工…

Pytorch:torch.utils.data.DataLoader()

如果读者正在从事深度学习的项目&#xff0c;通常大部分时间都花在了处理数据上&#xff0c;而不是神经网络上。因为数据就像是网络的燃料&#xff1a;它越合适&#xff0c;结果就越快、越准确&#xff01;神经网络表现不佳的主要原因之一可能是由于数据不佳或理解不足。因此&a…

聊聊clickhouse分布式表的操作

序 本文主要研究一下clickhouse分布式表的操作 创建分布式表 CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] (name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],... ) ENGINE Distributed(clust…

接口01-Java

接口-Java 一、引入(快速入门案例)二、接口介绍1、概念2、语法 三、应用场景四、接口使用注意事项五、练习题1 一、引入(快速入门案例) usb插槽就是现实中的接口。 你可以把手机、相机、u盘都插在usb插槽上&#xff0c;而不用担心那个插槽是专门插哪个的&#xff0c;原因是做u…

解决git action发布失败报错:Error: Resource not accessible by integration

现象&#xff1a; 网上说的解决方法都是什么到github个人中心setting里面的action设置里面去找。 可这玩意根本就没有&#xff01; 正确解决办法&#xff1a; 在你的仓库页面&#xff0c;注意是仓库页面的setting里面&#xff1a; Actions> General>Workflow permisss…

苹果手机如何格式化?五个步骤快速掌握!

如果手机出现异常情况&#xff0c;例如运行缓慢、频繁崩溃&#xff0c;又或者想将手机出售、转让给他人&#xff0c;那么将手机格式化可以有助于解决问题。苹果手机如何格式化&#xff1f;本文将为您介绍解决方法&#xff0c;只需要五个步骤就能搞定&#xff0c;帮助您快速掌握…

【新手解答5】深入探索 C 语言:宏中的文本、标识符和字符串 + 递归运算、条件语句、循环 + `switch-case` 与多项条件和枚举的差别

C语言的相关问题解答 写在最前面问题1编程中的一般概念1. 文本2. 标识符3. 字符串 宏中的文本、标识符和字符串例子规范 问题二的笔记梳理递归运算条件语句循环中断&#xff08;提前退出&#xff09;、继续循环break 语句&#xff08;补充&#xff09;continue 语句&#xff08…

天软高频时序数据仓库

1天软高频时序数仓方案架构 天软高频时序数据仓库是深圳天软科技开发有限公司专为金融用户提供的专业高频行情数据处理方案&#xff0c;集数据接入、检查、处理、存储、查询、订阅、计算于一体。 方案支持各类系统的实时行情、非实时行情接入&#xff1b;还支持压缩存储、分布式…

使用 DMA 在 FPGA 中的 HDL 和嵌入式 C 之间传输数据

使用 DMA 在 FPGA 中的 HDL 和嵌入式 C 之间传输数据 该项目介绍了如何在 PL 中的 HDL 与 FPGA 中的处理器上运行的嵌入式 C 之间传输数据的基本结构。 介绍 鉴于机器学习和人工智能等应用的 FPGA 设计中硬件加速的兴起&#xff0c;现在是剥开几层“云雾”并讨论 HDL 之间来回传…

xv6 内核空间共享

首发公号&#xff1a;Rand_cs 共享内核空间 我们常说&#xff0c;每个进程都有自己的虚拟地址空间&#xff0c;但其中内核部分是共享的。 这就有个问题&#xff0c;如何共享的&#xff1f; 系统启动时创建了一张内核页表&#xff0c;里面记录着内核地址空间与物理地址空间的…

Peter算法小课堂—高精度减法

给大家看个小视频高精度减法_哔哩哔哩_bilibili 基本思想 计算机模拟人类做竖式计算&#xff0c;从而得到正确答案 大家还记得小学时学的“减法竖式”吗&#xff1f;是不是这样 x-y问题 函数总览&#xff1a; 1.converts() 字符串转为高精度大数 2.le() 判断大小 3.sub() …

【技术干货】宇视IPC音频问题解决步骤

近期技术人员从宇视官网下载sdk进行二次开发时&#xff0c;在启动实时直播&#xff0c;并通过回调函数拿到流数据&#xff0c;发现没有音频流数据。 通过下面的数据发现&#xff0c;codeType此字段一直是28&#xff0c;代表的是H.264数据&#xff0c;但未没发现有音频的数据包…