更改 lucene/elasticsearch 中的复合令牌默认行为

问题描述

Lucene/elasticsearch 提供了复合令牌/子令牌的可能性。这是一个重要的功能,例如德语单词组合。 lucene 的认行为是将子标记OR 组合在一起,以免影响召回并排除返回的文档。但是,在特定情况下,则相反。

假设我要索引以下两个文档:

文档 1:

PUT /idxwith/_doc/1
{
  "name": "stockfisch"
}

文档 2:

PUT /idxwith/_doc/2
{
  "name" : "laufstock"
}

这里的单词会分解如下:

stockfisch  ==> stock,fisch
laufstock   ==> lauf,stock

现在使用以下搜索查询

POST /idxwith/_search
{
  "query": {
    "match": {
      "name": {
        "query": "stockfisch"
      }
    }
  }
}

我希望只返回第一个文档 - 事实并非如此。由于子标记OR 结合,两个文档都将被返回(影响我的搜索精度):

    "hits" : [
      {
        "_index" : "idxwith","_type" : "_doc","_id" : "1","_score" : 0.3287766,"_source" : {
          "name" : "stockfisch"
        }
      },{
        "_index" : "idxwith","_id" : "2","_score" : 0.241631,"_source" : {
          "name" : "laufstock"
        }
      }
    ]

我正在寻找有关如何调整 lucene(或弹性)以使此行为可配置的提示,即能够定义子令牌在必要时与 AND 组合。

谢谢!

解决方法

要解决这个问题,您可以使用 matchphrase 查询,如下所示:

POST /idxwith/_search
{
  "query": {
    "match_phrase": {
      "name": {
        "query": "stockfisch"
      }
    }
  }
}

短语查询以任何顺序匹配最多可配置的 slop(默认为 0)的术语。转置词的斜率为 2。有关 MatchPhrase 的更多信息,请检查 here

也可以在匹配查询中使用运算符,这意味着所有术语都应该在术语中,更多信息 here

在您的具体情况下,我认为 Match_Phrase 是一个更好的选择,因为术语的顺序很重要。