【ElasticSearch】深入探索 DSL 查询语法,实现对文档不同程度的检索,以及对搜索结果的排序、分页和高亮操作

文章目录

  • 前言
  • 一、Elasticsearch DSL Query 的分类
  • 二、全文检索查询
    • 2.1 `match` 查询
    • 2.2 `multi_match` 查询
  • 三、精确查询
    • 3.1 term 查询
    • 3.2 range 查询
  • 四、地理坐标查询
    • 4.1 geo_bounding_box 查询
    • 4.2 geo_distance 查询
  • 五、复合查询
    • 5.1 function score 查询
    • 5.2 boolean 查询
  • 六、对搜索结果的处理
    • 6.1 对搜索结果进行排序
    • 6.2 对搜索结果进行分页
    • 6.3 对搜索结果中的搜索关键字高亮处理

前言

Elasticsearch(简称ES)是一个强大的开源搜索和分析引擎,广泛应用于各种应用程序中,从企业级搜索引擎到日志和指标分析。其强大之处在于其灵活的数据模型和丰富的查询语言,使得用户能够轻松地进行全文检索、精确查询、地理坐标查询等操作。

本文将深入探讨Elasticsearch的DSL(Domain Specific Language)查询,分为多个部分进行介绍。首先,我们会了解Elasticsearch DSL Query的分类,然后深入研究全文检索查询、精确查询、地理坐标查询以及复合查询等不同类型的查询。

每一节都会提供详细的语法和实际示例,以便读者能够更好地理解和运用Elasticsearch中强大的查询功能。最后,我们将介绍对搜索结果进行排序、分页以及搜索关键字高亮处理等实用的处理技巧,以完善搜索体验。

让我们开始深入探讨Elasticsearch DSL Query,发现如何利用其强大的功能来提升搜索和分析的效果。

一、Elasticsearch DSL Query 的分类

Elasticsearch 提供了强大而灵活的DSL(领域特定语言)查询,用于定义对索引库中文档的不同类型查询。下面将详细介绍一些常见的 DSL查询类型:

1. 查询所有 - match_all

查询所有文档,通常用于测试或获取整个索引的文档。

{"query": {"match_all": {}}
}

2. 全文检索查询

  • match 查询

利用分词器对用户输入的内容进行分词,然后在索引中匹配分词后的词语。

{"query": {"match": {"field_name": "search_text"}}
}
  • multi_match 查询

在多个字段上执行全文检索查询。

{"query": {"multi_match": {"query": "search_text","fields": ["field1", "field2"]}}
}

3. 精确查询

  • ids 查询

根据文档ID查询文档。

{"query": {"ids": {"values": ["doc_id1", "doc_id2"]}}
}
  • term 查询

根据精确词条值查找数据,适用于 keyword、数值、日期、boolean等类型字段。

{"query": {"term": {"field_name": "exact_value"}}
}
  • range 查询

根据范围查询,适用于数值、日期等类型的范围查询。

{"query": {"range": {"field_name": {"gte": "start_value","lte": "end_value"}}}
}

4. 地理查询

  • geo_distance 查询

根据经纬度查询指定距离范围内的文档。

{"query": {"geo_distance": {"distance": "10km","location": {"lat": 40.73,"lon": -73.98}}}
}
  • geo_bounding_box 查询

根据指定的矩形框查询文档。

{"query": {"geo_bounding_box": {"location": {"top_left": {"lat": 40.73,"lon": -74.1},"bottom_right": {"lat": 40.01,"lon": -71.12}}}}
}

5. 复合查询

  • bool 查询

通过组合多个查询条件,支持must、must_not、should等逻辑。

{"query": {"bool": {"must": [{ "match": { "field1": "value1" } },{ "range": { "field2": { "gte": 10, "lte": 20 } } }],"must_not": [{ "term": { "field3": "value2" } }],"should": [{ "match": { "field4": "value3" } }]}}
}
  • function_score 查询

根据某个函数计算的分数对查询结果进行打分,用于加权不同的查询条件。

{"query": {"function_score": {"query": { "match": { "field": "search_text" } },"functions": [{"filter": { "range": { "field2": { "gte": 10, "lte": 20 } } },"weight": 2}],"score_mode": "multiply"}}
}

以上是一些常见的 Elasticsearch DSL查询类型,在使用的时候可以根据具体需求灵活组合这些查询条件来实现复杂的搜索和过滤功能。下面是针对于这些不同查询的详细说明以及查询演示。

二、全文检索查询

全文检索查询是通过对用户输入的内容进行分词,然后在索引中匹配分词后的词语,实现更灵活的文本搜索。在Elasticsearch中,常用的关键词是 matchmulti_match

2.1 match 查询

match查询会根据一个字段进行查询,适用于单一字段的全文检索。在实际应用中,可以使用 copy_to 将多个字段的值合并到一个字段,从而实现类似 multi_match 的查询效果。

例如,针对 hotel 索引库的全文检索查询:

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

这里假设 all 字段是通过 copy_to 包含了多个字段的内容,如:“brand”、“business”、“name”。查询结果如下:

match查询结果

2.2 multi_match 查询

multi_match查询允许根据多个字段进行全文检索查询,但需要注意,参与查询的字段越多,查询效率可能越低。

例如,使用 multi_match 查询:

GET /hotel/_search
{"query": {"multi_match": {"query": "如家","fields": ["brand", "business", "name"]}}
}

在这个例子中,参与查询的字段同样是:“brand”、“business”、 “name”。查询结果如下:

multi_match查询结果

可以观察到,matchmulti_match 的查询结果是相同的。在实际应用中,选择使用哪种方式要根据具体需求和性能考虑来决定。

三、精确查询

精确查询是搜索引擎中常用的查询方式,特别适用于针对关键字、数值、日期、boolean等类型字段的精准检索。在酒店订购网站等应用中,用户通常希望根据特定的条件,如城市、星级、品牌、价格范围等,进行准确的信息检索。

下面将介绍在 Elasticsearch 中如何使用 termrange 进行精确查询。

3.1 term 查询

term 查询用于根据词条的精确值进行查询。例如,在酒店订购网站中,用户希望查找位于上海的所有酒店,可以使用以下 DSL 语句:

GET /hotel/_search
{"query": {"term": {"city": {"value": "上海"}}}
}

查询结果:

上述查询返回了所有城市为上海的酒店信息。然而,要注意的是,term 查询对查询关键字的精确匹配要求较高。如果将查询的值更改为 “上海北京”,将找不到匹配的结果:

因此,在使用 term 查询时,务必确保查询的关键字是准确的。

3.2 range 查询

range 查询用于根据值的范围进行查询,特别适用于数值型字段,比如价格范围。例如,用户希望查找价格在 100 到 200 之间的酒店,可以使用以下 DSL 语句:

GET /hotel/_search
{"query": {"range": {"price": {"gte": 100,"lte": 200}}}
}

查询结果:

在上述查询中,使用了 gte 表示大于等于某个值,而 lte 表示小于等于某个值。通过这样的查询,可以精确地获取符合价格范围的酒店信息。

总的来说,精确查询在搜索引擎中是非常常用且实用的功能,通过合理使用 termrange 查询,可以满足用户对于准确信息检索的需求。

四、地理坐标查询

地理坐标查询是 Elasticsearch 中常见的功能之一,特别适用于需要根据地理位置信息进行搜索的场景,如查询附近的酒店、出租车、或者附近的人。下面介绍两种常用的地理坐标查询方式:geo_bounding_boxgeo_distance

4.1 geo_bounding_box 查询

geo_bounding_box 查询用于查询 geo_point 值在某个矩形范围内的所有文档。以下是一个示例:

GET /indexName/_search
{"query": {"geo_bounding_box": {"FIELD": {"top_left": {"lat": 31.1,"lon": 121.5},"bottom_right": {"lat": 30.9,"lon": 121.7}}}}
}

在这个例子中,通过指定矩形的左上角和右下角的经纬度,可以查询所有位置在这个矩形范围内的文档。

搜索范围示意图,形状为矩形:

4.2 geo_distance 查询

geo_distance 查询用于查询到指定中心点距离小于某个距离值的所有文档。以下是一个示例:

GET /indexName/_search
{"query": {"geo_distance": {"distance": "15km","FIELD": "31.21,121.5"}}
}

在这个例子中,通过指定中心点的经纬度和距离值,可以查询所有距离中心点小于 15 公里的文档。

搜索范围示意图,形状为圆:

通过这两种方式,可以在地理坐标信息中实现灵活而精确的查询,满足用户在不同应用场景下的位置搜索需求。

五、复合查询

复合(compound)查询可以将其它简单查询组合起来,实现更复杂的搜索逻辑,例如:

  • function score: 算分函数查询,可以控制文档相关性算分,控制文档排名,类似于百度搜索结果中一些顶置的广告。

  • Boolean Query:布尔查询,一个或多个查询子句的组合,子查询的组合方式有:

    • must:必须匹配每个子查询,类似“与”。
    • should:选择性匹配子查询,类似“或”。
    • must_not:必须不匹配,不参与算分,类似“非”。
    • filter:必须匹配,不参与算分。

5.1 function score 查询

假设,现在文档中有一些是广告,我们希望这些广告在查询结果中是最靠前的,因此可以使用 function score 查询来修改特定文档的打分,例如,给“如家”这个品牌的酒店排名靠前一定:

为了实现这个目标,我们需要提供以下三个要素:

  1. 哪些文档需要算分加权?

    • 品牌为如家的酒店。
  2. 算分函数是什么?

    • weight
  3. 加权模式是什么?

    • 乘积。

查询 DSL 语句如下:

GET /hotel/_search
{"query": {"function_score": {"query": {"match": {"all": "上海"}},"functions": [{"filter": {"term": {"brand": "如家"}},"weight": 10}],"boost_mode": "multiply"}}
}

说明:

  • query :原始查询条件,搜索文档并根据相关性打分(query score)。
  • filter:过滤条件,符合条件的文档才会被重新算分。
  • weight:算分函数,算分函数的结果称为 function score ,将来会与 query score 运算,得到新算分。常见的算分函数有:
    • weight:给一个常量值,作为函数结果(function score)。
    • field_value_factor:用文档中的某个字段值作为函数结果。
    • random_score:随机生成一个值,作为函数结果。
    • script_score:自定义计算公式,公式结果作为函数结果。
  • boost_mode:加权模式,定义 function score 与 query score 的运算方式,包括:
    • multiply:两者相乘。默认就是这个。
    • replace:用 function score 替换 query score。
    • 其它:sumavgmaxmin

查询结果:
Function Score Query Result

5.2 boolean 查询

例如,现在有一个查询需求:搜索名字包含“如家”,价格不高于400,在坐标31.21,121.5周围 10km 范围内的酒店。

GET /hotel/_search
{"query": {"bool": {"must": [{"match": {"name": "如家"}}],"must_not": [{"range": {"price": {"gte": 400}}}],"filter": [{"geo_distance": {"distance": "10km","location": {"lat": 31.21,"lon": 121.5}}}]}}
}

说明:

  • must:必须匹配每个子查询,类似“与”。
  • must_not:必须不匹配,不参与算分,类似“非”。
  • filter:必须匹配,不参与算分。

搜索结果:

Boolean Query Result

通过这个例子,我们可以看到如何使用布尔查询来组合多个条件,实现更精确的搜索。

六、对搜索结果的处理

6.1 对搜索结果进行排序

ElasticSearch 支持对搜索结果排序,默认是根据相关度算分(_score)来排序。可以排序字段类型有:keyword 类型、数值类型、地理坐标类型、日期类型等。

示例一:对酒店数据按照用户评价降序排序,评价相同的按照价格升序排序

评价是 score 字段,价格是 price 字段,按照顺序添加两个排序规则即可。

GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"score": "desc"},{"price": "asc"}]
}

示例二:实现对酒店数据按照到(121.507712,31.224612)的位置坐标的距离升序排序

获取经纬度的方式:https://lbs.amap.com/demo/jsapi-v2/example/map/click-to-get-lnglat/。

GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"_geo_distance": {"location": {"lat": 31.224612,"lon": 121.507712},"order": "asc","unit": "km"}}]
}

6.2 对搜索结果进行分页

ElasticSearch 默认情况下只返回 top 10 的数据。而如果要查询更多数据就需要修改分页参数了。ElasticSearch 中通过修改 fromsize 参数来控制要返回的分页结果。

基本语法如下:

GET /hotel/_search
{"query": {"match_all": {}},"from": 990, // 分页开始的位置,默认为0"size": 10, // 期望获取的文档总数"sort": [{"price": "asc"}]
}

示例:使用 match_all 查询,然后对结果进行分页

GET /hotel/_search
{"query": {"match_all": {}},"from": 0,"size": 5
}

搜索结果,现在就只展示5条结果了:

分页结果

深度分页问题:

ES是分布式的,所以会面临深度分页问题。例如按 price 排序后,获取 from = 990,size =10 的数据:

  1. 首先在每个数据分片上都排序并查询前1000条文档。
  2. 然后将所有节点的结果聚合,在内存中重新排序选出前1000条文档。
  3. 最后从这1000条中,选取从990开始的10条文档。

如果搜索页数过深,或者结果集(from + size)越大,对内存和 CPU 的消耗也越高。因此 ES 设定结果集查询的上限是10000。

深度分页解决方案:

针对深度分页,ES提供了两种解决方案:

  1. **search after:**分页时需要排序,原理是从上一次的排序值开始,查询下一页数据。官方推荐使用的方式。
  2. **scroll:**原理将排序数据形成快照,保存在内存。官方已经不推荐使用。

6.3 对搜索结果中的搜索关键字高亮处理

高亮处理,就是在搜索结果中把搜索关键字突出显示。

原理:

  • 将搜索结果中的关键字用标签标记出来。
  • 在页面中给标签添加 CSS 样式。

语法:

GET /hotel/_search
{"query": {"match": {"FIELD": "TEXT"}},"highlight": {"fields": {"FIELD": {"pre_tags": "<em>",  // 用来标记高亮字段的前置标签"post_tags": "</em>" // 用来标记高亮字段的后置标签}}}
}

示例:对搜索的品牌名称进行高亮处理

GET /hotel/_search
{"query": {"match": {"brand": "如家"}},"highlight": {"fields": {"brand": {"pre_tags": "<em>","post_tags": "</em>"}}}
}

搜索结果:

高亮搜索结果

以上便是对ElasticSearch搜索结果进行排序、分页和关键字高亮处理的一些示例和基本操作。

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

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

相关文章

WorkPlus一站式解决方案,助力企业构建统一门户系统

在信息爆炸的时代&#xff0c;企业管理面临着海量的数据和各类业务应用的复杂性。如何实现信息的井然有序、高效管理&#xff0c;成为企业发展的关键。WorkPlus作为领先的品牌&#xff0c;致力于打造统一门户系统&#xff0c;为企业提供全方位的服务和解决方案。本文将以知乎的…

广州华锐互动:候车室智能数字孪生系统实现交通信息可视化

随着科技的不断发展&#xff0c;数字化技术在各个领域得到了广泛的应用。智慧车站作为一种新型的交通服务模式&#xff0c;通过运用先进的数字化技术&#xff0c;为乘客提供了更加便捷、舒适的出行体验。 将智慧车站与数字孪生大屏结合&#xff0c;可以将实际现实世界的实体车站…

java 无感hook实现(修改jdk)

背景 1 工作需要&#xff0c;需要修改一个java的程序逻辑&#xff0c;之前都是用的frida修改的&#xff0c;但是现在的工作场景&#xff0c;重视效率&#xff0c;所以frida这种重工具被pass了&#xff0c;只能重新选其他工具&#xff0c;初始的时候是想用java本身的一些修改工…

纸、纸板和纸制品 有效回收组分的测定

声明 本文是学习GB-T 42944-2023 纸、纸板和纸制品 有效回收组分的测定. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件描述了纸、纸板和纸制品中有效回收组分的测定方法。 本文件适用于各种纸、纸板和纸制品&#xff0c;也适用于铝箔…

微信小程序通过 movable-area 做一个与vuedraggable相似的上下拖动排序控件

因为只是做个小案例 我就直接代码写page页面里了 其实很简单 组件稍微改一下就好了 wxss /* 设置movable-area的宽度 */ .area{width: 100%; }/* a b c 每条元素的样式 */ movable-view {width: 100%;background-color: red;height: 40px;line-height: 40px;color: #FFFFFF;tex…

day

#include <iostream> using namespace std; class Per {//算术运算符friend const Per operator(const Per &k1,const Per &k2);friend const Per operator-(const Per &k1,const Per &k2);friend const Per operator*(const Per &k1,const Per &…

3ds Max渲染太慢?创意云“一键云渲染”提升3ds Max渲染体验

&#xfeff;在数字艺术设计领域&#xff0c;3ds Max是广泛使用的三维建模和渲染软件之一。然而&#xff0c;许多用户都面临着一个共同的问题&#xff1a;渲染速度太慢。渲染一帧画面需要耗费数小时&#xff0c;让人无法忍受。除了之前给大家介绍的几种解决方法外&#xff1a; …

Vue3中reactive, onMounted, ref,toRaw,conmpted 使用方法

import { reactive, onMounted, ref,toRaw,conmpted } from vue; vue3中 reactive &#xff0c;ref &#xff0c; toRaw&#xff0c;watch&#xff0c;conmpted 用法 toRaw 返回原响应式对象 用法&#xff1a; const rowList toRaw(row) reactive:ref: ref和reactive都是V…

快讯|Tubi 有 Rabbit AI 啦

在每月一期的 Tubi 快讯中&#xff0c;你将全面及时地获取 Tubi 最新发展动态&#xff0c;欢迎星标关注【比图科技】微信公众号&#xff0c;一起成长变强&#xff01; Tubi 推出 Rabbit AI 帮助用户找到喜欢的视频内容 Tubi 于今年九月底推出了 Rabbit AI&#xff0c;这是一项…

有效回收组分含量

声明 本文是学习GB-T 42944-2023 纸、纸板和纸制品 有效回收组分的测定. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件描述了纸、纸板和纸制品中有效回收组分的测定方法。 本文件适用于各种纸、纸板和纸制品&#xff0c;也适用于铝箔…

【自动驾驶】PETR/PETRv2/StreamPETR论文分析

1.PETR PETR网络结构如下&#xff0c;主要包括image-backbone, 3D Coordinates Generator, 3D Position Encoder, transformer Decoder 1.1 Images Backbone 采用resnet 或者 vovNet,下面的x表示concatenate 1.2 3D Coordinates Generator 坐标生成跟lss类似&#xff0c;假…

如何对比github中不同commits的区别

有时候想要对比跨度几十个commits之前的代码区别&#xff0c;想直接使用github的用户界面。可以直接在官网操作。 示例 首先要创建一个旧commit的branch。进入该旧的commit&#xff0c;然后输入branch名字即可。 然后在项目网址后面加上compare即可对比旧的branch和新的bran…

【轻松玩转MacOS】故障排除篇

引言 在使用 MacOS 时&#xff0c;遇到故障是在所难免的。不要担心&#xff0c;这篇文章将为您提供一些常见的故障排除步骤&#xff0c;并介绍如何联系苹果的支持团队寻求帮助。让我们一起来看看吧&#xff01; 一、常见的故障排除步骤 1.1 网络连接问题 如果你发现你的Mac…

初识华为云数据库GaussDB for openGauss

01 前言 GaussDB是华为自主创新研发的分布式关系型数据库。该产品具备企业级复杂事务混合负载能力&#xff0c;同时支持分布式事务&#xff0c;同城跨AZ部署&#xff0c;数据0丢失&#xff0c;支持1000的扩展能力&#xff0c;PB级海量存储。同时拥有云上高可用&#xff0c;高可…

【postgresql】ERROR: integer out of range

查询文章都类似&#xff0c;只是类型没有对应上&#xff0c;根据实际情况处理。 前情 使用postgresql数据库数据库ID类型int4实体类代码private Long id; 异常 ### Cause: org.postgresql.util.PSQLException: ERROR: integer out of range ; ERROR: integer out of range;…

Go 语言切片扩容规则是扩容2倍?1.25倍?到底几倍

本次主要来聊聊关于切片的扩容是如何扩的&#xff0c;还请大佬们不吝赐教 切片&#xff0c;相信大家用了 Go 语言那么久这这种数据类型并不陌生&#xff0c;但是平日里聊到关于切片是如何扩容的&#xff0c;很多人可能会张口就来&#xff0c;切片扩容的时候&#xff0c;如果老…

unity中绑定动画的行为系统

主要代码逻辑是创建一个action队列,当动画播放结束时就移除队头,执行后面的事件 public class Enemy : MonoBehaviour {public event Action E_AnimatorFin;//当动画播放完毕时public Action DefaultAction;//默认事件public Dictionary<Action, string> EventAnimator n…

基于 chinese-roberta-wwm-ext 微调训练中文命名实体识别任务

一、模型和数据集介绍 1.1 预训练模型 chinese-roberta-wwm-ext 是基于 RoBERTa 架构下开发&#xff0c;其中 wwm 代表 Whole Word Masking&#xff0c;即对整个词进行掩码处理&#xff0c;通过这种方式&#xff0c;模型能够更好地理解上下文和语义关联&#xff0c;提高中文文…

振弦传感器和振弦采集仪应用隧道安全监测的解决方案

振弦传感器和振弦采集仪应用隧道安全监测的解决方案 现代隧道越来越复杂&#xff0c;对于隧道安全的监测也变得越来越重要。振弦传感器和振弦采集仪已经成为了一种广泛应用的技术&#xff0c;用于隧道结构的监测和评估。它们可以提供更精确的测量结果&#xff0c;并且可以在实…

0基础学习VR全景平台篇 第104篇:720全景后期软件安装

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 摄影进入数码时代&#xff0c;后期软件继承“暗房工艺”&#xff0c;成为摄影师表达内在情感的必备工具。 首先说明&#xff0c;全景摄影与平面摄影的一个显著的区别是全景图片需…