Elasticsearch检索分类深入详解—基础篇

2023-11-05

题记

Elasticsearch中当我们设置Mapping(分词器、字段类型)完毕后,就可以按照设定的方式导入数据。

有了数据后,我们就需要对数据进行检索操作。根据实际开发需要,往往我们需要支持包含但不限于以下类型的检索:
1)精确匹配,类似mysql中的 “=”操作;
2)模糊匹配,类似mysql中的”like %关键词% “查询操作;
3)前缀匹配;
4)通配符匹配;
5)正则表达式匹配;
6)跨索引匹配;
7)提升精读匹配。

细数一下,我们的痛点在于:
1)ES究竟支持哪些检索操作?
2)如何实现ES精确值检索、指定索引检索、全文检索?

这些就是本文着重参考ES最新官方文档,针对ES5.X版本探讨的内容。
0、检索概览

检索子句的行为取决于查询应用于过滤(filter)上下文还是查询/分析(query)上下文。

过滤上下文——对应于结构化检索

1)核心回答的问题是:“这个文档是否符合这个查询条款?”

2)答案是简单的是或否,不计算分数。

3)过滤器上下文主要用于过滤结构化数据。类似于Mysql中判定某个字段是否存在:

例如:
a. 时间戳字段:是否属于2015年或2016年?
b. 状态字段:是否设置为“已发布”?

经常使用的过滤器将被Elasticsearch**自动缓存,以加快性能**。

分析上下文——对应于全文检索
1)核心回答了“本文档与此查询子句是否匹配?”的问题。

2)除了决定文档是否匹配之外,查询子句还会计算一个_score,表示文档与其他文档的匹配程度。

综合应用场景如下:

GET /_search
{  "query": {  "bool": {  "must": [
  { "match": { "title": "Search" }},
  { "match": { "content": "Elasticsearch" }}
  ],  "filter": [
  { "term": { "status": "published" }},
  { "range": { "publish_date": { "gte": "2015-01-01" }}}
  ]
  }
  }
}

以上检索,title中包含”Search”并且content中包含 “Elasticsearch”,status中精确匹配”published”,并且publish_date 大于“2015-01-01”的全部信息。

以下,以“脑图”的形式直观展示检索分类。
这里写图片描述
其中,3-7根据我随着我开发深入再做更新。

以下内容的原文需要参考ES官方文档(随着版本变化,后续会有更新)
1、结构化检索

针对字段类型: 日期、时间、数字类型,以及精确的文本匹配。
结构化检索特点:
* 1)结构化查询,我们得到的结果 总是 非是即否,要么存于集合之中,要么存在集合之外。
* 2)结构化查询不关心文件的相关度或评分;它简单的对文档包括或排除处理。
1.1 精确值查找
1.1.1 单个精确值查找(term query)

term 查询会查找我们指定的精确值。term 查询是简单的,它接受一个字段名以及我们希望查找的数值。

想要类似mysql中如下sql语句的查询操作:

SELECT document FROM products WHERE price = 20;
DSL写法:

GET /my_store/products/_search
{
  "query" : {
  "term" : {
  "price" : 20
  }
  }
}

当进行精确值查找时, 我们会使用过滤器(filters)。过滤器很重要,因为它们执行速度非常快,不会计算相关度(直接跳过了整个评分阶段)而且很容易被缓存。如下: 使用 constant_score 查询以非评分模式来执行 term 查询并以一作为统一评分。

GET /my_store/products/_search
{
  "query" : {
  "constant_score" : {
  "filter" : {
  "term" : {
  "price" : 20
  }
  }
  }
  }
}

注意:5.xES中,对于字符串类型,要进行精确值匹配。需要讲类型设置为text和keyword两种类型。mapping设置如下:

POST testindex/testtype/_mapping
{
   "testtype ":{
  "properties":{
  "title":{
  "type":"text",
  "analyzer":"ik_max_word",
  "search_analyzer":"ik_max_word",
  "fields":{
  "keyword":{
  "type":"keyword"
  }
  }
  }
}
}

精确值java api jest使用方法:
searchSourceBuilder.query(QueryBuilders.termQuery(“text.keyword”, “来自新华社的报道”));
1.1.2 布尔过滤器

一个 bool 过滤器由三部分组成:

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

must ——所有的语句都 必须(must) 匹配,与 AND 等价。
must_not ——所有的语句都 不能(must not) 匹配,与 NOT 等价。
should ——至少有一个语句要匹配,与 OR 等价。
filter——必须匹配,运行在非评分&过滤模式。
就这么简单! 当我们需要多个过滤器时,只须将它们置入 bool 过滤器的不同部分即可。

举例:

GET /my_store/products/_search
{
  "query" : {
  "filtered" : {
  "filter" : {
  "bool" : {
  "should" : [
  { "term" : {"price" : 20}},

  { "term" : {"productID" : "XHDK-A-1293-#fJ3"}}

  ],
  "must_not" : {
  "term" : {"price" : 30}

  }
  }
  }
  }
  }
}

 

1.1.3 多个值精确查找(terms query)

{
  "terms" : {
  "price" : [20, 30]
  }
}

 

如上,terms是包含的意思,包含20或者包含30。
如下实现严格意义的精确值检索, tag_count代表必须匹配的次数为1。

GET /my_index/my_type/_search
{
  "query": {
  "constant_score" : {
  "filter" : {
  "bool" : {
  "must" : [
  { "term" : { "tags" : "search" } },
  { "term" : { "tag_count" : 1 } }
  ]
  }
  }
  }
  }
}

 

1.2 范围检索(range query)

range 查询可同时提供包含(inclusive)和不包含(exclusive)这两种范围表达式,可供组合的选项如下:

gt: > 大于(greater than)
lt: < 小于(less than)
gte: >= 大于或等于(greater than or equal to)
lte: <= 小于或等于(less than or equal to)

类似Mysql中的范围查询:

SELECT document
FROM   products
WHERE  price BETWEEN 20 AND 40

ES中对应的DSL如下:

GET /my_store/products/_search
{
  "query" : {
  "constant_score" : {
  "filter" : {
  "range" : {
  "price" : {
  "gte" : 20,
  "lt" : 40
  }
  }
  }
  }
  }
}

1.3 存在与否检索(exist query)

mysql中,有如下sql:
SELECT tags FROM posts WHERE tags IS NOT NULL;

ES中,exist查询某个字段是否存在:

GET /my_index/posts/_search
{
    "query" : {
        "constant_score" : {
            "filter" : {
                "exists" : { "field" : "tags" }
            }
        }
    }
}

 

若想要exist查询能匹配null类型,需要设置mapping:

"user": {
  "type": "keyword",
  "null_value": "_null_"
  }

 

missing查询在5.x版本已经不存在,改成如下的判定形式:

GET /_search
{
    "query": {
        "bool": {
            "must_not": {
                "exists": {
                    "field": "user"
                }
            }
        }
    }
}

 

1.4 前缀检索( Prefix Query )

匹配包含 not analyzed 的前缀字符:

GET /_search
{ "query": {
  "prefix" : { "user" : "ki" }
  }
}

1.5 通配符检索( wildcard query)

匹配具有匹配通配符表达式( (not analyzed )的字段的文档。 支持的通配符:
1)*,它匹配任何字符序列(包括空字符序列);
2)?,它匹配任何单个字符。
请注意,此查询可能很慢,因为它需要遍历多个术语。
为了防止非常慢的通配符查询,通配符不能以任何一个通配符*或?开头。

举例:

GET /_search
{
    "query": {
        "wildcard" : { "user" : "ki*y" }
    }
}

1.6 正则表达式检索(regexp query)

正则表达式查询允许您使用正则表达式术语查询。
举例如下:

GET /_search
{
  "query": {
  "regexp":{
  "name.first": "s.*y"
  }
  }
}

注意: *的匹配会非常慢,你需要使用一个长的前缀,
通常类似.*?+通配符查询的正则检索性能会非常低。

1.7 模糊检索(fuzzy query)

模糊查询查找在模糊度中指定的最大编辑距离内的所有可能的匹配项,然后检查术语字典,以找出在索引中实际存在待检索的关键词。
举例如下:

GET /_search
{
  "query": {
  "fuzzy" : { "user" : "ki" }
  }
}

1.8 类型检索(type query)

举例:

GET /my_index/_search
{
  "query": {
  "type" : {
  "value" : "xext"
  }
  }
}

已验证,检索索引my_index中,type为xext的全部信息。
1.9 Ids检索(ids query)

返回指定id的全部信息。

GET /my_index/_search
{
  "query": {
  "ids" : {
  "type" : "xext",
  "values" : ["2", "4", "100"]
  }
  }
}

2、全文检索

高级全文查询通常用于在全文本字段(如电子邮件正文)上运行全文查询。他们了解如何对被查询的字段进行分析,并在执行前将每个字段的分析器(或search_analyzer)应用于查询字符串。
2.1 匹配检索(match query)

匹配查询接受文本/数字/日期类型,分析它们,并构造查询。
1)匹配查询的类型为boolean。 这意味着分析所提供的文本,并且分析过程从提供的文本构造一个布尔查询,
可以将运算符标志设置为或以控制布尔子句(默认为或);
2)文本分析取决于mapping中设定的analyzer(中文分词,我们默认选择ik分词器);
3) fuzziness——模糊性允许基于被查询的字段的类型进行模糊匹配;
4)”operator”: “and”——匹配与操作(默认或操作);
5) “minimum_should_match”: “75%”——这让我们可以指定必须匹配的词项数用来表示一个文档是否相关。
举例:

GET /_search
{
    "query": {
        "match" : {
            "message" : {
                "query" : "this is a test",
                "operator" : "and"
            }
        }
    }
}

2.2 匹配解析检索 match_phrase query

match_phrase查询分析文本,并从分析文本中创建短语查询。
类似 match 查询, match_phrase 查询首先将查询字符串解析成一个词项列表,然后对这些词项进行搜索,但只保留那些包含 全部 搜索词项,且 位置 与搜索词项相同的文档。
举例如下:对于 quick fox 的短语搜索可能不会匹配到任何文档,因为没有文档包含的 quick 词之后紧跟着 fox 。

GET /my_index/my_type/_search
{
  "query": {
  "match_phrase": {
  "title": "quick brown fox"
  }
  }
}

2.3 匹配解析前缀检索(match_phrase_prefix)

用户已经渐渐习惯在输完查询内容之前,就能为他们展现搜索结果,这就是所谓的 即时搜索(instant search) 或 输入即搜索(search-as-you-type) 。
不仅用户能在更短的时间内得到搜索结果,我们也能引导用户搜索索引中真实存在的结果。
例如,如果用户输入 johnnie walker bl ,我们希望在它们完成输入搜索条件前就能得到:
Johnnie Walker Black Label 和 Johnnie Walker Blue Label 。

match_phrase_prefix与match_phrase相同,除了它允许文本中最后一个术语的前缀匹配。
举例:

GET / _search
{
    “query”:{
        “match_phrase_prefix”:{
            “message”:“quick brown f”
        }
    }
}

2.4 多字段匹配检索( multi_match query)

multi_match 查询为能在多个字段上反复执行相同查询提供了一种便捷方式。
默认情况下,查询的类型是 best_fields, 这表示它会为每个字段生成一个 match 查询。
举例1:”fields”: “*_title”
——任何与模糊模式正则匹配的字段都会被包括在搜索条件中, 例如可以左侧的方式同时匹配 book_title 、 chapter_title 和 section_title (书名、章名、节名)这三个字段。
举例2: “fields”: [ “*_title”, “chapter_title^2” ]
——可以使用 ^ 字符语法为单个字段提升权重,在字段名称的末尾添加 ^boost , 其中 boost 是一个浮点数。
举例3:”fields”: [ “first_name”, “last_name” ],
“operator”: “and”
——两个字段必须都包含。

GET /_search
{
  "query": {
  "multi_match" : {
  "query": "this is a test",
  "fields": [ "subject", "message" ]
  }
  }
}

 

2.5 字符串检索(query_string)

一个使用查询解析器解析其内容的查询。
query_string查询提供了以简明的简写语法执行多匹配查询 multi_match queries ,布尔查询 bool queries ,提升得分 boosting ,模糊匹配 fuzzy matching ,通配符 wildcards ,正则表达式 regexp 和范围查询 range queries 的方式。
支持参数达10几种。

GET /_search
{
  "query": {
  "query_string" : {
  "default_field" : "content",
  "query" : "this AND that OR thus"
  }
  }
}

2.6 简化字符串检索(simple_query_string)

一个使用SimpleQueryParser解析其上下文的查询。 与常规query_string查询不同,simple_query_string查询永远不会抛出异常,并丢弃查询的无效部分。
举例:

GET /_search
{
    "query": {
        "simple_query_string" : {
            "fields" : ["content"],
            "query" : "foo bar -baz"
        }
    }
}

支持的操作如下:
1)+表示AND操作
2)| 表示OR操作
3)- 否定操作
4)*在术语结束时表示前缀查询
5)(和)表示优先
3 小结

有的博友可能会问,这和ES官网API有什么区别。
仔细对比你会发现,ES的中文文档是根据2.X版本翻译的,ES的英文文档一个版本是没有更新到5.X版本,另一个已经更新。
当我们进行相关检索查询的时候,文档结构一篇一篇翻查,很零散、很不系统。
本文内容综合了几个官网文档,结合自己的实战经验进行了总结,是对我开发和认知的梳理。
---------------------
作者:铭毅天下
来源:CSDN
原文:https://blog.csdn.net/laoyang360/article/details/77623013
版权声明:本文为博主原创文章,转载请附上博文链接!

 

https://blog.csdn.net/laoyang360/article/details/77623013

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Elasticsearch检索分类深入详解—基础篇 的相关文章

  • 你真的知道运维是干嘛的吗?

    文章目录 前言 运维基本能力 运维岗位分类 按照职责划分 按照服务类型划分 按照运维模式划分 按照工作模式划分 按照管理层级划分 按照技术方向划分 按照服务对象划分 按照工作内容划分 按照服务形式划分 按照业务类型划分 按照技术栈划分 按照
  • python selenium页面跳转_Python爬虫之Selenium多窗口切换的实现

    前言 在页面操作过程中有时候点击某个链接会弹出新的窗口 但由于Selenium的所有操作都是在第一个打开的页面进行的 这时就需要主机切换到新打开的窗口上进行操作 WebDriver提供了switch to window 方法 可以实现在不同

随机推荐

  • 如何去实现机械灵巧手玩魔方和弹钢琴_工业级灵巧手与智慧抓取技术

    随着工业机器人的发展以及机器人应用领域的不断扩展 作为末端执行器的机器人夹爪的应用边界也在不断扩展 在工业自动化领域被广泛使用的气动手爪 正在被可精确控制 可数字化管理的新一代末端执行器所替代 编辑 符号整理 Cloud Sunny 机器人
  • “找不到或无法加载主类”该问题出现的一个可能原因

    今天按照教材上的程序 编译运行时 程序编译没有问题 但是运行时 出现 找不到或无法加载主类 的提示 遂网上四处找答案 说什么 1 拼写错误 2 环境变量配置时classpath和path前面未加 下面是我的程序 package myFram
  • vue——echarts柱状图横轴文字太多放不下【处理办法】

    1 如果单纯是文字太多 且中间无法分割开的话 可以采用两种方式 文字倾斜展示 效果 在options配置中的xAxis中配置如下代码 axisLabel interval 0 rotate 40 文字竖直显示 效果 在options配置中的
  • 终于搞定了SHADOWMAP,

    5 5pcf
  • 关于 ChatGPT 必看论文推荐【附论文链接】

    关于 ChatGPT 必看论文推荐 2022年11月 OpenAI推出人工智能聊天原型 ChatGPT 再次赚足眼球 为AI界引发了类似AIGC让艺术家失业的大讨论 ChatGPT 是一种专注于对话生成的语言模型 它能够根据用户的文本输入
  • 情人节用Python画玫瑰花

    用Python turtle 绘制的玫瑰花 效果图 import turtle import time turtle penup turtle setup 1100 1000 turtle hideturtle turtle speed 1
  • tensorRT模型推理时动态shape

    动态shape 所谓动态shape就是编译时指定可动态的范围 L H 推理时可以允许L lt shape lt H 在全卷积网络中我们通常就是有这个诉求的 推理时的shape是可以动态改变的 不一定要限制死 这个动态shape不一定只宽高
  • 有序数组中找到num

    问题 在有序数组中找到num 分析 直接遍历查找均可 但既然是有序数组 则充分利用此条件 采用效率更高的二分法 代码 创建一个随机的有序数组 void Random array int array int num for int i 0 i
  • Fisco技术文档总结3---使用工具

    前言 本文介绍fisco技术文档中的使用工具模块 该模块中将重点介绍开发部署工具和控制台 这都是开发过程中十分常用的 其他的工具是封装的工具 方便开发者使用这里接受一下方便之后使用 开发部署工具 功能 build chain sh脚本用于快
  • 第四届2021美团网络安全 MT-CTF writeup

    第四届2021美团网络安全 MT CTF 文章目录 第四届2021美团网络安全 MT CTF MISC Un ix zip 鱿鱼游戏 Boom Crypto Symbol MISC Un ix zip flag Welc0me Unz1p
  • 【Hadoop】Java API 测试

    目录 一 环境配置 二 eclipse环境设置 三 代码编写 1 引入库 2 Test 3 成功界面 总结 一 环境配置 准备文件 jar包和Windows版本的hadoop2 7 4 复制 Windows版本的hadoop2 7 4文件中
  • 3789 隐藏字符串(枚举 + 递推)

    1 问题描述 给定一个由小写字母构成的字符串 s 我们称字符串 t 隐藏于字符串 s 中 如果它满足 存在一个字符串 s 的子序列 与其一一对应 该子序列的各个元素的下标可以构成一个等差序列 例如 字符串 aab 就隐藏于字符串 aaabb
  • 混淆矩阵,准确率,精确率,召回率,F1值,ROC/AUC曲线的理解

    在机器学习中 对一个模型的学习能力好坏的评估 往往人为判断不容易直接得到结果 这时候就可以根据一些数据指标进行分析评估 对模型 分类器 学习器 的泛化能力进行评估 有衡量模型泛化能力的评价标准 被称为性能度量 性能度量反应了人物需求 在对比
  • ry-ui.js

    调用方式 property function 属性 功能 通用js方法封装处理 Copyright c 2019 ruoyi 当前table相关信息 var table config 当前实例配置 options 设置实例配置 set fu
  • 企业通用人工智能时代已经开启,使用 GPT-4、llama2 和 LangChain 构建的应用程序将如何改变一切

    内容 简介 摘要 第一部分 企业 IT 50 年历史 第二部分 企业 AGI 黎明之前 第三部分 2023 年及以后的企业 AGI 之路 第四部分 我可能错的地方以及为什么它不重要 第五部分 你可以做些什么来准备 每个工作职能都会演变或消失
  • 用audition让声音更加好听

    用audition让声音更加好听 用audition让声音更加好听 用audition让声音更加好听 用audition打声音 点击如下图 选择如下 参数均衡器 把曲线弄成 V 字形 就很好听了 记得在导出之前要点击 应用 这样才生效 如下
  • 服务器硬件测试 如何查看系统信息及测试使用工具

    硬件长稳 一 查看硬件信息 sar sar命令 好一个大宝剑 7750783的技术博客 51CTO博客超全 使用 yum install sysstat 命令安装 sar命令来对系统作一个了解 该命令是系统维护的重要工具 主要帮助我们掌握系
  • 【小5聊】Postman设置环境变量之不同的IP或域名切换变量

    1 点击右上角的齿轮 2 添加环境变量 设置一个名称 比如本地环境 3 点击本地环境 进入添加参数变量和值 4 选择本地环境变量 5 点击请求即可 一句话一感想一心情 版本更新 增加测颜值推荐图文 来体验下句子的魅力
  • 李航感知机对偶形式python代码

    author xinxinzhang import numpy as np def loadData 加载数据 X np mat 3 3 4 3 1 1 Y 1 1 1 return X Y def Gram X 计算Gram矩阵 m n
  • Elasticsearch检索分类深入详解—基础篇

    题记 Elasticsearch中当我们设置Mapping 分词器 字段类型 完毕后 就可以按照设定的方式导入数据 有了数据后 我们就需要对数据进行检索操作 根据实际开发需要 往往我们需要支持包含但不限于以下类型的检索 1 精确匹配 类似m