具有 multi_match 和 bool_prefix 类型的 Elasticsearch 模糊性

Posted

技术标签:

【中文标题】具有 multi_match 和 bool_prefix 类型的 Elasticsearch 模糊性【英文标题】:Elasticsearch fuzziness with multi_match and bool_prefix type 【发布时间】:2022-01-08 05:01:48 【问题描述】:

我有一组 search_as_you_type_fields 我需要搜索。这是我的地图

"mappings" : 
      "properties" : 
        "description" : 
          "type" : "search_as_you_type",
          "doc_values" : false,
          "max_shingle_size" : 3
        ,
        "questions" : 
          "properties" : 
            "content" : 
              "type" : "search_as_you_type",
              "doc_values" : false,
              "max_shingle_size" : 3
            ,
            "tags" : 
              "type" : "text",
              "fields" : 
                "keyword" : 
                  "type" : "keyword"
                
              
            
          
        ,
      
        "title" : 
          "type" : "search_as_you_type",
          "doc_values" : false,
          "max_shingle_size" : 3
        ,
      
    

我正在使用 bool_prefix 类型的 multi_match 查询。

"query": 
    "multi_match": 
      "query": "triangle", 
      "type": "bool_prefix",
       "fields": [
           "title",
           "title._2gram",
           "title._3gram",
           "description",
           "description._2gram",
           "description._3gram",
           "questions.content",
           "questions.content._2gram",
           "questions.content._3gram",
           "questions.tags",
           "questions.tags._2gram",
           "questions.tags._3gram"
       ]
    
  

到目前为止工作正常。现在我想添加一个错字容错,这是 ES 中的模糊性。但是,看起来 bool_prefix 与此有一些冲突。因此,如果我修改查询并添加“fuzziness”:“AUTO”并在单词“triangle”->“triangld”中出错,它将不会得到任何结果。

但是,如果我正在寻找一个短语“直角三角形”,我有一些不同的行为:

    即使没有拼写错误,我也能通过“模糊”获得更多结果:“AUTO”(1759 与 1267) 如果我在 2d 单词“right triangdd”中添加错字,它似乎可以工作,但看起来它现在会首先推送包含“right”而没有“triangle”的结果(“权利法案”、“正当程序和隐私权”等)。 如果我在第一个单词(“直角三角形”)或两者(“右三角”)中打错字,结果似乎还不错。所以这可能是唯一正确的行为。

我看过几篇文章,甚至 GitHub 上的问题,即模糊性在使用 bool_prefix 的 multi_match 查询时无法正常工作,但我找不到解决方法。我尝试更改查询类型,但看起来 bool_prefix 是唯一支持在您键入时进行搜索的类型,并且我需要在用户开始输入内容时获取搜索结果。

由于我从后端发出来自 ES 的所有请求,因此我还可以操作查询字符串以在需要时构建不同的搜索查询类型。例如,对于 1 个单词搜索,使用一种类型进行多使用另一种。但我基本上需要保持当前的行为。

我还尝试在字符串中附加一个符号“~”或“~1[2]”,这似乎是指定模糊性的另一种方式,但结果相当不清楚,性能(搜索速度)似乎变得更糟。

我的问题是:

    如何实现 1 字搜索的模糊性?以便查询“triangld”返回包含“triangle”等的文档。 当查询的 2d(最后一个?)单词中出现拼写错误时,如何获得正确的搜索结果?就像我上面提到的那样,它有效,但请参阅上面的第 2 点 即使短语正确,为什么只添加模糊性(参见第 1 页)会返回更多结果? 我的分析仪等有什么需要改变的吗?

【问题讨论】:

【参考方案1】:

为了达到预期的行为,我们做了以下工作:

    将查询类型更改为“query_string” 在后端添加了查询字符串预处理。我们用空格分割查询字符串,如果每个单词的长度分别超过 4 个字符或 8 个字符,则在每个单词中添加“~1”或“~2”。 ~ 是 ES 中的一种模糊语法。但是,在用户键入空格之前,我们不会将其添加到当前键入的单词中。例如,用户输入 [t, tr, tri, ... triangle] => 没有模糊,但一次“triangle” => “triangle~2”。这是因为最后一个词有模糊性会有意想不到的结果 我们还从搜索字段中删除了所有 ngram 字段,因为我们得到了相同的结果,但性能要好一些。 在查询中添加了“default_operator”:“AND”以包含短语查询的一个字段的结果

【讨论】:

以上是关于具有 multi_match 和 bool_prefix 类型的 Elasticsearch 模糊性的主要内容,如果未能解决你的问题,请参考以下文章

multi_match 的 minimum_should_match

Elasticsearch:Multi-match (multi_match) 及 Disjunction max 查询

Elasticsearch:Multi-match (multi_match) 及 Disjunction max 查询

嵌套:QueryParsingException[[multi_match] 查询不支持 [fields]];

elasticsearch term match multi_match区别

multi_match 查询