当前位置: 首页 > article >正文

Elasticsearch-模糊查询

模糊查询

  • 前缀搜索:prefix

    概念:以xx开头的搜索,不计算相关度评分。
    注意:
    • 前缀搜索匹配的是term,而不是field。

    • 前缀搜索的性能很差

    • 前缀搜索没有缓存

    • 前缀搜索尽可能把前缀长度设置的更长

      语法:
      GET <index>/_search
      {
      "query": {
        "prefix": {
          "<field>": {
            "value": "<word_prefix>"
          }
        }
      }
      }
      index_prefixes: 默认   "min_chars" : 2,   "max_chars" : 5 
      
PUT my_index
{
  "mappings": {
    "properties": {
      "text": {
        "analyzer": "ik_max_word",
        "type": "text",
        "index_prefixes":{
          "min_chars":2,
          "max_chars":4
        },
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      }
    }
  }
}

PUT my_index的含义是向Elasticsearch发送一个PUT请求来创建一个名为“my_index”的索引。
在Elasticsearch中,索引是用于存储和检索数据的容器。每个索引都有一个或多个映射(mapping),这些映射定义了索引中字段的类型、分析器、字段属性等。在提供的JSON中,“mappings"字段的作用是指定索引的映射定义。它定义了索引中包含的字段及其属性。
在"properties"字段下,定义了一个名为"text"的字段。该字段的配置如下:
“analyzer”: “ik_max_word”:指定使用"ik_max_word"分析器,这是一个用于中文分词的分析器。
“type”: “text”:字段类型设置为"text”,表示这是一个文本字段,可以用于全文搜索。
“index_prefixes”:定义了前缀搜索的参数,其中"min_chars"和"max_chars"分别表示最小和最大前缀长度。
“fields”:定义了多重字段(multi-fields),即一个字段可以有多个不同的表示。在这里,定义了一个名为"keyword"的子字段,其类型为"keyword",表示这是一个不分析的字段,通常用于精确匹配和排序。
"ik_max_word"是IK分词器的一个变种,用于中文分词。它试图将文本尽可能细粒度地分割成单词,以提供更好的全文搜索效果。
"index_prefixes"和"fields"的用途是提供对文本字段的额外索引方式。例如,"index_prefixes"使得可以使用前缀搜索,而"fields"中的"keyword"子字段使得可以进行精确匹配和排序,而不是基于分析器的全文搜索。
综合上述配置,这个映射定义了一个名为"text"的文本字段,该字段使用"ik_max_word"分析器进行中文分词,并提供了前缀搜索和精确匹配的不同索引方式。

GET my_index/_mapping
POST /my_index/_bulk?filter_path=items.*.error
{"index":{"_id":"1"}}
{"text":"城管打电话喊商贩去摆摊摊"}
{"index":{"_id":"2"}}
{"text":"笑果文化回应商贩老农去摆摊"}
{"index":{"_id":"3"}}
{"text":"老农耗时17年种出椅子树"}
{"index":{"_id":"4"}}
{"text":"夫妻结婚30多年AA制,被城管抓"}
{"index":{"_id":"5"}}
{"text":"黑人见义勇为阻止抢劫反被铐住"}
GET my_index/_search
GET my_index/_mapping
GET _analyze
{
  "analyzer": "ik_max_word",
  "text": ["城管打电话喊商贩去摆摊摊"]
}
GET my_index/_search
{
  "query": {
    "prefix": {
      "text": {
        "value": "摊摊"
      }
    }
  }
}
# 通配符
DELETE my_index
POST /my_index/_bulk
{ "index": { "_id": "1"} }
{ "text": "my english" }
{ "index": { "_id": "2"} }
{ "text": "my english is good" }
{ "index": { "_id": "3"} }
{ "text": "my chinese is good" }
{ "index": { "_id": "4"} }
{ "text": "my japanese is nice" }
{ "index": { "_id": "5"} }
{ "text": "my disk is full" }
DELETE product_en
POST /product_en/_bulk
{ "index": { "_id": "1"} }
{ "title": "my english","desc" :  "shouji zhong de zhandouji","price" :  3999, "tags": [ "xingjiabi", "fashao", "buka", "1"]}
{ "index": { "_id": "2"} }
{ "title": "xiaomi nfc phone","desc" :  "zhichi quangongneng nfc,shouji zhong de jianjiji","price" :  4999, "tags": [ "xingjiabi", "fashao", "gongjiaoka" , "asd2fgas"]}
{ "index": { "_id": "3"} }
{ "title": "nfc phone","desc" :  "shouji zhong de hongzhaji","price" :  2999, "tags": [ "xingjiabi", "fashao", "menjinka" , "as345"]}
{ "title": { "_id": "4"} }
{ "text": "xiaomi erji","desc" :  "erji zhong de huangmenji","price" :  999, "tags": [ "low", "bufangshui", "yinzhicha", "4dsg" ]}
{ "index": { "_id": "5"} }
{ "title": "hongmi erji","desc" :  "erji zhong de kendeji","price" :  399, "tags": [ "lowbee", "xuhangduan", "zhiliangx" , "sdg5"]}
GET my_index/_search
GET product_en/_search
GET my_index/_mapping
GET product_en/_mapping
GET my_index/_search
{
  "query": {
    "wildcard": {
      "text.keyword": {
        "value": "my eng*ish"
      }
    }
  }
}

GET my_index/_search 是一个Elasticsearch的HTTP请求,用于查询名为my_index的索引库中的所有文档。其中,_search是Elasticsearch的API端点,用于执行搜索查询。

wildcard查询用于模糊匹配,支持通配符。*代表任意多个字符,?代表单个字符。

在wildcard查询中,text.keyword字段表示要在text字段的keyword子字段中执行通配符查询。value属性是查询模式,用于匹配文档中的字段值。

"value": "my eng*ish"表示查询text.keyword字段中包含"my"开头,以"ish"结尾,中间任意字符的字符串。例如,它会匹配"my english""my english speaking"等。

整个查询请求的含义是:在my_index索引库中,查找text.keyword字段值匹配"my eng*ish"模式的所有文档。

需要注意的是,wildcard查询可能不如其他类型的查询(如match、term)高效,因为它需要对索引进行全扫描,以找到匹配模式的文档。因此,在需要高效查询的场景中,可能需要选择其他类型的查询。

GET product_en/_mapping
#exact value
GET product_en/_search
{
  "query": {
    "wildcard": {
      "tags.keyword": {
        "value": "men*inka"
      }
    }
  }
}
  • 正则:regexp

    概念:regexp查询的性能可以根据提供的正则表达式而有所不同。为了提高性能,应避免使用通配符模式,如.或 .?+未经前缀或后缀
    语法:
    GET <index>/_search
    {
      "query": {
        "regexp": {
          "<field>": {
            "value": "<regex>",
            "flags": "ALL",
          }
        }
      }
    }
    
    flags
    • ALL

      启用所有可选操作符。

    • COMPLEMENT

      启用操作符。可以使用对下面最短的模式进行否定。例如

      a~bc # matches ‘adc’ and ‘aec’ but not ‘abc’

    • INTERVAL

      启用<>操作符。可以使用<>匹配数值范围。例如

      foo<1-100> # matches ‘foo1’, ‘foo2’ … ‘foo99’, ‘foo100’

      foo<01-100> # matches ‘foo01’, ‘foo02’ … ‘foo99’, ‘foo100’

    • INTERSECTION

      启用&操作符,它充当AND操作符。如果左边和右边的模式都匹配,则匹配成功。例如:

      aaa.+&.+bbb # matches ‘aaabbb’

    • ANYSTRING

      启用@操作符。您可以使用@来匹配任何整个字符串。
      您可以将@操作符与&和~操作符组合起来,创建一个“everything except”逻辑。例如:

      @&~(abc.+) # matches everything except terms beginning with ‘abc’

GET product_en/_search
{
  "query": {
    "regexp": {
      "title": "[\\s\\S]*nfc[\\s\\S]*"
    }
  }
}

该查询请求的含义是:在product_en索引中,通过正则表达式搜索title字段,查找包含nfc子串的文档。
解释如下:
GET product_en/_search:这是Elasticsearch的HTTP GET请求的基本结构,用于从product_en索引中检索数据。_search端点用于执行搜索查询。
“query"字段:在Elasticsearch查询中,query字段用于定义搜索条件。在此查询中,使用了regexp查询,它是基于正则表达式的查询。
“regexp"查询:regexp查询允许用户通过正则表达式模式来匹配文档中的字段值。在此查询中,它被用于匹配title字段。
正则表达式”[\s\S]nfc[\s\S]”:这个正则表达式的匹配规则如下:
[\s\S]:匹配任何字符,包括空格和非空格字符。
:匹配前面的字符零次或多次。
nfc:匹配字面字符串"nfc"。
再次使用[\s\S]
,表示"nfc"前后可以有任何字符(包括空格和非空格字符)。
因此,该正则表达式匹配title字段中包含"nfc"的文档,且"nfc"前后可以有任何字符。
综合以上信息,该查询请求在product_en索引中查找title字段中包含"nfc"的文档,且"nfc"前后可以有任何字符。

GET product_en/_search
{
  "query": {
    "regexp": {
      "desc": {
        "value": "zh~dng",
        "flags": "COMPLEMENT"
      }
    }
  }
}

GET product_en/_search 是一个Elasticsearch的HTTP请求,用于查询名为product_en的索引库中的所有文档。_search是Elasticsearch的API端点,用于执行搜索查询。
在这个查询中,使用了正则表达式查询(regexp),用于匹配符合特定正则表达式的字段值。具体来说,它试图匹配desc字段中包含正则表达式zh~dng的文档。
“value”: "zhdng"表示要匹配的正则表达式。在正则表达式中,通常表示匹配一个单词的边界。但在这个例子中,zhdng可能并不是一个有效的正则表达式,因为通常用于单词边界,而zhdng更像是字符z、h、、d和n的序列,并没有明确的单词边界含义。
“flags”: "COMPLEMENT"表示使用的正则表达式标志。COMPLEMENT标志表示取反,即匹配所有不符合正则表达式的文档。
然而,zh~dng可能并不是一个合适的正则表达式,因为它并不符合常见的正则表达式语法和用途。通常,在Elasticsearch中使用正则表达式查询时,我们会期望value参数中的表达式是一个有效的正则表达式,用于匹配特定的字符串模式。
因此,这个查询可能并不会按照预期工作,除非desc字段中的文档确实包含zh~dng这个字符串,或者这个查询是用于测试某种特定的正则表达式行为。
需要注意的是,Elasticsearch的正则表达式查询是基于Apache Lucene的正则表达式引擎,所以正则表达式的语法和标志可能与其他语言或工具中的有所不同。
另外,使用COMPLEMENT标志时,请确保您的查询是清晰的,并且了解它将返回不符合正则表达式的文档。在实际应用中,确保您的正则表达式是有效的,并且与您的查询意图相匹配。

GET product_en/_search
{
  "query": {
    "regexp": {
      "tags.keyword": {
        "value": ".*<2-3>.*",
        "flags": "INTERVAL"
      }
    }
  }
}

查询包含2-3的数据

这是一个Elasticsearch查询语句,用于在product_en索引中搜索数据。这个查询语句使用了正则表达式查询(regexp),它允许用户通过正则表达式模式来匹配文档中的字段值。
GET product_en/_search:
这部分是Elasticsearch的HTTP GET请求的基本结构,用于从product_en索引中检索数据。_search端点用于执行搜索查询。regexp查询:
regexp查询是Elasticsearch中的一种查询类型,它使用正则表达式来匹配文档中的字段值。这种查询类型特别适用于需要基于模式匹配的场景。
“tags.keyword”:
这表示查询的是tags.keyword字段。tags可能是一个包含多个标签的字段,而keyword通常表示该字段的值是精确匹配的,不会被分词。
“value”: “.<2-3>.”:
这是正则表达式的模式。这里的模式尝试匹配任何包含<2-3>字符串的文本。但是,.*<2-3>.*并不是一个有效的正则表达式,因为它没有定义<2-3>应该匹配的具体内容。通常,<2-3>会被当作字面量而不是正则表达式的一部分,这意味着它会尝试匹配包含这个字符串的文档。
“flags”: “INTERVAL”:
flags参数用于指定正则表达式的匹配选项。然而,INTERVAL并不是Elasticsearch中regexp查询的有效标志。标准的regexp标志包括ALL、ANYSTRING、COMPLEMENT、EMPTY、INTERSECTION、INTERVAL、NONE、NOTEMPTY和NOTNONE。其中,INTERVAL标志用于定义重复数量的区间,但它通常与{}一起使用,例如{2,3}表示匹配2到3次重复。在这里,flags的INTERVAL值可能是错误的,或者该查询可能尝试使用一个特定于应用程序或自定义的正则表达式标志。
这个查询整体上试图找到tags.keyword字段中包含<2-3>字符串的文档,但由于正则表达式模式不正确,以及flags参数中可能存在的错误,这个查询可能不会返回预期的结果。正确的正则表达式模式取决于<2-3>应如何解释,以及是否应该使用特定的标志来影响匹配过程。
这个查询可能适用于需要基于标签中的特定模式或特定值进行搜索的场景,例如,如果<2-3>是一个特定的标签值,并且你想找到所有包含这个标签的文档。然而,由于正则表达式和标志的错误,这个查询可能需要进行修正才能正常工作。

  • 模糊查询:fuzzy

    混淆字符 (box → fox) 缺少字符 (black → lack)

    多出字符 (sic → sick) 颠倒次序 (act → cat)

    语法
    GET <index>/_search
    {
      "query": {
        "fuzzy": {
          "<field>": {
            "value": "<keyword>"
          }
        }
      }
    }
    
    参数:
    • value:(必须,关键词)

    • fuzziness:编辑距离,(0,1,2)并非越大越好,召回率高但结果不准确

      1. 两段文本之间的Damerau-Levenshtein距离是使一个字符串与另一个字符串匹配所需的插入、删除、替换和调换的数量

      2. 距离公式:Levenshtein是lucene的,es改进版:Damerau-Levenshtein,

      axe=>aex Levenshtein=2 Damerau-Levenshtein=1

    • transpositions:(可选,布尔值)指示编辑是否包括两个相邻字符的变位(ab→ba)。默认为true。

GET product_en/_search
{
  "query": {
    "fuzzy": {  
      "desc": {
        "value": "zhandou",
        "fuzziness": "2"
      }
    }
  }
}

该查询请求的含义是:在product_en索引中,使用模糊查询(fuzzy query)在desc字段中查找包含与"quangongneng nfc"相似词项的文档。
解释如下:
GET product_en/_search:这是Elasticsearch的HTTP GET请求的基本结构,用于从product_en索引中检索数据。_search端点用于执行搜索查询。
"query"字段:在Elasticsearch查询中,query字段用于定义搜索条件。在此查询中,使用了fuzzy查询,它是基于模糊匹配的查询,用于查找与指定词项相似的词项。
"fuzzy"查询:fuzzy查询在Elasticsearch中允许用户通过编辑距离(fuzziness)来匹配与指定词项相似的词项。它基于Levenshtein距离(也称为编辑距离)来度量两个词项之间的相似性。
“value"字段:value参数定义了要搜索的原始词项,即"quangongneng nfc”。
“fuzziness"字段:fuzziness参数定义了最大的编辑距离,用于确定与原始词项相似的词项。在这里,fuzziness设置为"2”,意味着查询将匹配与"quangongneng nfc"在最多两个字符内相似的词项。
综合以上信息:整个查询请求在product_en索引中查找desc字段中包含与"quangongneng nfc"相似的词项的文档,其中相似度由最多两个字符的编辑距离确定。
此查询将返回与"quangongneng nfc"在最多两个字符内相似的所有词项所在的文档。

GET product_en/_search
{
  "query": {
    "match_phrase_prefix": {
      "desc": {
        "query": "zhong hongzhaji",
        "max_expansions": 50,
        "slop": 3
      }
    }
  }
}

这个查询请求的含义是:在product_en索引中,使用match_phrase_prefix查询在desc字段中查找与"zhong hongzhaji"相似词项的文档。
解释如下:
GET product_en/_search:这是一个Elasticsearch的HTTP GET请求,用于从product_en索引中检索数据。_search端点用于执行搜索查询。
match_phrase_prefix查询:这是一个特定类型的查询,它用于查找与指定词项在特定字段中相似(但不一定完全匹配)的词项。与match_phrase查询相比,match_phrase_prefix允许在最后一个词项上只匹配前缀,从而可以捕获更多与查询词项相似的词项。
“zhong hongzhaji”:这是搜索的查询词项,表示用户想要查找与"zhong hongzhaji"相关的内容。
max_expansions: 50:这个参数定义了最后一个词项可以被重写(扩展)成多少个前缀。这里设置为50,意味着将尝试生成最多50个前缀来匹配文档中的词项。
slop: 3:这个参数用于定义在匹配词项时,允许词项之间的最大位移量。这里的值为3,表示在匹配过程中,词项之间的最大距离为3个词项。
整个查询语句的意图:这个查询请求的目的是在product_en索引中查找与"zhong hongzhaji"相关的文档,通过扩展前缀和允许一定的词项位移量,以捕获更多相似但不完全匹配的文档。
应用场景:这个查询可能用于类似搜索引擎的场景,当用户输入部分搜索词时,系统能够自动补全或推荐与用户输入相似的完整词项,以提供更精确的搜索结果。例如,在电商网站中,用户可能输入"zhong"作为商品名称的一部分,系统可以推荐完整的商品名称,如"zhong xiao mi"或"zhong xing"等。
这个查询使用了Elasticsearch的match_phrase_prefix查询类型,它允许用户输入部分搜索词,并自动补全或推荐与用户输入相似的完整词项,从而提供更精确和相关的搜索结果。

GET _analyze
{
  "tokenizer": "ik_max_word",
  "filter": [ "edge_ngram" ],
  "text": "reba always loves me"
}

PUT my_index
{
  "settings": {
    "analysis": {
      "filter": {
        "2_3_edge_ngram": {
          "type": "edge_ngram",
          "min_gram": 2,
          "max_gram": 3
        }
      },
      "analyzer": {
        "my_edge_ngram": {
          "type":"custom",
          "tokenizer": "standard",
          "filter": [ "2_3_edge_ngram" ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "text": {
        "type": "text",
        "analyzer":"my_edge_ngram",
        "search_analyzer": "standard"
      }
    }
  }
}
GET /my_index/_mapping


POST /my_index/_bulk
{ "index": { "_id": "1"} }
{ "text": "my english" }
{ "index": { "_id": "2"} }
{ "text": "my english is good" }
{ "index": { "_id": "3"} }
{ "text": "my chinese is good" }
{ "index": { "_id": "4"} }
{ "text": "my japanese is nice" }
{ "index": { "_id": "5"} }
{ "text": "my disk is full" }


GET /my_index/_search
GET /my_index/_mapping
GET /my_index/_search
{
  "query": {
    "match_phrase": {
      "text": "my eng is goo"
    }
  }
}



PUT my_index2
{
  "settings": {
    "analysis": {
      "filter": {
        "2_3_grams": {
          "type": "edge_ngram",
          "min_gram": 2,
          "max_gram": 3
        }
      },
      "analyzer": {
        "my_edge_ngram": {
          "type":"custom",
          "tokenizer": "standard",
          "filter": [ "2_3_grams" ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "text": {
        "type": "text",
        "analyzer":"my_edge_ngram",
        "search_analyzer": "standard"
      }
    }
  }
}
GET /my_index2/_mapping
POST /my_index2/_bulk
{ "index": { "_id": "1"} }
{ "text": "my english" }
{ "index": { "_id": "2"} }
{ "text": "my english is good" }
{ "index": { "_id": "3"} }
{ "text": "my chinese is good" }
{ "index": { "_id": "4"} }
{ "text": "my japanese is nice" }
{ "index": { "_id": "5"} }
{ "text": "my disk is full" }

GET /my_index2/_search
{
  "query": {
    "match_phrase": {
      "text": "my eng is goo"
    }
  }
}

GET _analyze
{
  "tokenizer": "ik_max_word",
  "filter": [ "ngram" ],
  "text": "用心做皮肤,用脚做游戏"
}

http://www.kler.cn/a/453311.html

相关文章:

  • 【Docker命令】如何使用`docker exec`在容器内执行命令
  • GJB289A总线典型网络理论分析
  • Qt使用QZipWriter和QZipReader来解压、压缩文件
  • 实战分享:开发设计文档模版及编写要点
  • 信息安全管理与评估赛题第9套
  • 低代码开发中 DDD 领域驱动的页面权限控制
  • C语言学习(10)—递归
  • git回退指定版本/复制提交id
  • 【算法题解】Berland 路标限速问题(Follow Traffic Rules)
  • Google Cloud Architect 认证考试错题集7
  • 华三M-LAG场景下,部分MAC内的流量泛洪导致端口流量打满
  • 信创数据防泄漏中信创沙箱是什么样的安全方案
  • 配置带外与更改密码
  • upload-labs关卡记录11
  • ViT-Reg:面向tinyML平台的回归聚焦型硬件感知微调Vision Transformer
  • 自动驾驶控制算法-横向控制与流程代码仿真
  • 2-196基于matlab的混沌改进蚁群算法优化PID
  • 如何通过HTTP API插入Doc
  • Unity学习1:初接触,C#的一些基础,和相关报错
  • 前端(八)js介绍(1)
  • 使用Docker启动Linux Riscv版
  • 什么是公网对讲机?公网对讲机有哪些好的品牌
  • 游戏引擎学习第59天
  • Database.NET——一款轻量级多数据库客户端工具
  • 微软 CEO 萨提亚・纳德拉:回顾过去十年,展望 AI 时代的战略布局
  • 网络安全研究中的网络攻击