Java代码实现elasticSearch的DSL复合查询

elasticsearch提供DSL(domain specific language)查询,就是以json格式定义查询条件实现复杂条件查询。

DSL查询分为俩大类: 

  叶子查询:一般是在特定的字段里查询特定值,属于简单查询,很少单独使用。

  复合查询:以逻辑方式组合多个叶子查询后者更改叶子查询的行为方式。

我们还可以对查询结果做进一步的处理,博包括:排序、分页、高亮、聚合等等。

叶子查询:  叶子查询进一步细分有

  全文检索查询:利用分词器对用户输入内容分词,然后去词条列表中匹配。

  精确查询:不对用户输入内容分词,直接精确匹配,一般是查找keyword、数值、日期、布尔类型等等。

  地理查询:用于搜索地理位置。

 代码实现: 我已经把我数据库的信息存储一份到elasticSearch中了,各位在进行下面操作时不忘了把自己数据库的数据存储一份到elasticsearch。  在写代码时,我会先告诉大家在elasticsearch中的代码实现,然后根据elasticsearch的代码去实现Java代码。

    全文检索查询: match(单字段查询)    和    multi_match(多字段查询)        

注意:es中查询数据,最多查询到10000条,但控制台只会显示出10条。所以要注意看到查询结果中显示查询到数据10000条时,很可能符合条件的数据不止10000条。

#match查询所有
GET /items/_search
{"query": {"match": {"name": "脱脂牛奶"}}
}

控制台返回: 

 我来说一下返回数据中最外层的数据是什么意思:  took 表示查询话费的时间;timed_out表示是否超时;_shared 是分片情况;hits是命中情况,就是符合条件的基本信息。

我们主要看hits命中信息: 其中total中的vaule和relation分别是查询到的信息数量 和 查询方式equals。 max_score 表示最大相关性得分,es有个底层算法可以帮我们算出每条信息与我们搜索内容的相关性。然后后面又是一个hits,这个内层的hits就是我们查询到的每条数据的详细信息,_index表示在哪个索引库中进行的操作;_type表示对什么进行的操作,_source就是查到的每条数据了。

下面我们开始写相应的Java代码:

首先我们要初始化对es操作的客户端:

 private RestHighLevelClient client;@BeforeEachvoid setUp() {client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://localhost:9200")));}@AfterEachvoid tearDown() throws IOException {if (client != null) {client.close();}}

 然后我们就可以用client对es进行各种操作了。

//查询单、多字段@Testvoid testMatch() throws IOException {SearchRequest request = new SearchRequest("items");//索引库名//单字段request.source().query(QueryBuilders.matchQuery("name", "脱脂牛奶"));//多字段//request.source().query(QueryBuilders.multiMatchQuery("脱脂牛奶", "name", "category"));SearchResponse response = client.search(request, RequestOptions.DEFAULT);//解析数据SearchHits searchHits = response.getHits();SearchHit[] hits = searchHits.getHits();for (SearchHit hit : hits) {String source = hit.getSourceAsString();ItemDoc itemDoc = JSONUtil.toBean(source, ItemDoc.class);System.out.println("itemDoc: " + itemDoc);}}

首先创建一个用于发送请求的request对象,用于查询的用SearchRequest  ;

单字段就是只对一个字段做查询,比如查询name字段中有 脱脂牛奶 的 ,格式是matchQuery("name", "脱脂牛奶")先写字段名,在写查询内容 。多字段就是对多个字段进行查询,格式是 multiMatchQuery("脱脂牛奶", "name", "category") 先写查询内容,在写n个字段名,就是查询name中有"脱脂牛奶"的或者category中有"脱脂牛奶"的。发送请求用client.search(...) 返回响应数据response。

然后就是解析数据:这个要根据我们在es中做查询时返回的数据格式:我们要的是内层的那个hits中的source中的数据。而我们获取的response是最外面的大括号,里面有 took,timed_out,shards,hits。所以要先获取外层hits:SearchHits searchHits = response.getHits();然后在获取内层hits:SearchHit[] hits = searchHits.getHits();最后获取source:String source = hit.getSourceAsString();这样我们就获得了查询的详细信息了。

精确查询:

//精确查询@Testvoid testTerm() throws IOException {SearchRequest request = new SearchRequest("items");request.source().query(QueryBuilders.termQuery("brand", "德亚"));SearchResponse response = client.search(request, RequestOptions.DEFAULT);//解析数据explainData(response);}//范围查询@Testvoid testRange() throws IOException {SearchRequest request = new SearchRequest("items");request.source().query(QueryBuilders.rangeQuery("price").gte(10000).lte(15000));SearchResponse response = client.search(request, RequestOptions.DEFAULT);explainData(response);}

接下来说复合查询:可分为俩类

   第一类:基于逻辑运算组合叶子查询,例如bool;

  第二类:基于某种算法修改查询时的文档相关性算分,从而改变文档排名。

bool查询: 是一个或多个查询子句的组合,组合方式有:

must:必须匹配每个子查询,类似“与”;should:选择性匹配子查询,类似“或”;

must_not:必须不匹配,不参与算法,类似“非” ;filter:必须匹配,不参与算法。

这里说的算法指的是计算该数据与搜索内容相关性的算法,像品牌、价格就不需要参与算法。

@Testvoid testBool() throws IOException {SearchRequest request = new SearchRequest("items");request.source().query(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("name", "脱脂牛奶")).filter(QueryBuilders.termQuery("brand", "德亚")).filter(QueryBuilders.rangeQuery("price").lte(30000)));SearchResponse response = client.search(request, RequestOptions.DEFAULT);explainData(response);}
//我把解析数据的操作写成了一个方法
private void explainData(SearchResponse response) {SearchHits searchHits = response.getHits();TotalHits totalHits = searchHits.getTotalHits();System.out.println("total: " + totalHits);SearchHit[] hits = searchHits.getHits();for (SearchHit hit : hits) {String source = hit.getSourceAsString();ItemDoc itemDoc = JSONUtil.toBean(source, ItemDoc.class);Map<String, HighlightField> highlightFields = hit.getHighlightFields();if (highlightFields!=null&&!highlightFields.isEmpty()) {HighlightField name = highlightFields.get("name");if (name!=null){String hm = name.getFragments()[0].toString();itemDoc.setName(hm);}System.out.println("itemDoc: " + itemDoc);}}}

 

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

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

相关文章

anaconda powershell prompt中的指令

1.查看安装目录 pip list 或者 conda list 2.查看虚拟环境 conda env list 3.进入虚拟环境 conda activate 环境名称 例如&#xff1a;conda activate pytorch_learn 4.安装虚拟环境 conda create -n “” python 5.在虚拟环境中安装某模块/包 先进入虚拟环境 再 conda install…

spring tx @Transactional 详解 `Advisor`、`Target`、`ProxyFactory

在Spring中&#xff0c;Transactional注解的处理涉及到多个关键组件&#xff0c;包括Advisor、Target、ProxyFactory等。下面是详细的解析和代码示例&#xff0c;解释这些组件是如何协同工作的。 1. 关键组件介绍 1.1 Advisor Advisor是一个Spring AOP的概念&#xff0c;它包…

第16周:LSTM-火灾温度预测

目录 前言 一、LSTM简介 1.1 LSTM的本质 1.2 LSTM的提出 1.3 LSTM的原理 1.3.1 RNN原理介绍 1.3.2 LSTM原理介绍 二、前期准备 2.1 导入库、设置GPU 2.2 导入数据 2.3 构建数据集 2.3.1 数据集预处理 2.3.2 设置X&#xff0c;y 2.3.3 缺失值检测 2.3.4 划分数据…

【运维】磁盘满了怎么办?如何快速找到占用空间的文件和腾出空间

机器用久了&#xff0c;很容易生成很多临时或者无用的文件&#xff0c;占用大量空间造成磁盘不够用。尤其是服务器&#xff0c;当磁盘不够用时&#xff0c;系统会出现莫名其妙的问题&#xff0c;数据库可能会造成数据损坏。此时快速定位可以删除的大文件并及时释放空间&#xf…

AI Earth——1990-2022年全国月度气象数据检索应用app

应用结果 代码 #导入安装包 import os import json import datetime import streamlit as st import streamlit.components.v1 as components import traceback from PIL import Imageimport aie#读取当前目录的内容 current_work_dir = os.path.dirname(__file__) #添加地图…

leetcode--二叉树中的最大路径和

leetcode地址&#xff1a;二叉树中的最大路径和 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点&#xff0c;且不一定经过根节点。 路径和 是路径中各节点值的总…

Nginx+Tomcat群集

**Nginx Tomcat 集群** Nginx 和 Tomcat 集群的组合是一种常见且强大的架构方案&#xff0c;旨在实现高可用性、可扩展性和高性能的 Web 应用服务。 Nginx 是一款轻量级的高性能 Web 服务器和反向代理服务器。它能够高效地处理静态资源请求&#xff0c;并将动态请求转发到后…

pytest-yaml-sanmu(六):YAML数据驱动测试

如果说 pytest 中哪些标记使用得最多&#xff0c;那无疑是 parametrize 了&#xff0c; 它为用例实现了参数化测试的能力&#xff0c;进而实现了数据驱动测试的能力。 1. 使用标记 parametrize 的使用需要提高两个内容&#xff1a; 参数名 参数值 pytest 在执行用例时&…

6元/年英国Giffgaff卡申请和使用

官网&#xff1a;https://www.giffgaff.com/freesim-international 今天和大家分享一款来自英国的电话卡——Giffgaff&#xff0c;它能够在大陆正常使用&#xff0c;并且保号的费用也十分便宜&#xff0c;大约6元/年。自己免费申请的卡已经激活成功&#xff0c;将过程与大家分…

亚信安全新一代终端安全TrustOne2024年重磅升级

以极简新主义为核心&#xff0c;亚信安全新一代终端安全TrustOne自2023年发布以来&#xff0c;带动了数字化终端安全的革新。60%&#xff0c;安装部署及管理效率的提升&#xff1b;50%&#xff0c;安全管理资源的节省&#xff1b;100%&#xff0c;信创非信创场景的全覆盖。Trus…

FastReport 指定sql 和修改 数据库连接地址的 工具类 :FastReportHelper

FastReport 指定sql 和修改 数据库连接地址的 工具类 &#xff1a;FastReportHelper 介绍核心代码&#xff1a;完整代码&#xff1a; 介绍 在FastReport中&#xff0c;经常会遇到需要给 sql 加条件的情况&#xff0c;或者给数据库地址做更换。 &#xff08;废话不多说&#x…

java之循环练习题

思路分析&#xff1a; 代码&#xff1a; public static void main(String[] args) {int sum0;for (int i1;i<100;i){for (int j1;j<i;j) {sum j;}}System.out.println(sum);} 结果为&#xff1a;

DeepViT:字节提出深层ViT的训练策略 | 2021 arxiv

作者发现深层ViT出现的注意力崩溃问题&#xff0c;提出了新颖的Re-attention机制来解决&#xff0c;计算量和内存开销都很少&#xff0c;在增加ViT深度时能够保持性能不断提高 来源&#xff1a;晓飞的算法工程笔记 公众号 论文: DeepViT: Towards Deeper Vision Transformer 论…

提升爬虫OCR识别率:解决嘈杂验证码问题

引言 在数据抓取和网络爬虫技术中&#xff0c;验证码是常见的防爬措施&#xff0c;特别是嘈杂文本验证码。处理嘈杂验证码是一个复杂的问题&#xff0c;因为这些验证码故意设计成难以自动识别。本文将介绍如何使用OCR技术提高爬虫识别嘈杂验证码的准确率&#xff0c;并结合实际…

面向对象的程序设计设计思想(解决问题所需要的类),面向过程的程序设计思想(解决问题的步骤)

一、引言 面向对象思想是现代编程语言的主流编程思想&#xff0c;除了C语言外&#xff0c;其他的主流编程语言&#xff0c;无论是脚本的还是非脚本的&#xff0c;基本上都引入了面向对象这一设计思想&#xff0c;面向对象设计思想是怎样的&#xff1f;为什么现在的编程语言大都…

模型驱动开发(Model-Driven Development,MDD):提高软件开发效率与一致性的利器

目录 前言1. 模型驱动开发的原理1.1 什么是模型驱动开发1.2 MDD的核心思想 2. 模型驱动开发的优势2.1 提高开发效率2.2 确保代码一致性2.3 促进沟通和协作2.4 方便维护和扩展 3. 实现模型驱动开发的方法3.1 选择合适的建模工具3.1.1 UML3.1.2 BPMN3.1.3 SysML 3.2 建模方法3.2.…

大学生竞赛管理系统-计算机毕业设计源码37276

大学生竞赛管理系统的设计与实现 摘 要 随着教育信息化的不断发展&#xff0c;大学生竞赛已成为高校教育的重要组成部分。传统的竞赛组织和管理方式存在着诸多问题&#xff0c;如信息不透明、效率低下、管理不便等。为了解决这些问题&#xff0c;提高竞赛组织和管理效率&#x…

K8S 上部署大数据相关组件

文章目录 一、前言二、Redis 一、前言 Artifact Hub 是一个专注于云原生应用的集中式搜索和发布平台。它旨在简化开发者在 CNCF&#xff08;Cloud Native Computing Foundation&#xff09;项目中寻找、安装和分享包与配置的过程。用户可以通过这个平台方便地发现、安装各类云原…

用SurfaceView实现落花动画效果

上篇文章 Android子线程真的不能刷新UI吗&#xff1f;(一&#xff09;复现异常 中可以看出子线程更新main线程创建的View&#xff0c;会抛出异常。SurfaceView不依赖main线程&#xff0c;可以直接使用自己的线程控制绘制逻辑。具体代码怎么实现了&#xff1f; 这篇文章用Surfa…

vscode启用项目后,没有触发debugger

启动项目后在debugger时&#xff0c;一直不走断点&#xff0c;重启vscode和电脑&#xff0c;打开其他vscode项目&#xff0c;都不行 1.F12点击设置 2.然后取消忽略列表的勾选即可。