代码之家  ›  专栏  ›  技术社区  ›  Paul T Davies

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

  •  9
  • Paul T Davies  · 技术社区  · 7 年前

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

    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 回复  |  直到 7 年前
        1
  •  13
  •   Community TheSoundDefense    4 年前

    我假设您使用的是Elasticsearch 5.0及以上版本。 我认为这可能是因为max\u扩展的默认值。

    here ,max_扩展参数用于控制最后一项将扩展多少前缀。默认值为50,这可能解释了为什么“黑色”和“蓝色”包含前两个字母B和L,而不仅仅包含B。

    文档对此非常清楚:

    match\u phrase\u前缀查询是穷人的自动完成查询。它很容易使用,可以让您在键入时快速开始搜索,但它的结果通常足够好,有时可能会令人困惑。

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

    问题是,前50个项可能不包括项fox,因此不会找到相位快速棕色fox。这通常不是问题,因为用户会继续键入更多字母,直到他们要查找的单词出现

    如果你想获得好的性能,我无法告诉你是否可以将这个参数增加到50以上,因为我从未尝试过自己。