Elasticsearch 第四期:搜索和过滤

news2024/11/20 6:28:03

 序

        2024年4月,小组计算建设标签平台,使用ES等工具建了一个demo,由于领导变动关系,项目基本夭折。其实这两年也陆陆续续接触和使用过ES,两年前也看过ES的官网,当时刚毕业半年多,由于历史局限性导致根本看不懂。因此趁着这个机会,在5月~6月期间,基本看了一遍ES的官方文档,先从整体梳理了ES的基础知识,共四期。

Elasticsearch 第一期:ES的前世今生-CSDN博客

Elasticsearch 第二期:基础的基础概念-CSDN博客

Elasticsearch 第三期:倒排索引,分析,映射-CSDN博客

Elasticsearch 第四期:搜索和过滤-CSDN博客

前言

这篇文章的内容是根据ES官方关于搜索的章节整理的。但目录结构做了重新整理。分别从相关性,搜索,过滤进行了介绍。具体如下:

相关性

ES搜索的本质其实是把文档根据搜索内容进行相关性排序。所以在介绍ES搜索之前,先简单介绍一下ES相关性。关于相关性的理论知识具体可以参考官网。当然相关性得分只是搜索排序的一种,还有特殊场景的排序方法,如地理位置邻近算法。

众所周知,查询语句会为每个文档生成一个评分: _score 。通常我们说的 相关性 是用来计算全文本字段的值相对于全文本检索词相似程度的算法。

Elasticsearch 的相似度算法被定义为:TF/IDF(检索词频率/反向文档频率) 。

检索词频率:检索词在该字段出现的频率。出现频率越高,相关性也越高。 字段中出现过 5 次要比只出现过 1 次的相关性高。

反向文档频率:每个检索词在全部索引中出现的频率。频率越高,计算相关时相关性的权重越低。检索词出现在多数文档中会比出现在少数文档中的权重更低。

字段长度准则:该字段的长度是多少。长度越长,相关性越低。 检索词出现在一个短的 title 要比同样的词出现在一个长的 content 字段权重更大。

检索词频率

title:dog love person

很明显,dog在第二个文档中出现了2次,因此文档2相关性更强

title:dog love dog

反向文档频率

title:dog love person

当使用dog和person来搜索时,虽然文档2被命中了2次,但person在全部文档中出现了频率比dog少,因此计算person相关性权重的时候会更大

title:dog love dog

字段长度准则

title:dog love person

搜索love时可以名字两个文档,但文档2中的字段相对较短,其得分更高。

title:dog love dog

搜索

搜索的过程就是在全文字段中搜索到最相关的文档。搜索两个最重要的方面是:

相关性(Relevance)它是评价查询与其结果间的相关程度,并根据这种相关程度对结果排名的一种能力

分析(Analysis)它是将搜索关键字和文档内容转换为有区别的、规范化的 词项(token) 的一个过程。 目的是为了(a)创建倒排索引 (b)查询倒排索引。

在Elasticsearch 7.x中,它提供了三种主要的文档检索方式:全文搜索、词项搜索和复合搜索。

全文搜索

简单查询

全文搜索是Elasticsearch最常见的搜索方式,主要用于搜索文本字段。用户只需要提供关键词,Elasticsearch就能自动地在索引中找到包含这些关键词的文档。在全文搜索中,Elasticsearch使用了一种名为“倒排索引”的数据结构,可以非常高效地执行搜索操作。

全文搜索主要通过match查询实现。match查询会对用户给出的关键词进行解析,然后进行分词处理。只要查询语句中的任意一个词项在文档中被匹配,该文档就会被检索到。

全文搜索经常用的命令包括:

match

匹配查询,用于单字段搜索

multi_match

在多个字段上反复执行相同查询

match
{
    "query": {
        "match": {
          "title":{
            "query":"BROWN DOG!",
            "operator":and  //所有词项都要匹配时
            "minimum_should_match":"50%"
          }
        }
    }
}

上面是match搜索的一个用例。搜索内容可以是一个词项,也可以是多个词项。若是多个词项场景,这些词语会被解析成单个词,然后在倒序索引中进行精确(term)查找。默认是这些词之间的关系是or,即满足文档中包含其中一个词就会被找到。

match有两个参数来控制搜索操作和返回结果。

  1. operator:需要搜索的关键词必须全部出现

  2. minimum_should_match :最小匹配参数

有时候需要搜索的关键词必须全部出现,可以使用参数 operator ,设置为 and 。

若文档数量超多,可以对相关性设定阈值,而我们只希望返回相关性高的文档, 可以使用 minimum_should_match 最小匹配参数。该参数的值设置有两种方式,指定必须匹配的词项数用来表示一个文档是否相关。具体数值可以参考:

1. 设置为某个具体数字来制定匹配的词项数量

2. 将其设置为一个百分数:百分数可以设置为正值(75%)也可以设置为负值(-25%)。计算必须文档中要匹配的词项数量

75%

-25%

4个搜索关键词

4*75%=3

4-4*25%=3

4个搜索关键词

5*75%=3(向下取整)

5-5*25%=4(向下取整)

multi_match

multi_match 则是match在多字段查到的一个简便方式。可以在能在多个字段上反复执行相同查询。

{
 "query":{
    "multi_match": {
      "query": "BROWN DOG",
      "fields":["title","body"]
    }
  }

短语近似匹配

简单查询中match 或者multi_match查询可以获得包含查询词条的文档。但搜索查询时没有考虑词语之间的关系(如:位置关系,词性关系),甚至都不能确定匹配到的内容是否来自同一个字段。

1. Java是一门很好的语言,很多工程师都喜欢使用.

2. Java工程师都很优秀.

用 match 搜索 Java 工程师 上面的两个文档都会得到匹配,但很明显,其实文档2是我们需要的可能性更大。

当使用分析器将文档内容和搜索关键词进行分词之后,理解分词之间的关系是一个复杂的难题。我们也无法通过更换查询方式或者底层存储结构来解决分词问题。但我们至少可以通过出现在彼此附近或者相邻的分词来判断分词之间的相关性

这就是短语匹配或者近似匹配的所属领域。对于短语匹配,match_phrase也是经常用的搜索方式之一。例如下面的例子:

{
    "query": {
        "match_phrase": {
            "title": {
                 "query":"quick brown fox",
                  "slop":2
            }
        }
    }
}

对于与matchmulti_match查询不同的是,除了将查询关键字解析成一个词项,然后在倒排索引中进行搜索查询外,match_phrase还会比较快搜索词项之间的位置,最终结果只会保留 位置 与搜索词项相同的文档。 

精确短语匹配 或许是过于严格了。也许我们想要包含 “Java 高级 工程师” 的文档也能够匹配 “Java 工程师,” ,可以通过使用 slop 参数将灵活度引入短语匹配中。

slop 参数告诉 match_phrase 查询词条相隔多远时仍然能将文档视为匹配 。 相隔多远的意思是为了让查询和文档匹配你需要移动词条多少次。

词项搜索

词项搜索与全文搜索不同,查询不会对输入进行分词处理,而是将输入作为一个整体进行搜索。词项搜索方式本文整理了精确查找--term和部分匹配搜索。

精确查找和范围查找

我们首先来看最为常用的 term 查询和range查询。正如上面所说,词项搜索不会对输入进行分词处理,而是将输入作为一个整体,在倒排索引中查找准确的词项。term和range一般适用于用来处理数字(numbers)、布尔值(Booleans)、日期(dates)等。

term

查询某个字段等于搜索词的文档

"term":{ "address":"香港"}

查询地址等于'香港'的文档 

terms

查询某个字段里包含多个关键词的文档

terms":{   "address":["香港","北京"]}

查询地址等于"香港"或"北京"的

range

实现范围查询

"range": {             "age": {                 "from": 18,                 "to": 28,                 "include_lower": true,                 "include_upper": true             }         }

部分匹配

可以发现,以上提出的搜索查询方式都是针对倒排索引整个词的操作。即根据词项在倒排索引中进行匹配查找。也就是说只能查找倒排索引中存在的词,最小的单元为单个词。

但如果想匹配倒排索引中存在词项一部分, 如搜索Java的时候,也希望把JavaScript查出来。这个时候怎么办呢?这个便是接下来要解释的内容--部分匹配。

 部分匹配 允许用户指定查找词的一部分并找出所有包含这部分片段的结果。默认状态下, 部分匹配默认不做相关度评分计算,它只是将所有匹配的文档返回。部分匹配有三种方式,这三种方式也不会对搜索词进行分词:

  1. 前缀查询

  2. 通配符查询

  3. 正则表达式查询

prefix

不会在搜索之前分析查询字符串,它假定传入前缀就正是要查找的前缀。

"prefix": {"postcode": "W1"}

wildcard

使用标准的 shell 通配符查询: ? 匹配任意字符, * 匹配 0 或多个字符

"wildcard": {

            "postcode": "W?F*HW" ,

            "postcode": "W[0-9].+" }

regexp

正则式

{ "regexp": { "title": "br.*" }}

复合搜索

复合搜索是Elasticsearch中最强大的搜索方式之一,它允许用户组合多种查询条件,实现复杂的搜索需求。在Elasticsearch中,复合搜索主要通过bool查询实现。bool查询可以利用逻辑关系(如andornot)组合多个其他的查询,从而构建出复杂的查询条件。

除了bool查询,Elasticsearch还提供了其他一些复合查询方式,如filter查询、join查询等。这些查询方式可以进一步扩展复合搜索的能力,满足更复杂的搜索需求。

bool 过滤器一般由以下三部分组成:

{
   "bool" : {
      "must" :     [],
      "should" :   [],
      "must_not" : []
   }
}

must

 必须 匹配这些条件才能被包含进来。

must_not

 必须不 匹配这些条件才能被包含进来。

should

如果满足这些语句中的任意语句,将增加 _score ,否则,无任何影响。它们主要用于修正每个文档的相关性得分。

过滤

过滤和搜索不同,过滤不需要谈论相关性或得分。过滤得到的结果: 非是即否。它简单的对文档包括或排除处理。fliter可以单独使用,也可以结合bool复合搜索来实现功能更强大的操作。

Elasticsearch 会在运行过滤查询时执行多个操作,如执行下面语句时,Elasticsearch行为包含4步:

{ 
 "filter":{
    "term":{"age": [3,63]},
     "term":{"price": 30}
  }
}
  1. 查找匹配文档.

term 查询在倒排索引中查找,获取包含该 term 的所有文档。

2. 创建 bitset.

过滤器会创建一个 bitset (一个包含 0 和 1 的数组),它描述了哪个文档会包含该 term 。匹配文档的标志位是 1 。如有四个文档,执行完"term":{"age": [3,63]}语句之后,会得到一个bitset 的值: [1,0,0,0] 。

3. 迭代 bitset(s)

一旦为每个查询生成了 bitsets ,Elasticsearch 就会循环迭代 bitsets 从而找到满足所有过滤条件的匹配文档的集合。一般来说先迭代稀疏的 bitset (因为它可以排除掉大量的文档)。

4. 增量使用计数.

Elasticsearch 能够缓存过滤查询从而获取更快的访问,而且过滤查询也不会计算相关行。因此,filter速度要快于query。

总结

本文先介绍了相关性的知识,然后从全文搜 索,词项搜索,复合搜索三方面来介绍了ES搜索的常见场景和操作。最后介绍了与搜索对应的过滤操作。

本文的内容意在梳理ES搜索操作,并未细究背后的原理,如相关性算法等。后续如果有需要会补充。当然,在实际应用中,要综合考虑具体场景来选择相应的搜索方式。

参考文档

https://www.cnblogs.com/qdhxhz/p/11493677.html

Elasticsearch 7.x文档检索的三大策略:全文搜索、词项搜索与复合搜索-百度开发者中心

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

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

相关文章

耗材分类功能解析:智慧校园的必备利器

在智慧校园的资产管理架构中,耗材分类功能是确保日常运营物资有效管理的关键组成部分,它致力于提高耗材使用的效率和经济性。此功能通过智能化、精细化的管理手段,对校园内各种易耗品进行科学分类与跟踪。 耗材分类功能首先建立在对校园日常运…

Prometheus 监控服务器

Prometheus概述 组件化设置:nginx ,ceph , Prometheus 部署Prometheus服务器 配置时间 安装Prometheus服务器 访问web页面:http://192.168.88.5:9090/ 添加被监控端 监控方式: 拉取:pull。监控端联系被监控端,采集数…

Android sdk 安装已经环境配置

🍎个人博客:个人主页 🏆个人专栏:Android ⛳️ 功不唐捐,玉汝于成 目录 正文 一、下载 二、安装 三、环境配置 我的其他博客 正文 一、下载 1、大家可去官网下载 因为需要魔法 所以就不展示了 2、去下面这…

MySQL期末答辩—仓库管理系统

仓库管理系统:仓库管理系统是一种基于互联网对实际仓库的管理平台,旨在提供一个方便、快捷、安全的存取货物和查询商品信息平台。该系统通过在线用户登录查询,可以线上操作线下具体出/入库操作、查询仓库商品信息、提高仓库运作效率&#xff…

SPI 通信 协议

介绍: SPI(Serial Peripheral Interface)是由摩托罗拉公司开发的一种通用数据总线 四根通信线: SCK(Serial Clock) 时钟线MOSI(Master Output Slave Input&…

粗糙度轮廓仪功能简介:一体型轮廓仪功能亮点

在精密制造和质量控制领域,表面粗糙度和轮廓的精确测量是至关重要的。一体型轮廓仪为这一需求提供了全面的解决方案。它采用超高精度纳米衍射光学测量系统、超高直线度研磨级摩擦导轨、高性能直流伺服驱动系统、高性能计算机控制系统技术,为用户提供了一…

90后懒人带娃的福音,小学生古诗词的神器——ChatMoney全能知识库AI软件

本文由 ChatMoney团队出品 因为工作需要,浅尝辄止般的用了一下ChatMoney全能知识库AI软件。一些长期积存的问题迎刃而解,但这只是一款企业级大模型功能的冰山一角。让自己尤为惊奇的是里面涵盖的各类资料系统,居然能助力宝妈宝爸带娃脱困。只…

AIGC对设计行业的影响与启发:AIGC设计能替代真正的设计师吗?

随着科技的飞速发展,人工智能生成内容(AIGC)技术在设计行业的应用日益广泛,引发了广泛的讨论和关注。AIGC以其高效、多样化的生成能力,为设计行业带来了前所未有的变革。然而,关于AIGC是否能替代真正的设计…

Rustdesk如何编译代码实现安装后不会显示主界面,不会在右下角出现托盘图标,作为后台服务运行

环境: Rustdesk1.1.9 问题描述: Rustdesk如何编译代码实现安装后不会显示主界面,不会在右下角出现托盘图标,作为后台服务运行 解决方案: 可以自定义进程名称和图标,不会显示主界面,不会在…

uboo对内存操作读写命令的基本使用

内存操作命令 直接对DRAM进行读写的操作,uboot常用的内存操作命令有md,nm,mm,mw,cp和cmp. md命令: 显示内存值 # md md - memory display Usage: md [.b, .w, .l, .q] address [# of objects] b:1个字节 byte w:2个字节 world l:4个字节 long of objects 以word 为单位的1…

搭建个人博客及错误记录

搭建个人博客及错误记录 文章目录 搭建个人博客及错误记录需要用到的网址2.推荐两个参考教学视频3.发布一篇博客个人主题配置的提醒localhost拒绝连接问题解决办法ssh -T gitgithub.com失败问题解决Deployer not found:git解决 可以根据目录解决遇到的相同问题 需要用到的网址 …

昇思25天学习打卡营第3天|yulang

今天主要学习03-张量Tensor,主要包含了处理创建张量、张量的属性、张量索引和张量运算,稀疏张量,有点看不太懂,感觉要开始入门到放弃了?张量在构建和训练深度学习模型中的实际应用,如卷积神经网络。 张量&a…

Vue入门-如何创建一个Vue实例

创建一个一个Vue实例总共分为四步: 1.创建一个容器 2.引包:地址栏搜索v2.cn.vuejs.org这是vue2的官网地址,把2去掉就是vue3的官网地址,我们的包分为开发版本和生产版本,开发版本包含完整的警告和调试模式生产版本删除…

【Python机器学习】算法链与管道——用预处理进行参数选择的注意项

对于许多机器学习算法,提供的特定数据表示非常重要。比如,首先对数据进行缩放,然后手动合并特征,再利用无监督机器学习来学习特征。因此,大多数机器学习应用不仅需要应用多个算法,而且还需要将许多不同的处…

BIOS中的设置虽然不少,但其实大部分时候只需进行一些简单的调整

序言 浏览BIOS可能会让人感到不知所措,因为要考虑的设置太多了。但是,你应该在BIOS中进行一些简单的调整,以提高系统的性能和稳定性。我们将向你展示其中的一些调整,并解释你可能想要使用它们的时间和原因。 用密码保护你的BIOS 虽然我们很小心地对用户帐户进行密码保护…

打卡第一天

今天是参加算法训练营的第一天,希望我能把这个训练营坚持下来,希望我的算法编程题的能力有所提升,不再面试挂了,面试总是挂编程题,记录我leetcode刷题数量: 希望我通过这个训练营能够实现两份工作的无缝衔接…

【Spring Boot】Java 持久层 API:JPA

Java 持久层 API:JPA 1.Spring Data1.1 主要模块1.2 社区模块 2.JPA3.使用 JPA3.1 添加 JPA 和 MySQL 数据库的依赖3.2 配置数据库连接信息 4.了解 JPA 注解和属性4.1 常用注解4.2 映射关系的注解4.3 映射关系的属性 5.用 JPA 构建实体数据表 1.Spring Data Spring…

【Linux】多线程(一万六千字)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 文章目录 前言 线程的概念 线程的理解(Linux系统为例) 在Linux系统里如何保证让正文部分的代码可以并发的去跑呢? 为什么要有多进程呢? 为…

统计信号处理基础 习题解答11-13

题目 如果是一个2x1的随机矢量,具有PDF 证明的PDF是一个随机变量。提可以因式分解成,其中是一个在4.5节描述的白化变换。 解答 首先: 因此,存在: 也就是是Hermitian矩阵。详细的性质可以参考: https://z…

linux系统中的各种命令的解释和帮助(含内部命令、外部命令)

目录 一、说明 二、命令详解 1、帮助命令的种类 (1)help用法 (2)--help用法 2、如何区别linux内部命令和外部命令 三、help和—help 四、man 命令 1、概述 2、语法和命令格式 (1)man命令的格式&…