SpringCloud系列(十六)[分布式搜索引擎篇] - DSL 查询及相关性算分的学习 (部分)

在SpringCloud系列(十五)[分布式搜索引擎篇] - 结合实际应用场景学习并使用 RestClient 客户端 API这篇文章中我们已经对 RestClient 有了初步的了解, 并且已经将一些数据进行了存储, 但是这并不是我们学习 ElasticSearch 的目的, ElasticSearch 最擅长的还是对数据的搜索及分析, 因此本篇博客将对 ElasticSearch 的数据搜索功能进行演示.

DSL 查询及相关性算分的学习

  • ①DSL 对文档的查询
    • 1.1 查询所有
    • 1.2 全文检索查询
    • 1.3 精准查询
    • 1.4 地理坐标查询
    • 1.5 复合查询
      • 1.5.1 相关性算分
      • 1.5.2 语法
      • 1.5.3 布尔查询
  • ② 搜索结果的处理
  • ③ RestClient 查询文档
  • ④ 案例

①DSL 对文档的查询

常见查询类型:

  • 查询所有: 查询所有数据, 如 match_all;
  • 全文检索查询(full text): 主要利用分词器对用户的输入内容进行分词, 然后去倒排索引库中进行匹配查询, 如 match_query / multi_match_query;
  • 精确查询: 根据精确词条查询数据, 一般是用来查询日期 / 数值等类型的字段, 如 ids / range / term;
  • 地理查询(geo): 通常根据经纬度进行查询, 如 geo_distance / geo_bounding_box;
  • 复合查询(compound): 可以将上面的几种查询类型进行组合, 合并查询条件, 如 bool / function_score.

下面所有的查询语法基本如出一辙:

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

1.1 查询所有

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

因为是查询所有的数据, 所以没有查询条件, 查询类型为 match_all, 查询所有一般用不到, 使用场景也就仅限于测试的时候使用;

1.2 全文检索查询

在这里插入图片描述

全文检索查询的使用场景比较多, 我们生活中也经常使用, 如在淘宝上买鞋子买衣服等, 都是搜索某一个牌子的名称或者是物品的名称, 也就是说需要拿着词条去索引库中匹配, 因此参与搜索的字段也必须是可分词的 text 类型的字段; 通过这个例子可以得到全文检索查询的基本流程如下:

  • 对搜索的内容进行分词得到词条;
  • 根据词条去倒排索引库中匹配, 得到文档 id;
  • 根据文档 id 找到文档, 然后返回到页面中.

关于全文检索的查询主要包括 match / multi_match 两种, 一个是单字段查询, 一个是多字段查询, 多字段查询的意思就是任意一个字段符合条件就满足查询条件. 示例如下:

match:

GET /hotel/_search
{"query": {"match": {"all":"喜来登"}}
}

在这里插入图片描述

multi_match:

GET /hotel/_search
{"query": {"multi_match": {"query":"上海喜来登","fields": ["name","business"]}}
}

在这里插入图片描述
这里需要注意: multi_match 是根据多个字段进行查询, 参与的字段越多, 查询的效率就会越低, 因此一般使用 match 查询即可.

1.3 精准查询

精准查询的使用场景也是挺多的, 如查询某个日期范围内的数据, 或者是精确查询某一个地区的数据;

  • term: 根据词条精确值进行查询, 如查询北京地区的喜来登酒店, 筛选出的数据就只有北京地区的喜来登;
  • range: 根据值得范围进行查询, 如查询 500 元以上的酒店数据.

term 查询:

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

在这里插入图片描述
这里需要注意: 词条必须是精确的, 不能是多个词语组成的短语, 如果是北京上海, 是搜索不到结果的, 如下所示:
在这里插入图片描述

range 查询:

GET /hotel/_search
{"query": {"range": {"price": {"gte": "2000","lte":"5000"}}}
}

查询到的是 2000 元到 5000 元价格酒店;
在这里插入图片描述

1.4 地理坐标查询


出去游玩打车或者订酒店经常需要进行定位附近的快车及酒店, 地理坐标的查询就能实现这样的功能, 一种是根据地理坐标的经纬度进行查询, 如根据矩形范围进行查询:

GET /hotel/_search
{"query": {"geo_bounding_box": {"FIELD": {"top_left": { "lat": 31.35786,"lon": 121.59324},"bottom_right": {"lat": 31.35493,"lon": 121.59838}}}}
}

这里首先要确定左上角的点的坐标及右下角的点的坐标, 比较复杂, 但是有一种简单的方式, 可以根据距离进行查询, 查询到指定中心点小于某个距离值的所有数据; 也就是说以我现在的位置为中心, 距离我某个距离的圆弧内都符合条件, 如下所示:

GET /hotel/_search
{"query": {"geo_distance": {"distance": "5km","location": "39.94076,116.46099"}}
}

这里我查询的是以三里屯为中心点, 距离三里屯 5 km 所有的数据:
在这里插入图片描述

1.5 复合查询

  复合查询可以将其简单的查询组合起来, 实现更加复杂的搜索逻辑, 主要有以下两种:

  • function score: 算分函数查询, 通过控制文档相关性算分, 来控制文档的排名;
  • bool query: 布尔查询, 主要利用逻辑关系组合多个查询, 实现复杂的搜索逻辑.

1.5.1 相关性算分

  当我们使用 match 进行查询时, 文档结果会根据与搜索词条的关联度进行打分, 返回的结果也会按照分值的降序进行排序;   ElasticSearch 早起使用的打分算法是 TF-IDF 算法, 关于算法的公式如下:
在这里插入图片描述
但是 TF-IDF 算法有一个缺陷: 当词条的频率越来越高的时候, 文档的得分也会越来越高, 单个词条对文档的影响较大. 针对这样的问题, ElasticSearch 将打分算法改进为 BM25, BM25 会让单个词条的算分有一个上限, 曲线更加的平滑.公式如下:
在这里插入图片描述

1.5.2 语法

GET /hotel/_search
{"query": {"function_score": {"query": {"match": {"all": "北京"}},"functions": [{"filter": {"term": {"id": "1"}},"weight": 10}],"boost_mode": "multiply"}}
}

在这里插入图片描述


如图所示, 可以看得出分数值是降序的, 具体的语法说明如下:
在这里插入图片描述
具体流程如下:

  • 根据原始条件查询搜索文档, 并且计算相关性算分, 也就是 query score (原始算分);
  • 根据过滤条件过滤掉不符合条件的文档;
  • 基于算分函数运算得到函数得分 (function score);
  • 将原始算分 (query score) 和 函数算分 (function score) 基于运算模式做运算, 得到相关性算分的最终结果.

例如: 给北京的喜来登排名靠前, 如下:
原始查询, 得分为 2.6944847;
在这里插入图片描述
添加算分函数后, 得分为 4.6944847, 如下:
在这里插入图片描述

1.5.3 布尔查询

在这里插入图片描述

  布尔查询的使用场景还是挺多的, 如上图在淘宝上搜索 阿迪达斯, 我们可以进行选择筛选, 可以根据鞋码 / 性别等; 因为每一个字段都是不同的, 查询的条件或者方式也不一样, 因此肯定是多个不同的查询, 那么要组合这些查询就用到了布尔查询;
 总之, 布尔查询也是一个或者多个字句的组合, 每一个字句都是一个子查询, 组合方式有:

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

例子:

GET /hotel/_search
{"query": {"bool": {"must": [{"term": {"city": "北京"}}],"should": [{"term": {"brand":"希尔顿"}},{"term": {"brand":"喜来登"}}],"must_not": [{"range": {"price": {"lte": 1200} }}],"filter": [{"range": {"score": {"gte": 47}}},{"geo_distance": {"distance": "50km","location": {"lat": 39.91979,"lon": 116.41804}}}]}}
}

代码解读:
在这里插入图片描述


这里需要注意的是: 搜索过程中, 参与打字的字段越多, 查询的性能就会越差劲, 因此多条件查询时, 需要注意以下两点:

  • 搜索框的关键字搜索是全文检索查询, 使用 must 查询参与算分;
  • 其他的过滤条件采用 filter 查询, 不参与算分.

② 搜索结果的处理

③ RestClient 查询文档

④ 案例

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

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

相关文章

SQL中的where语句的使用

WHERE语句用于在SQL查询中过滤行,只返回满足特定条件的行。下面是一些常用的WHERE语句的例子,假设有三个表:users,products和orders。 1. 简单的WHERE子句 SELECT * FROM users WHERE age > 18; 这条语句将从users表中选择所…

物业管理微信小程序的设计与开发

1.物业管理微信小程序实现的功能 该微信小程序包含小程序端,后台管理端以及后端。 小程序端提供给业主使用,实现的功能模块有公告通知、访客预约、车位申请、装修申请、一键报修、报修单、意见反馈、缴费通知、一键求助、个人信息管理; 后台…

arcgis建筑物平均高度

主要用到相交和属性表的汇总功能。 路网 建筑物栋 相交结果 右键,bh列汇总 原始块有392,这里只有389,说明有的地块没有建筑,所以应该将表连接到原始街区上检查是否合理,以及随机验证一个结果是否正确。 连接结果&…

使用matlab里的集成树进行数据回归预测

当使用MATLAB时,您可以使用集成学习方法中的决策树来进行数据回归预测。决策树回归是一种基于树状结构的机器学习算法,它通过对训练数据进行分层次的决策来进行预测连续值的输出。 MATLAB提供了一个称为RegressionTree的集成树回归器。以下是一个使用MA…

无涯教程-Javascript - 变量声明

编程语言的最基本特征之一是它支持的数据类型,这些是可以用编程语言表示和操作的值的类型。 JavaScript允许您使用三种原始数据类型- 数字(Numbers)类型 - 如123、120.50等 字符串(Strings)类型 - 如"hello would"等 布尔值(Boolean)类…

中高级前端必须掌握的package.json最新最全指南

前言 package.json 是一个用于描述和配置项目的重要文件,其中包含了许多字段和选项,可以影响项目的构建、依赖管理、脚本执行等方面。了解这些字段可以帮助开发者更好地理解和控制项目的行为。 package.json对于大部分前端开发者来说,知道d…

spring boot maven 手动打入外部jar包依赖

有时候拿到第三方sdk是,以前都放在项目的某个目录下,然后通过项目路径去引入非常麻烦,最近找到了一个方法,可以手动将外部的jar包导入到本地的maven仓库中,这样你就可以像其他依赖一样正常使用了。 命令如下 mvn inst…

Spring6.0 源码部署

环境依赖 Git JDK17 Gradle(版本号需要和Spring源码中的版本一致) 源码下载 官网地址 源码配置修改 maven { url "https://maven.aliyun.com/repository/central" }gradle-wrapper.properties #distributionUrlhttps\://services.gradle…

无虚拟 DOM 版 Vue 进行到哪一步了?

前言 就在一年前的 Vue Conf 2022,尤雨溪向大家分享了一个非常令人期待的新模式:无虚拟 DOM 模式! 我看了回放之后非常兴奋,感觉这是个非常牛逼的新 feature,鉴于可能会有部分人还不知道或者还没听过什么是 Vue 无虚…

离线安装Elasticsearch7.15.1集群(使用内置jdk)

离线安装Elasticsearch7.15.1集群(使用内置jdk) 背景: 以192.168.50.210、192.168.50.211、192.168.50.212这三台机器为例,进行相关的配置 而我本地的jdk是1.8的,已经不符合要求了。但项目中没有那么高版本的jdk,也只想用1.8版本…

Excel-公式VLOOKUP 使用方法-小记

个人愚见 表示 MongoDB列中的任意一条数据 在 MySQL列 精确查找 和MongoDB列 中一模一样的数据,有的话返回MongoDB列数据,没有话返回#N/A 官方解释

【Web安全】小白怎么快速挖到第一个漏洞,src漏洞挖掘经验分享,绝对干货!

src漏洞挖掘经验分享 – 掌控安全以恒 一、公益src 公益src是一个白帽子提交随机发现的漏洞的品台,我们可以把我们随机发现或者是主动寻找到的漏洞在漏洞盒子进行提交。 在挖掘src的时候不能越红线,一般情况下遇到SQL注入 只获取数据库名字以证明漏洞的…

myAgv的slam算法学习以及动态避障下篇

引言 在之前的一篇文章中有提到购入了一台myAGV,以树莓派4B为控制核心的移动机器人。上篇文章中向大家介绍了myAGV如何实现建图、导航以及静态避障,但我们深知,这只是机器人自主导航能力的基础。在实际应用场景中,机器人需要面对复…

Flask入门:flask run运行入口函数

背景: 这两天在看后端代码覆盖率平台代码的时候,发现启动服务只需要执行flask run命令即可。但是找了半天都没有看到工程中Flask app实例对象是在哪里创建的。工程中定义了一个create_app()函数,可是没有看到调用它的地方。带着疑惑&#xf…

2023牛客暑期多校训练营1

2023牛客暑期多校训练营1 D-Chocolate 题意 ​ 二人博弈,每局给出一个 n m nm nm的巧克力,每次操作可以选择一个点 ( x , y ) (x,y) (x,y)然后拿走所有 ( i ≤ x & & j ≤ y ) (i \leq x \&\&j\leq y) (i≤x&&j≤y)的巧克力…

创建 CephFS 文件系统 MDS 接口(短暂的分别是为了更好的再见)

文章目录 一、Ceph 简介二、Ceph 特点三、创建 CephFS 文件系统 MDS 接口四、 创建 Ceph 块存储系统 RBD 接口五、 创建 Ceph 对象存储系统 RGW 接口1、对象存储概念2、创建 RGW 接口3、将生成的证书合并为pem OSD 故障模拟与恢复1、模拟 OSD 故障2、将坏掉的 osd 踢出集群 一、…

【react】react18的学习(十一)– 底层原理(一)之 diff 算法

diff算法、fiber链表 步骤:(追求多复用,快渲染) 首次渲染,缓存虚拟dom或fiber链表(17及以后); 组件更新,将新生成的虚拟dom与已有的真实dom的fiber链表对比&#xff1b…

【C语言+sqlite3 API接口】实现水果超市

实验内容: 假如我家开了个水果超市,有以下水果,想实现自动化管理,扫描二维码就能知道当前的水果状态,进货几天了, 好久需要再次进货,那些水果畅销,那些水果不畅销,那些水…

selenium查找svg元素

目录 如何为SVG元素编写XPath 使用local-name()的语法 需要记住的一点 将“and”与SVG元素一起使用 如何定位嵌套的SVG元素? XPath是一种用于定位XML文档中的web元素的语言,包括构成网页的HTML文档。在Selenium中&#xff0…

学习day48

事件的基本使用: 1.使用v-on:xxx或xxx绑定事件,其中xxx是事件名 2.事件的回调需要配置在methods对象中,最终会在vm上 3.methods中配置的函数,不要用箭头函数!否则this就不是vm了 4.methods中配置的函数&…