>想象一下,我有一些文档,以下值包含在一个名为name
的文本字段中
- 文档 1:
abc xyz group
- 文档2:
group x/group y
- 文档3:
group 1, group 2, group 3, group 4
现在假设我正在向 ES 发送术语"组"的简单匹配查询:
{
"query": {
"match": {
"name": "group"
}
}
}
我期望的结果是所有 3 个文档都将以相同的分数返回,无论该术语出现的频率、出现的位置等。 现在,我已经知道我可以通过用constant_score
包裹我的match
来做到这一点,如下所示:
{
"query": {
"constant_score": {
"filter": {
"match": {
"name": "group"
}
},
"boost": 1
}
}
}
但是,假设我现在想使用搜索词abc group
进行查询。在这种情况下,我想发生的是 Document2 和 Document3 将返回相同的分数(匹配group
),但 Document1 具有更好的分数,因为它同时匹配abc
和group
。
使用包装我的match
查询的constant_score
,包含任何术语的文档返回相同的分数(即 Document1、2 和 3 返回相同的abc group
分数)。如果我删除constant_score
,那么文档 3 的得分可能最高,因为它包含与搜索文本的更多匹配项(group
出现 4 次)。
似乎我需要一种方法,将constant_score
查询移动到match
查询分析了我的搜索文本之后。有效地使abc group
查询成为两个constant_score
查询 - 一个用于abc
,一个用于group
。
有谁知道实现这一目标的方法?
我设法通过使用Elasticsearch的unique
令牌过滤器来解决这个问题:https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-unique-tokenfilter.html
我已将其添加到索引映射中的name
字段中,它看起来正在检索所需的结果,而不必担心constant_score
。
但请注意,所有这些只是消除术语频率对_score
的任何影响 - 其他指标(如fieldLength
)仍然对结果有影响。因此,这并不等同于使用我在问题中假设的constant_score
的后期分析版本,但这足以满足我当前的需求。