elasticsearch match_phrase在结果之前列出包含我的短语的结果,该结果与我的短语完全相同

时间:2018-02-01 17:02:31

标签: elasticsearch

我正在尝试使用ElasticSearch在字符串字段上执行短语搜索,但我并不完全理解结果返回的顺序。我有一个简单的" match_phrase"查询表格:

GET /MyIndex/_search
{
  "query": 
  { 
    "match_phrase": 
    {
      "FieldToSearch": "find this phrase" 
    }
  }
}

因此,假设我的文档包含" FieldToSearch":["This is the way to find this phrase", "find this phrase", "find this phrase to win a prize"]的以下值。我希望它能在其他2个结果之前返回"find this phrase",因为它与我正在寻找的短语完全匹配。但是,我注意到它有时会首先列出类似"find this phrase to win a prize"的内容。有没有办法返回"完全匹配"在包含完全匹配的结果之前?

1 个答案:

答案 0 :(得分:0)

短语“发现此短语”对于索引中的文档来说太常见了。基本上每个文档都匹配此搜索查询,相关性的差异很小,这是由于字段长度规范。据我所知,每个分片计算字段长度范数。因此,当索引的三个文档中的每一个都位于其自己的分片中时,您可以看到略微令人惊讶的搜索结果,其中文档与最短字段的相关性低于其他字段。您可以通过仅使用一个主分片创建索引来测试它。在那种情况下,字段值为“查找此短语”的文档将获得最高分。您还可以通过禁用字段长度规范来为多个主分片获得相同的结果:

PUT your_index/_mapping/your_type
{
  "properties": {
    "FieldToSearch": {
      "type": "text",
      "norms": false
    }
  }
}

但我认为更准确的查询会更好。

修改

我的观点是使用包含相对唯一令牌的更具体的查询。例如,不是查询索引中几乎每个文档中包含的短语Jurassic Park,而是查询仅包含在一个文档中的World Jurassic Park更好。

但是,有一种方法可以为您的示例获得所需的结果。看看this问题。您需要更改映射以在某些字段上启用令牌计数器:

PUT your_index/_mapping/your_type
{
  "properties": {
    "FieldToSearch": { 
      "type": "text",
      "fields": {
        "length": { 
          "type": "token_count",
          "analyzer": "standard"
        }
      }
    }
  }
}

然后使用function_score来提高相关性,具体取决于字段包含的令牌数量:

GET your_index/your_type/_search
{
  "query": {
    "function_score": {
      "query": {"match_phrase": {
        "title": "Jurassic Park"
      }},
      "field_value_factor": {
        "field": "FieldToSearch.length",
        "modifier": "reciprocal"
      }
    }
  }
}

这样,包含少量令牌的字段的文档将获得更高的分数。