Elasticsearch:wildcard - 通配符搜索

Elasticsearch 是一个分布式、免费和开放的搜索和分析引擎,适用于所有类型的数据,例如文本、数字、地理空间、结构化和非结构化数据。 它基于 Apache Lucene 构建,Apache Lucene 是一个全文搜索引擎,可用于各种编程语言。 由于其速度、可扩展性以及对不同类型内容进行索引的能力,Elasticsearch 已在多种用例中得到应用,例如:

  • 企业搜索
  • 日志记录和日志分析
  • 应用搜索
  • 商业分析
  • 地理空间数据分析和可视化

它是如何工作的?

Elasticsearch 不是将信息存储为列式数据行,而是存储已序列化为 JSON 文档的复杂数据结构。 每个文档由一组键(文档中的字段或属性的名称)及其相应的值(字符串、数字、布尔值、日期、值数组、地理位置或其他类型的数据)组成。 它使用一种称为倒排索引的数据结构,列出任何文档中出现的每个唯一单词,并标识每个单词出现的所有文档。

字段类型 - 分析或未分析

Elasticsearch 中的字符串文字要么被分析,要么未被分析。 那么分析到底是什么意思呢? 已分析字段是指在索引之前经过分析过程的字段。 然后,该分析的结果存储在倒排索引中。 分析过程基本上涉及对文本块进行分词和规范化。 这些字段被分词为术语,并且术语被转换为小写字母。 这是标准分析器的行为,也是默认行为。 但是,如果需要,我们可以指定我们自己的分析器,例如,如果你还想索引特殊字符,而标准分析器则不会这样做。如果你想对 analyzer 有更多的了解,请阅读文章 “Elasticsearch: analyzer”。

我们尝试使用如下的命令来进行分词:

GET _analyze
{
  "analyzer": "standard",
  "text" : "Beijing is a beautiful city"
}

Elasticsearch 的标准分析器会将此文本转换为以下内容:

{
  "tokens": [
    {
      "token": "beijing",
      "start_offset": 0,
      "end_offset": 7,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "is",
      "start_offset": 8,
      "end_offset": 10,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "a",
      "start_offset": 11,
      "end_offset": 12,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "beautiful",
      "start_offset": 13,
      "end_offset": 22,
      "type": "<ALPHANUM>",
      "position": 3
    },
    {
      "token": "city",
      "start_offset": 23,
      "end_offset": 27,
      "type": "<ALPHANUM>",
      "position": 4
    }
  ]
}

通配符(wildcard)搜索快速介绍

通配符是特殊字符,充当文本值中未知字符的占位符,并且可以方便地查找具有相似但不相同数据的多个项目。 通配符搜索基于查询中提到的字符与包含这些字符模式的文档中的单词之间的字符模式匹配。

查找名字/姓氏为 John 的每个人

现在我们已经基本了解了 Elasticsearch 的工作原理、分析字段和通配符搜索是什么,让我们更深入地了解本文的主题 — 字符串字段并对其运行通配符搜索。

字符串字段和通配符搜索

Elasticsearch 中的每个字段都有一个字段数据类型。 此类型指示字段包含的数据类型(例如字符串或布尔值)及其预期用途。 Elasticsearch 中可用于字符串的两种字段类型是 — text(默认)和 keyword。 它们之间的主要区别在于,文本字段在索引时进行分析,而关键字字段则不然。 这意味着,文本字段在索引之前会被标准化并分解为单独的分词,而关键字字段则按原样存储。 此外,由于文本字段已标准化,因此它们支持不区分大小写的搜索。 为了对关键字字段实现相同的效果,我们必须在创建索引时定义一个 normalizer,然后在定义字段映射时指定相同的 normalizer。有关 nomalizer 的详细介绍,请阅读文章 “Elasticsearch:词分析中的 Normalizer 的使用”。

PUT wildcard
{
  "settings": {
    "analysis": {
      "normalizer": {
        "lowercase_normalizer": {
          "type": "custom",
          "char_filter": [],
          "filter": [
            "lowercase",
            "asciifolding"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "text-field": {
        "type": "text"
      },
      "keyword-field": {
        "type": "keyword",
        "normalizer": "lowercase_normalizer"
      }
    }
  }
}

现在进行通配符查询,假设我们有以下文档,并且我们想要对其运行一些通配符搜索:

PUT wildcard/_doc/1
{
  "text-field": "Mockingbirds don’t do one thing but make music for us to enjoy.",
  "keyword-field": "Mockingbirds don’t do one thing but make music for us to enjoy."
}

如下所示的查询可以很好地处理文本字段:

GET wildcard/_search?filter_path=**.hits
{
  "_source": false, 
  "fields": [
    "text-field"
  ], 
  "query": {
    "wildcard": {
      "text-field": {
        "value": "*birds*"
      }
    }
  }
}

上面的搜索返回结果:

{
  "hits": {
    "hits": [
      {
        "_index": "wildcard",
        "_id": "1",
        "_score": 1,
        "fields": {
          "text-field": [
            "Mockingbirds don’t do one thing but make music for us to enjoy."
          ]
        }
      }
    ]
  }
}

然而,下面的搜索则不会:

GET wildcard/_search?filter_path=**.hits
{
  "_source": false, 
  "fields": [
    "text-field"
  ], 
  "query": {
    "wildcard": {
      "text-field": {
        "value": "*birds*music*"
      }
    }
  }
}

它返回的结果是:

{
  "hits": {
    "hits": []
  }
}

原因是,该字段的单词已被分析并存储为分词。 因此,elasticsearch 无法找到与给定表达式(*birds*music*)对应的分词。

但是,这适用于关键字字段,因为它们按原样存储。我们来尝试如下的搜索:

GET wildcard/_search?filter_path=**.hits
{
  "_source": false,
  "fields": [
    "keyword-field"
  ],
  "query": {
    "wildcard": {
      "keyword-field": {
        "value": "*birds*music*"
      }
    }
  }
}

上面的命令返回的结果是:

{
  "hits": {
    "hits": [
      {
        "_index": "wildcard",
        "_id": "1",
        "_score": 1,
        "fields": {
          "keyword-field": [
            "mockingbirds don't do one thing but make music for us to enjoy."
          ]
        }
      }
    ]
  }
}

现在,让我们讨论从 ElasticSearch v7.9 引入的另一个字符串字段——通配符。 这是一种专门的字段类型,主要用于非结构化机器生成的内容。更多阅读,请参阅文章 “Elasticsearch:使用新的 wildcard 字段更快地在字符串中查找字符串 - 7.9 新功能”。

以下是对这 3 种字段类型运行几个通配符查询的性能统计数据:

Query : *Elasticsearch* — Full word search

Query : *Wal* — Substring search

Query : *Elastic*stash* — Search across multiple words

我们可以清楚地看到,关键字字段的性能在所有搜索查询和索引大小中是最一致的。 文本字段也做得不错,但它们不能用于搜索像 *Elastic*stash* 这样的值,这使得关键字类型成为明显的赢家。

那么为什么要引入通配符字段呢? 那么,引入通配符字段是为了解决文本和关键字字段存在的以下限制:

  • 文本字段 - 将任何通配符表达式的匹配限制为单个分词,而不是字段中保存的原始整个值。
  • 关键字字段 - 当搜索子字符串和有许多唯一值时,关键字字段的速度很慢。 关键字字段还存在数据大小限制的缺点。 默认字符串映射会忽略长度超过 256 个字符的字符串。 这可以扩展到单个令牌 32k 的 Lucene 硬限制。 当您尝试搜索系统日志和类似文档时,这可能会产生问题。

通配符字段解决了上述限制。 它不会将字符串视为由标点符号分隔的标记集合,而是通过首先对所有文档进行近似匹配,然后对通过匹配接收到的文档子集应用详细比较来执行模式匹配。

文本、关键字和通配符字段之间的详细比较可以在此处阅读。

上述统计信息是通过在 v8.9 上运行的 elasticsearch 索引上运行搜索获得的,映射如下:

{
    "wildcard-search-demo-index": {
        "mappings": {
            "properties": {
                "field1": {
                    "type": "text"
                },
                "field2": {
                    "type": "keyword"
                },
                "field3": {
                    "type": "wildcard"
                }
            }
        }
    }
}

索引的文档在所有字段中具有统一的数据,即文档中的所有 3 个字段都具有相同的值。 例如,

"hits": [
            {
                "_index": "wildcard-search-demo-index",
                "_type": "_doc",
                "_id": "vlPiHYYB6ikeelRg4I8n",
                "_score": 1.0,
                "_source": {
                    "field1": "It started as a scalable version of the Lucene open-source search framework then added the ability to horizontally scale Lucene indices.",
                    "field2": "It started as a scalable version of the Lucene open-source search framework then added the ability to horizontally scale Lucene indices.",
                    "field3": "It started as a scalable version of the Lucene open-source search framework then added the ability to horizontally scale Lucene indices."
                }
            },
            {
                "_index": "wildcard-search-demo-index",
                "_type": "_doc",
                "_id": "v1PiHYYB6ikeelRg4I87",
                "_score": 1.0,
                "_source": {
                    "field1": "Elasticsearch allows you to store, search, and analyze huge volumes of data quickly and in near real-time and give back answers in milliseconds.",
                    "field2": "Elasticsearch allows you to store, search, and analyze huge volumes of data quickly and in near real-time and give back answers in milliseconds.",
                    "field3": "Elasticsearch allows you to store, search, and analyze huge volumes of data quickly and in near real-time and give back answers in milliseconds."
                }
            }
        ]

综上所述,字段类型的选择并没有固定的规则。 它取决于多种因素,例如数据类型、必须涵盖的不同用例集等。

在设置数据存储时,决定字段类型是一个非常关键的因素,因为它极大地影响性能,并且应该通过考虑所有可能的场景和因素来决定。

Elasticsearch 还有一种称为通配符的查询类型,可用于运行通配符查询。 

另外值得指出的是:由于通配符搜索带来很多的性能问题,有时甚至会吃掉很多的系统资源。在生成环境中,有的建议关掉这个功能以避免影响系统的运行。建议阅读文章:

  • Kibana:如何在 Kibana 中禁止查询中使用前置通配符(wildcard)查询

  • Elasticsearch:如何提高查询性能

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

windows环境装MailHog

背景&#xff1a;win10系统&#xff0c;windows 宝塔&#xff0c;laravel 项目&#xff0c;邮件相关需要装一个MailHog 下载地址&#xff1a;https://sourceforge.net/projects/mailhog.mirror/ 直接下载&#xff0c;下载后双击运行就可以了&#xff0c;系统可能提示”不信任“…

stable diffusion实践操作-SD原理

本文专门开一节写提示词相关的内容&#xff0c;在看之前&#xff0c;可以同步关注&#xff1a; stable diffusion实践操作 正文 1、出图原理 1.1 AI画画不是和人一样&#xff0c;从0开始&#xff0c;而是一个去噪点的过程&#xff1a; 1.2 逆向去噪 所有的人图片都是从一张噪…

重新理解百度智能云:写在大模型开放后的24小时

在这些回答背后共同折射出的一个现实是——大模型不再是一个单选题&#xff0c;而更是一个综合题。在这个新的时代帆船上&#xff0c;产品、服务、安全、开放等全部都需要成为必需品&#xff0c;甚至是从企业的落地层面来看&#xff0c;这些更是刚需品。 作者| 皮爷 出品|产…

jmeter 线程组

在jmeter中&#xff0c;通过指定并发数量、启动延迟时间和持续时间&#xff0c;并组织示例&#xff08;Samplers&#xff09;在多个线程之间的执行方式&#xff0c;实现模拟并发用户的行为。 添加线程组&#xff1a; 在测试计划中&#xff0c;右键点击“添加” -> “Thread…

53 个 CSS 特效 3(完)

53 个 CSS 特效 3&#xff08;完&#xff09; 前两篇地址&#xff1a; 53 个 CSS 特效 153 个 CSS 特效 2 这里是第 33 到 53 个&#xff0c;很多内容都挺重复的&#xff0c;所以这里解释没之前的细&#xff0c;如果漏了一些之前的笔记会补一下&#xff0c;写过的就会跳过。…

【游戏开发教程】Unity Cinemachine快速上手,详细案例讲解(虚拟相机系统 | 新发出品 | 良心教程)

文章目录 一、前言二、插件下载三、案例1&#xff1a;第三人称自由视角&#xff0c;Free Look character场景1、场景演示2、组件参数2.1、CinemachineBrain&#xff1a;核心2.2、CinemachineFreeLook&#xff1a;第三人称自由视角相机2.2.1、设置Follow&#xff1a;跟随2.2.2、…

openlayers-16-添加一组轨迹动画

实现一组动画&#xff0c;即根据一组只有起止点坐标的线段&#xff0c;实现点在这些线段上较为平滑的移动&#xff0c;移动速度和平滑程度均可控制。 下面的代码仅作为思路参考&#xff0c;还欠缺很多细节&#xff0c;比如在进行插值计算时&#xff0c;还需要判断经纬度坐标差&…

6. vue-element-admin 二次开发避坑指南

vue-element-admin 二次开发避坑指南 1.1 前言1.1.1 切换标签时未保存页面的操作内容1.1.2 markdown 样式乱码1.1.3 修改默认尺寸1.1.4 当后端服务器宕机情况下页面加载层一直转圈无法停止&#xff0c;只能关闭页面1.1.5 隐藏齿轮 1.1 前言 上一篇博文&#xff0c;我们分享了vu…

传送带下料口堵塞识别检测算法 yolov5

传送带下料口堵塞识别检测算法通过python基于yolov5网络深度学习框架模型&#xff0c;下料口堵塞识别检测算法能够准确判断下料口是否出现堵塞现象&#xff0c;一旦发现下料口堵塞&#xff0c;算法会立即抓拍发出告警信号。Python是一种由Guido van Rossum开发的通用编程语言&a…

【VM】保姆级VM算法平台二次开发之-环境配置

VM算法平台二次开发 1.下载Visual Studio 20222.项目的创建 C# 应用3.设置属性&#xff0c;去掉属选型32位4. 进行引用的导入工作5. 重新加载&#xff0c;查看引用6. 工具箱添加Dll的依赖。&#xff08;只需要加载一次就行&#xff09; 1.下载Visual Studio 2022 可以直接在官…

【学习笔记】计算机视觉对比学习综述

计算机视觉对比学习综述 前言百花齐放InstDiscInvaSpreadCPCCMC CV双雄MoCoSimCLRMoCo v2SimCLR v2SwAV 不用负样本BYOLSimSiam TransformerMoCo v3DINO 总结参考链接 前言 本篇对比学习综述内容来自于沐神对比学习串讲视频以及其中所提到的论文和博客&#xff0c;对应的链接详…

ESXi 6.7添加螃蟹2.5g网卡支持

安装了ESXi 6.7&#xff0c;结果机器两块网卡只能识别一块&#xff0c;然后想着不能让另一块浪费啊&#xff0c;开始折腾&#xff0c;看着网上都是找的驱动然后封装进iso&#xff0c;可是我已经装完了&#xff0c;怎么办&#xff0c;然后找到了下面解决方法 1.找驱动 下载RTL81…

对话出海企业:2023亚马逊云科技出海日圆桌论坛

在全球经济亟待复苏的今天&#xff0c;持续对外开放是中国未来经济发展重要的“两条腿”之一。在愈发饱和的国内市场&#xff0c;中国企业需要对外寻找全新机遇才能在未来不确定的市场博弈下生存下去。“出海”&#xff0c;也成为近几年最炙手可热的词汇之一&#xff0c;大量中…

mysql通过.frm和.ibd 文件恢复数据库

问题背景&#xff1a;由于强制在服务关闭mysql导致部分数据表以及数据丢失 如下图只有.frm .ibd的文件为我的问题文件 查找不到表结构和表数据目录D:XXXX\mysql-5.7.24-winx64\data\mydata 从frm文件中恢复表结构 先把原来的数据备份一次 避免过程中出错 先备份之前数据的.fr…

Oracle的学习心得和知识总结(二十九)|Oracle数据库数据库回放功能之论文三翻译及学习

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《Oracle Database SQL Language Reference》 2、参考书籍&#xff1a;《PostgreSQL中文手册》 3、EDB Postgres Advanced Server User Gui…

数据结构入门 — 栈

本文属于数据结构专栏文章&#xff0c;适合数据结构入门者学习&#xff0c;涵盖数据结构基础的知识和内容体系&#xff0c;文章在介绍数据结构时会配合上动图演示&#xff0c;方便初学者在学习数据结构时理解和学习&#xff0c;了解数据结构系列专栏点击下方链接。 博客主页&am…

利用逻辑回归判断病人肺部是否发生病变

大家好&#xff0c;我是带我去滑雪&#xff01; 判断肺部是否发生病变可以及早发现疾病、指导治疗和监测疾病进展&#xff0c;以及预防和促进肺部健康&#xff0c;定期进行肺部评估和检查对于保护肺健康、预防疾病和提高生活质量至关重要。本期将利用相关医学临床数据结合逻辑回…

DEAP库文档教程二-----创建类型

本节将展示如何通过creator创建类型以及如何使用toolbox进行初始化。 1、Fitness 已经提供的Fitness类是一个抽象类&#xff0c;它需要weight来使得它成为一个函数。一个最小化的适应度是通过负权重构建的&#xff0c;而一个最大化适应度则需要正权重。 creator.create(&quo…

算法通关村第10关【青铜】| 快速排序各种写法

思路&#xff1a; 指定一个数字&#xff0c;将数组比他小的放到左边&#xff0c;比他大的放到右边&#xff0c;实现归位 然后再指定一个数字递归&#xff0c;一直遍历完数组 最好的情况每次指定的都是中间位置的数字&#xff0c;划分完后两边长度相等&#xff0c;2T(n/2) O…

Ansible之playbooks剧本

文章目录 一.playbooks介绍1.playbooks简述2.playbooks剧本格式3.playbooks组成部分4.运行playbooks及检测文件配置 二.模块实战实例1.playbooks模块实战实例2.vars模块实战实例3.指定远程主机sudo切换用户4.when模块实战实例5.with_items迭代模块实战实例6.Templates 模块实战…