[英]Elasticsearch: Search over most frequent matches / terms without TF or IDF adjustment
我们正在研究基于文本的搜索(通过著名的“在此处键入您的搜索”输入框),它计算多个字段的分数并显示最佳结果。 它基本上是一个布尔查询,在许多不同的字段上混合了“术语”和“匹配”(使用模糊度、ngram、edge-ngrams 等)。
我们希望最好的结果(最“受欢迎”)首先出现(从而获得最高分)。 然而,lucene 的默认 TF-IDF 算法给了我们完全相反的结果。 图像您寻找存在于 30% 的所有索引条目中的供应商。 它将具有非常高的 IDF 并且排名非常低。 我们只想要完全相反的 - 给我们最频繁的第一个(!)。
尝试使用“cross-field”查询并没有成功,因为我们想将不同的查询类型与“bool”结合起来。
现在,我们“发现”的是,使用 k1=0 和 b=0 几乎(?)的 Okapi BM25 的行为就像忽略了 TF(词频)和 IDF(逆文档频率)的相似性。 然而,我们不确定这是否真的是要走的路。
你能给我们一些反馈吗?
这是要走的路还是对于我们的“问题”是否有更好的等待被发现?
我试着让我的问题更清楚(对不起,任何混淆):
假设我们有一个汽车索引......
{id: 1, vendor: Opel, model: Astra, engine: 90hp gasoline}
{id: 2, vendor: Opel, model: Astra, engine: 100hp diesel}
{id: 3, vendor: Opel, model: Astra, engine: 120hp gasoline}
{id: 4, vendor: Chevrolet, model: Astro, engine: 120hp gasoline}
我们对当前用户输入的“astr”进行“全文搜索”
使用“edge ngram”分析器 {min:2, max:10} 分析所有字段(供应商、模型 + 引擎)以支持前缀搜索。
输入“astr”将匹配所有条目 #1 - #4(它是“Astra”和“Astro”的开头,所以所有条目都将包含一个边 ngram 匹配)
“Astr a ”的 IDF 是 log(4/3) ~= 0,287
“Astr o ”的 IDF 是 log(4/1) ~= 1,386
因此,由于 IDF,#4 的排名会更好
然而,我们想要恰恰相反:“更频繁”(=“更受欢迎”)的汽车应该排名更高。
注意:“跨字段”查询是不够的,因为我们将几个不同的查询(模糊、边缘 ngram、原始)合并到一个大的 bool 查询中
听起来您想遵循以下一般流程:
解决方案 1 (最灵活,性能最低)
您可以使用供应商字段上的术语聚合来获取 #2 的信息。
然后您可以使用必要的派生提升重新查询(花费第二次往返)
或者
解决方案 2 (最不灵活,性能最高)
如果您满足于让vendor popularity
胜过_score
,您可以执行以下操作:
那么聚合结果中的[astr]
查询结果将如下所示:
[Opel bucket]
Astra 90hp
Astra 100hp diesel
Astra 120hp
Ascona 144hp (if you had fuzziness 2)
Ascona 230hp (if you had fuzziness 2)
[Chevrolet bucket]
Astro 120hp
Alero 140hp (if you had fuzziness 2)
如果您想使用文档频率来提高结果,请尝试在function_score
子句中滚动您自己的script_score函数。 您可以通过term statistics访问评分函数中某个术语的文档频率。
您可能会发现这种方法的一个意想不到的后果是,如果您没有明确地将它们作为停用词清除掉,诸如Corp
、 Solutions
、 Computer
、 Inc
等常见/通用术语将对您的分数产生巨大影响。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.