elasticsearch[二]-DSL查询语法:全文检索、精准查询(term/range)、地理坐标查询(矩阵、范围)、复合查询(相关性算法)、布尔查询

ES-DSL查询语法(全文检索、精准查询、地理坐标查询)

1.DSL查询文档

elasticsearch 的查询依然是基于 JSON 风格的 DSL 来实现的。

1.1.DSL 查询分类

Elasticsearch 提供了基于 JSON 的 DSL(Domain Specific Language)来定义查询。常见的查询类型包括:

  • 查询所有:查询出所有数据,一般测试用。例如:match_all

  • 全文检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:

    • match_query
    • multi_match_query
  • 精确查询:根据精确词条值查找数据,一般是查找 keyword、数值、日期、boolean 等类型字段。例如:

    • ids
    • range
    • term
  • 地理(geo)查询:根据经纬度查询。例如:

    • geo_distance
    • geo_bounding_box
  • 复合(compound)查询:复合查询可以将上述各种查询条件组合起来,合并查询条件。例如:

    • bool
    • function_score

查询的语法基本一致:

GET /indexName(索引库名称)/_search
{"query": {"查询类型": {"查询条件": "条件值"}}
}

我们以查询所有为例,其中:

  • 查询类型为 match_all
  • 没有查询条件
// 查询所有
GET /heima/_search
{"query": {"match_all": {}}
}

其它查询无非就是查询类型查询条件的变化。

1.2. 全文检索查询

1.2.1. 使用场景

全文检索查询的基本流程如下:

  • 对用户搜索的内容做分词,得到词条
  • 根据词条去倒排索引库中匹配,得到文档 id
  • 根据文档 id 找到文档,返回给用户

比较常用的场景包括:

  • 商城的输入框搜索
  • 百度输入框搜索

例如京东:

因为是拿着词条去匹配,因此参与搜索的字段也必须是可分词的 text 类型的字段。

1.2.2. 基本语法

常见的全文检索查询包括:

  • match 查询:单字段查询
  • multi_match 查询:多字段查询,任意一个字段符合条件就算符合查询条件

match 查询语法如下:

GET /indexName/_search
{"query": {"match": {"FIELD": "TEXT"}}
}

mulit_match 语法如下:

GET /indexName/_search
{"query": {"multi_match": {"query": "TEXT","fields": ["FIELD1", " FIELD12"]}}
}

1.2.3. 示例

match 查询示例:

multi_match 查询示例:

可以看到,两种查询结果是一样的,为什么?

因为我们将 brand、name、business 值都利用 copy_to 复制到了 all 字段中。因此你根据三个字段搜索,和根据 all 字段搜索效果当然一样了。

但是,搜索字段越多,对查询性能影响越大,因此建议采用 copy_to,然后单字段查询的方式。

1.2.4. 总结

match 和 multi_match 的区别是什么?

  • match:根据一个字段查询
  • multi_match:根据多个字段查询,参与查询字段越多,查询性能越差

1.3. 精准查询

精确查询一般是查找 keyword、数值、日期、boolean 等类型字段。所以不会对搜索条件分词。常见的有:

  • term:根据词条精确值查询
  • range:根据值的范围查询

1.3.1.term 查询

因为精确查询的字段搜是不分词的字段,因此查询的条件也必须是不分词的词条。查询时,用户输入的内容跟自动值完全匹配时才认为符合条件。如果用户输入的内容过多,反而搜索不到数据。

语法说明:

// term查询
GET /indexName/_search
{"query": {"term": {"FIELD": {"value": "VALUE"}}}
}

示例:

当我搜索的是精确词条时,能正确查询出结果:

但是,当我搜索的内容不是词条,而是多个词语形成的短语时,反而搜索不到:

1.3.2.range 查询

范围查询,一般应用在对数值类型做范围过滤的时候。比如做价格范围过滤。

基本语法:

// range查询
GET /indexName/_search
{"query": {"range": {"FIELD": {"gte": 10, // 这里的gte代表大于等于,gt则代表大于"lte": 20 // lte代表小于等于,lt则代表小于}}}
}

示例:

1.3.3. 总结

精确查询常见的有哪些?

  • term 查询:根据词条精确匹配,一般搜索 keyword 类型、数值类型、布尔类型、日期类型字段
  • range 查询:根据数值范围查询,可以是数值、日期的范围

1.4. 地理坐标查询

所谓的地理坐标查询,其实就是根据经纬度查询,官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-queries.html

常见的使用场景包括:

  • 携程:搜索我附近的酒店
  • 滴滴:搜索我附近的出租车
  • 微信:搜索我附近的人

附近的酒店:

附近的车:

1.4.1. 矩形范围查询

矩形范围查询,也就是 geo_bounding_box 查询,查询坐标落在某个矩形范围的所有文档:

查询时,需要指定矩形的左上右下两个点的坐标,然后画出一个矩形,落在该矩形内的都是符合条件的点。

语法如下:

// geo_bounding_box查询
GET /indexName/_search
{"query": {"geo_bounding_box": {"FIELD": {"top_left": { // 左上点"lat": 31.1,"lon": 121.5},"bottom_right": { // 右下点"lat": 30.9,"lon": 121.7}}}}
}

这种并不符合 “附近的人” 这样的需求,所以我们就不做了。

1.4.2. 附近查询

附近查询,也叫做距离查询(geo_distance):查询到指定中心点小于某个距离值的所有文档。

换句话来说,在地图上找一个点作为圆心,以指定距离为半径,画一个圆,落在圆内的坐标都算符合条件:

语法说明:

// geo_distance 查询
GET /indexName/_search
{"query": {"geo_distance": {"distance": "15km", // 半径"FIELD": "31.21,121.5" // 圆心}}
}

示例:

我们先搜索陆家嘴附近 15km 的酒店:

发现共有 47 家酒店。

然后把半径缩短到 3 公里:

1.5. 复合查询

复合(compound)查询:复合查询可以将其它简单查询组合起来,实现更复杂的搜索逻辑。常见的有两种:

  • fuction score:算分函数查询,可以控制文档相关性算分,控制文档排名
  • bool query:布尔查询,利用逻辑关系组合多个其它的查询,实现复杂搜索

1.5.1. 相关性算分

当我们利用 match 查询时,文档结果会根据与搜索词条的关联度打分(_score),返回结果时按照分值降序排列。

例如,我们搜索 “虹桥如家”,结果如下:

[{"_score" : 17.850193,"_source" : {"name" : "虹桥如家酒店真不错",}},{"_score" : 12.259849,"_source" : {"name" : "外滩如家酒店真不错",}},{"_score" : 11.91091,"_source" : {"name" : "迪士尼如家酒店真不错",}}
]

在 elasticsearch 中,早期使用的打分算法是 TF-IDF 算法,公式如下:

在后来的 5.1 版本升级中,elasticsearch 将算法改进为 BM25 算法,公式如下:

TF-IDF 算法有一各缺陷,就是词条频率越高,文档得分也会越高,单个词条对文档影响较大。而 BM25 则会让单个词条的算分有一个上限,曲线更加平滑:

小结:elasticsearch 会根据词条和文档的相关度做打分,算法由两种:

  • TF-IDF 算法
  • BM25 算法,elasticsearch5.1 版本后采用的算法

1.5.2. 算分函数查询

根据相关度打分是比较合理的需求,但合理的不一定是产品经理需要的。

以百度为例,你搜索的结果中,并不是相关度越高排名越靠前,而是谁掏的钱多排名就越靠前。如图:

要想认为控制相关性算分,就需要利用 elasticsearch 中的 function score 查询了。

1)语法说明

function score 查询中包含四部分内容:

  • 原始查询条件:query 部分,基于这个条件搜索文档,并且基于 BM25 算法给文档打分,原始算分(query score)
  • 过滤条件:filter 部分,符合该条件的文档才会重新算分
  • 算分函数:符合 filter 条件的文档要根据这个函数做运算,得到的函数算分(function score),有四种函数
    • weight:函数结果是常量
    • field_value_factor:以文档中的某个字段值作为函数结果
    • random_score:以随机数作为函数结果
    • script_score:自定义算分函数算法
  • 运算模式:算分函数的结果、原始查询的相关性算分,两者之间的运算方式,包括:
    • multiply:相乘
    • replace:用 function score 替换 query score
    • 其它,例如:sum、avg、max、min

function score 的运行流程如下:

  • 1)根据原始条件查询搜索文档,并且计算相关性算分,称为原始算分(query score)
  • 2)根据过滤条件,过滤文档
  • 3)符合过滤条件的文档,基于算分函数运算,得到函数算分(function score)
  • 4)将原始算分(query score)和函数算分(function score)基于运算模式做运算,得到最终结果,作为相关性算分。

因此,其中的关键点是:

  • 过滤条件:决定哪些文档的算分被修改
  • 算分函数:决定函数算分的算法
  • 运算模式:决定最终算分结果
2)示例

需求:给 “如家” 这个品牌的酒店排名靠前一些

翻译一下这个需求,转换为之前说的四个要点:

  • 原始条件:不确定,可以任意变化
  • 过滤条件:brand = “如家”
  • 算分函数:可以简单粗暴,直接给固定的算分结果,weight
  • 运算模式:比如求和

因此最终的 DSL 语句如下:

GET /hotel/_search
{"query": {"function_score": {"query": {  .... }, // 原始查询,可以是任意条件"functions": [ // 算分函数{"filter": { // 满足的条件,品牌必须是如家"term": {"brand": "如家"}},"weight": 2 // 算分权重为2}],"boost_mode": "sum" // 加权模式,求和}}
}

测试,在未添加算分函数时,如家得分如下:

添加了算分函数后,如家得分就提升了:

3)小结

function score query 定义的三要素是什么?

  • 过滤条件:哪些文档要加分
  • 算分函数:如何计算 function score
  • 加权方式:function score 与 query score 如何运算

1.5.3. 布尔查询

布尔查询是一个或多个查询子句的组合,每一个子句就是一个子查询。子查询的组合方式有:

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

比如在搜索酒店时,除了关键字搜索外,我们还可能根据品牌、价格、城市等字段做过滤:

每一个不同的字段,其查询的条件、方式都不一样,必须是多个不同的查询,而要组合这些查询,就必须用 bool 查询了。

需要注意的是,搜索时,参与打分的字段越多,查询的性能也越差。因此这种多条件查询时,建议这样做:

  • 搜索框的关键字搜索,是全文检索查询,使用 must 查询,参与算分
  • 其它过滤条件,采用 filter 查询。不参与算分
1)语法示例:
GET /hotel/_search
{"query": {"bool": {"must": [{"term": {"city": "上海" }}],"should": [{"term": {"brand": "皇冠假日" }},{"term": {"brand": "华美达" }}],"must_not": [{ "range": { "price": { "lte": 500 } }}],"filter": [{ "range": {"score": { "gte": 45 } }}]}}
}
2)示例

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

分析:

  • 名称搜索,属于全文检索查询,应该参与算分。放到 must 中
  • 价格不高于 400,用 range 查询,属于过滤条件,不参与算分。放到 must_not 中
  • 周围 10km 范围内,用 geo_distance 查询,属于过滤条件,不参与算分。放到 filter 中

3)小结

bool 查询有几种逻辑关系?

  • must:必须匹配的条件,可以理解为 “与”
  • should:选择性匹配的条件,可以理解为 “或”
  • must_not:必须不匹配的条件,不参与打分
  • filter:必须匹配的条件,不参与打分

参考链接:https://www.cnblogs.com/DeryKong/p/17002533.html

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

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

相关文章

2024年【广东省安全员B证第四批(项目负责人)】考试试卷及广东省安全员B证第四批(项目负责人)模拟考试题

题库来源:安全生产模拟考试一点通公众号小程序 2024年【广东省安全员B证第四批(项目负责人)】考试试卷及广东省安全员B证第四批(项目负责人)模拟考试题,包含广东省安全员B证第四批(项目负责人&…

Linux -- Nginx服务基础

4.1Nginx服务基础 Nginx(发音为[engine x])专为性能优化而开发,其最知名的优点是它的稳定性和低系统资源消 耗,以及对HTTP并发连接的高处理能力(单台物理服务器可支持30000~50000个并发请求),正因 为如此,…

振弦采集仪在隧道工程监测中的应用与效果评估

振弦采集仪在隧道工程监测中的应用与效果评估 振弦采集仪在隧道工程监测中起到了重要的作用,主要用于对隧道结构的振动进行监测和分析。通过测量振弦的振动频率和振幅,可以评估隧道结构的稳定性和安全性。 振弦采集仪的应用主要体现在以下几个方面&…

edge 指纹浏览,多账号

1.需求来源: 登录多个推特账号来测试 2.方法: 2.1 多个手机 pass 2.2 浏览器 --- 源于chrom浏览器多账号的应用 3.指纹浏览器可以实现,那么win11自带浏览器呢 看图:​​​​​​​ 新建个人资料后会打开新的浏览器--》可以不用账号…

python绘制热力图-数据处理-VOC数据类别标签分布及数量统计(-代码)

Python是一种功能强大的编程语言,它提供了许多库和工具,用于处理和可视化数据。在本文中,我们将介绍使用Python绘制热力图,并对VOC数据集中的类别标签进行分布及数量统计。 首先,我们需要导入所需的库。使用numpy库来…

新书速览|Spring Boot+Vue.js企业级管理系统实战

教你用Spring BootVue.js构建完整企业级管理系统项目 本书内容 《Spring BootVue.js企业级管理系统实战》以一个完整的全栈微服务项目为主线,详细阐述项目的技术架构、开发流程和技术要点,包括Vue.js前端技术、Spring Boot后端技术和Spring Cloud Alibab…

文件模块常用api

文件模块常用api 文件夹常用操作 文件夹操作 fs.mkdir fs.rmdir 需要是空目录 题目:递归删除目录* 串行/并行删除文件*

用二维码介绍产品详情,扫码查看图文并茂的宣传册

传统的产品宣传方式,往往以产品手册、宣传单等纸质物料为主,更新成本高昂,一旦修改内容,就必须重新印刷,而且不易携带和保存,影响宣传效果和客户体验。 为了避免上述问题,可以在草料上搭建产品…

soft212期末

文章目录 安卓填空题选择题 C# 安卓 Dalvik中得到Dx工具会把部分class文件转换成dex文件。 如果希望在XML布局文件中调用颜色资源,可以使用color调用 Android程序入口的Activity是在AndroidManifest.xml文件中注册的 Android中查看应用程序日志的工具是LogCat Dal…

Making Large Language Models Perform Better in Knowledge Graph Completion

Making Large Language Models Perform Better in Knowledge Graph Completion 基本信息 博客贡献人 鲁智深 作者 Yichi Zhang, Zhuo Chen, Wen Zhang, Huajun Chen 隶属于浙江大学计算机学院和软件学院 摘要 本文主要探讨了如何将有用的知识图谱结构信息融入大语言模型中…

哪种护眼灯对眼睛好?五款高品质考研台灯推荐

眼睛是我们感知世界的窗户,眼睛对光的敏感度非常高。长时间接触强光或不适宜的光线环境可能会对眼睛造成伤害。因此,选择一款适合自己的护眼台灯非常重要。护眼台灯能够模拟自然光的光谱,减少眼睛对不良光线的伤害。它具备调节光线亮度&#…

springCould中的Stream-从小白开始【12】

🥚今日鸡汤🥚 见过一些人,他们朝九晚五😭,有时也要加班,却能把生活过得很😎有趣。他们有自己的爱好,不怕独处。他们有自己的坚持,哪怕没人在乎。🤦‍♂️ 开心…

RISC-V Bytes: Caller and Callee Saved Registers

原文链接1:https://danielmangum.com/posts/risc-v-bytes-caller-callee-registers/ 原文链接2:https://zhuanlan.zhihu.com/p/77663680 //主要讲栈帧 原文链接3:https://www.jianshu.com/p/b666213cdd8a //主要讲栈帧 This is part of a new…

MySQL面试题 | 08.精选MySQL面试题

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

AArch64 memory management学习(二)

提示 该博客主要为个人学习,通过阅读官网手册整理而来(个人觉得阅读官网的英文文档非常有助于理解各个IP特性)。若有不对之处请参考参考文档,以官网文档为准。AArch64 memory management学习一共分为两章,这是第二章。…

实战 | 某电商平台类目SKU数获取与可视化展示

一、项目背景 最近又及年底,各类分析与规划报告纷至沓来,于是接到了公司平台类目商品增长方向的分析需求,其中需要结合外部电商平台做对比。我选择了国内某电商平台作为比较对象,通过获取最细层级前台类目下的SKU数以及结构占比&…

Java网络爬虫--HttpClient

目录标题 技术介绍有什么优点?怎么在项目中引入? 请求URLEntityUtils 类GET请求带参数的GET请求POST请求 总结 技术介绍 HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、功能丰富的、支持 HTTP 协议的客户端编程工具包。相…

八分钟了解一致性算法 -- Raft算法

前言 #### 分布式一致性在分布式环境中,一致性是指数据在多个副本之间是否能够保持一致的特性。 #### 分布式一致性算法比较常见的一致性算法包括Paxos算法,Raft算法,ZAB算法等• Paxos是Leslie Lamport提出的一种基于消息传递的分布式一致性算法。很多分布式一致性算法都由…

机器学习根据金标准标记数据-九五小庞

根据金标准标记数据是一种在机器学习和数据科学中常见的操作,主要用于评估分类模型的性能。其基本步骤如下: 收集数据:首先需要收集相关领域的原始数据,这些数据通常来自不同的来源和渠道。数据清洗和预处理:在这一步…

什么是Modbus协议?

Modbus协议是一种在工业自动化领域广泛应用的通信协议,它允许不同设备之间进行可靠的数据交换和控制。该协议最初由Modicon公司于1979年创建,旨在提供一种简单而有效的方法,使PLC(可编程逻辑控制器)和其他自动化设备能…