关于elasticsearch搜索不精确问题

        今天有个同事在使用elasticsearch搜索“李四”的时候,跟我说搜索不准切,为什么在username字段里出现“李四君”的排前面,而“李四”的排在后面呢,我也觉得奇怪,按照lucene的评分公式,的确应该是“李四”评分最高。

        后来使用elasticsearch的explain功能对每个hit评分的详细情况进行分析,结果发现,“李四君”所在hit的maxDocs=6,而其他的hit全都是maxDocs=2,导致idf计算的差异,其他关于评分公式的参数都是一样的,比如tf。

        查阅lucene详细评分公式以及lucene原理和代码解析,idf的值越小,评分越大,也就是在termDocFreq一致的情况下,maxDocs越大评分越大。

        但是我又想到elasticsearch的每个分片的都是负载均衡的,各个评分的docs数据最多相差1,因为我们没有干预建索引时候的routing,数据都是按照elasticsearch原本的分发docs的规则,我去查看“李四君”所在的分片发现分片的maxDocs=6,numDocs=3,deleteDocs=3,这样一来问题就清楚了,原因在于maxDocs包括了deleteDocs

        那么为什么lucene不使用numDocs而要使用maxDocs呢?

        我想这可能跟lucene的索引结构有关吧,因为lucene的删除文档是逻辑删除,所有删除文档的docid都在segment.del段文件或者在lucene的Segments文件中,只有在索引优化以后才会做物理删除操作,如果使用numDocs那么termDocFreq也要减去其中是删除文档的数目才对,这样会使评分计算复杂吧。

        在对索引进行optimize后,虽然“李四君”的maxDocs=3比“李四”的maxDocs大,但是“李四”的tf评分大,综合计算“李四”排在了前面。

        这让我不禁想到以前碰到的类似的问题,有两个文档,其中一个文档“高腾”出现一次,字段也少,字段的内容也少,另外一个文档“高腾”出现多次,字段多,字段内容多,结果搜索的结果是“高腾”出现一次的排在前面,那是什么原因呢?

        原因在于tf的计算,并不是说term出现的频度越高,评分越大,计算tf,是按照term在doc出现的比例,比例越高,term对于这个doc重要性也高,tf的值也越大。

        按照这样的想法,我对这两个文档进行tf计算,罗列出所有的tokens,发现“高腾”出现一次的tf值大。

        讲到这里,顺便提下灵活使用lucene的评分机制来提高搜索的精确度。

       1、建索引的时候详细制定某些字段或者某些文档的boost,这些标准化因子就存储在段文件segment.nrm中

       2、搜索的时候指定某些字段的权重

       3、在多个条件组合的搜索请求(比如布尔查询)中,可以指定某些条件的权重

      这些方法都是要在明确搜索需求的情况下才能做到。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值