Elasticsearch匹配短语前缀不匹配所有术语

Posted

技术标签:

【中文标题】Elasticsearch匹配短语前缀不匹配所有术语【英文标题】:Elasticsearch match phrase prefix not matching all terms 【发布时间】:2018-04-21 06:47:30 【问题描述】:

我遇到了一个问题,当我在 Elasticsearch 中使用 match_phrase_prefix 查询时,它没有返回我期望的所有结果,尤其是当查询是一个单词后跟一个字母时。

采用这个索引映射(这是一个人为的保护敏感数据的例子):

http://localhost:9200/test/drinks/_mapping

返回:


  "test": 
    "mappings": 
      "drinks": 
        "properties": 
          "name": 
            "type": "text"
          
        
      
    
  

在数以百万计的其他记录中,有这些:


    "_index": "test",
    "_type": "drinks",
    "_id": "2",
    "_score": 1,
    "_source": 
        "name": "Johnnie Walker Black Label"
    
,

    "_index": "test",
    "_type": "drinks",
    "_id": "1",
    "_score": 1,
    "_source": 
        "name": "Johnnie Walker Blue Label"
    

如下查询,即一个单词后两个字母:

POST http://localhost:9200/test/drinks/_search

    "query": 
        "match_phrase_prefix" : 
            "name" : "Walker Bl"
        
    

返回这个:


    "took": 1,
    "timed_out": false,
    "_shards": 
        "total": 5,
        "successful": 5,
        "failed": 0
    ,
    "hits": 
        "total": 2,
        "max_score": 0.5753642,
        "hits": [
            
                "_index": "test",
                "_type": "drinks",
                "_id": "2",
                "_score": 0.5753642,
                "_source": 
                    "name": "Johnnie Walker Black Label"
                
           ,
           
               "_index": "test",
               "_type": "drinks",
               "_id": "1",
               "_score": 0.5753642,
               "_source": 
                   "name": "Johnnie Walker Blue Label"
                
            
        ]
    

而这个查询只有一个单词和一个字母:

POST http://localhost:9200/test/drinks/_search

    "query": 
        "match_phrase_prefix" : 
            "name" : "Walker B"
        
    

不返回任何结果。这里会发生什么?

【问题讨论】:

【参考方案1】:

我假设您正在使用 Elasticsearch 5.0 及更高版本。 我认为这可能是因为 max_expansions 默认值。

如文档here 中所见,max_expansions 参数用于控制最后一个术语将使用多少个前缀进行扩展。默认值为 50,这可以解释为什么您会发现“黑色”和“蓝色”的前两个字母 B 和 L,但不是只有 B。

文档很清楚:

match_phrase_prefix 查询是穷人的自动完成。它非常易于使用,可让您快速开始使用“键入即搜索”,但它的结果通常足够好,但有时可能会令人困惑。

考虑查询字符串 quick brown f。此查询通过创建一个由 quick 和 brown 组成的短语查询来工作(即,术语 quick 必须存在并且必须跟在术语 brown 之后)。然后它查看已排序的术语字典以查找以 f 开头的前 50 个术语,并将这些术语添加到短语查询中。

问题是前 50 个术语可能不包括术语 fox,因此不会找到 Phase quick brown fox。这通常不是问题,因为用户会继续输入更多字母,直到出现他们要查找的单词

如果您正在寻找良好的性能,我无法告诉您是否可以将此参数增加到 50 以上,因为我自己从未尝试过。

【讨论】:

一个问题,文档说它将寻找“快速”,然后是“棕色”。然后 elasticsearch 会查找以下 50 个(默认情况下)以“f”开头并按顺序以“quick”和“brown”开头的术语吗?或者只是任何以“f”开头的术语?在前面的任何情况下,如果至少有 2 个以(在这个问题中)“b”(“蓝色”和“黑色”)开头的术语我期待看到前 50 个术语,为什么不返回结果至少应该显示这两个或其他的。或者我错了。 也许这 50 个术语来自基于集群使用的语言的内置字典(因为 ES 支持自定义语言),而不是来自索引中的不同文档。这将解释为什么它是 match_phrase_prefix 查询的自定义参数,与仅使用“size”参数不同 就我而言,我的所有字段都没有映射上的语言属性。一旦我介绍了一封新信,结果就会显示得更准确。我正在使用 multi_match 查询 "type": "phrase_prefix",所以不能使用 max_expansions 参数。 这似乎是个问题。 Index-time search-as-you-type 为我解决了这个问题:elastic.co/guide/en/elasticsearch/guide/current/…

以上是关于Elasticsearch匹配短语前缀不匹配所有术语的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch 8.X 有哪些自动补全的检索方式?

Elasticsearch 8.X 有哪些自动补全的检索方式?

Elasticsearch 8.X 有哪些自动补全的检索方式?

[Elasticsearch] 邻近匹配 - 短语匹配以及slop参数

Elasticsearch 前缀搜索、通配符搜索、正则搜索、不匹配搜索

Elasticsearch - 短语匹配(match_phrase)以及slop参数