elasticsearch学习笔记高级篇九多shard场景下相关度分数不准确问题

10次阅读

共计 979 个字符,预计需要花费 3 分钟才能阅读完成。

场景分析:

在某个 shard 中,有很多个 document 包含了 title 中有 java 这个关键字,比如说 10 个 doc 的 title 中包含了 java。

当一个搜索 title 包含 java 的请求到这个 shard 的时候,应该会这么计算 relevance score 相关度分数。TF/IDF 算法:

(1)在一个 document 的 title 中 java 出现了几次
(2)在所有的 document 的 title 中,java 出现了几次
(3)这个 document 的 title 的长度
由于 shard 只是一部分的 document,默认情况下就在 shard 本地计算 IDF。当有多个 shard 的时候,比如在一个 shard 中,只有一个 document title 包含 java,此时计算 shard local IDF 就会分数很高,导致相关度分数很高。这就有可能导致出现的搜索结果,似乎不太是你想要的结果。也许相关度很高的 doc 排在了后面,分数不高,而相关度很低的 doc 排在了前面,分数很高。

如何解决该问题

(1)在生产环境下,数据量大,尽可能实现均匀分配
数据量很大的话,在概率学的背景下,elasticsearch 都是在多个 shard 中均匀路由数据的,路由的时候根据_id,实现负载均衡。
比如说有 10 个 document,title 都包含 java, 一共有 5 个 shard,那么在概率学的背景下,如果负载均衡的话,其实每个 shard 都应该有 2 个 doc,title 包含 java。如果说数据分布均匀的话,其实就没有因为 IDF 不准确导致相关度分数不准确的问题。
(2)测试环境下,将索引的 primary shard 设置为 1 个
如果说只有一个 shard,那么当然所有的 document 都在这个 shard 里面,也就没有没有因为 IDF 不准确导致相关度分数不准确的问题。
(3)测试环境下,搜索附带 search_type=dfs_query_then_fetch 参数
带上 search_type=dfs_query_then_fetch 参数,就会将 local IDF 取出来计算 global IDF。也就是在计算一个 doc 的相关度分数的时候,就会将所有 shard 对 local IDF 计算一下,获取出来在本地进行 global IDF 分数的计算,此时会将所有 shard 的 doc 作为上下文来进行计算,可以保证准确性,但是生产环境下,不推荐这个参数,因为性能很差。

正文完
 0