弹性搜索:匹配短语,提供不需要的结果

时间:2015-10-01 11:03:59

标签: apache elasticsearch lucene

我有一份包含以下数据的文件:

Hello World and 

bmw Master World

Hello

因此文档包含3行,如上所示,我已将文档编入索引到弹性搜索服务器。  我使用下面的match_phrase查询来搜索确切的短语:" World Hello"。

:query=>{ :match_phrase=>{ :text=> "World Hello" } }

令人惊讶的是,它返回上述文档。

需要注意的是,本文档不包含短语" World Hello"。但第二行以" World"结束。第3行以" Hello"开头。 这就是上述文档与查询匹配的原因。

1 个答案:

答案 0 :(得分:0)

您可能想要了解analysis的工作原理。

另请参阅phrase matching的此说明。短语中的术语不必出现在查询的确切顺序中,第一个必须出现在第二个之前。由于"hello"之后有"world",因此该文档与您的查询相符。

另请注意,此处使用standard analyzer,无论是索引文档还是分析查询,因为未指定其他分析器。如果您愿意,可以自定义此行为。

作为一个简单的例子,我创建了一个简单的索引:

PUT /test_index

然后索引您的文档(转义换行符):

PUT /test_index/doc/1
{
    "doc_text": "Hello World and \n\nbmw Master World\n\nHello"
}

然后将另一个删除最后一个“Hello”索引:

PUT /test_index/doc/2
{
    "doc_text": "Hello World and \n\nbmw Master World"
}

现在,如果我运行您的查询,则只返回第一个文档:

POST /test_index/_search
{
   "query": {
      "match_phrase": {
         "doc_text": "World Hello"
      }
   }
}  
...
{
   "took": 2,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 0.4459011,
      "hits": [
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "1",
            "_score": 0.4459011,
            "_source": {
               "doc_text": "Hello World and \n\nbmw Master World\n\nHello"
            }
         }
      ]
   }
}

您可以使用term vectors向自己证明为什么会发生这种情况。我不会在这里讨论它,但是这里有一些代码可以用来调查你是否想要:

http://sense.qbox.io/gist/3ee955b8389d1b36ea56788654955c519e2bb429