我有2个文件,正在搜索关键字“Twitter”。假设这两个文档都是带有“标签”字段的博客文章。
文档A在“标记”字段中只有1个术语,它是“Twitter”。 文档B在“标签”字段中有100个术语,但其中3个是“Twitter”。
即使文档B的频率较高,弹性搜索也会为文档A提供较高的分数。但得分被“稀释”,因为它有更多的条款。如何为文档B提供更高的分数,因为它具有更高的搜索词频率?
我知道ElasticSearch / Lucene会根据文档中的术语数执行一些规范化。如何禁用此规范化,以便文档B获得更高的分数?
答案 0 :(得分:3)
正如另一个答案所说,看一下你在一个分片上是否有相同的结果会很有趣。我认为你会这样做,这取决于标签字段的规范,在使用tf / idf相似度(默认)计算得分时会考虑这些规范。
事实上,lucene确实考虑了术语频率,换句话说术语出现在字段中的次数(在您的情况下为1或3),以及反向文档频率,换句话说,术语是如何在索引中频繁出现,以便将其与查询中的其他术语进行比较(在您的情况下,如果您搜索单个术语,则没有任何区别)。
但还有另一个称为规范的因素,奖励较短的字段并考虑最终的索引时间提升,可以是每个字段(在映射中)甚至是每个文档。您可以验证规范是您的结果启用搜索请求中的解释选项并查看解释输出的原因。
我认为第一个文档只包含该标记的事实使得包含该标记的其他标记多次重要,但同时也包含很多标记。如果您不喜欢此行为,则可以在映射中禁用标记字段的规范。如果字段为"index":"analyzed"
(默认值),则应默认启用它。如果您不希望分析您的代码字段(通常有意义但取决于您的数据和域),您可以切换到"index":"not_analyzed"
,或者在代码的映射中添加"omit_norms": true
选项字段。
答案 1 :(得分:0)
文档是否在不同的分片上找到?来自弹性搜索文档:
“当在特定分片上执行查询时,它不考虑来自其他分片的术语频率和其他搜索引擎信息。如果我们想要支持准确的分级,我们需要首先对所有分区执行查询分片并收集相关的术语频率,然后在此基础上执行查询。“
解决方案是指定搜索类型。使用dfs_query_and_fetch搜索类型来执行初始分散阶段,该阶段将计算分布式术语频率,以获得更准确的评分。
您可以阅读更多here。