关于elasticsearch搜索不精确问题
来源:互联网 发布:大酒神淘宝店 编辑:程序博客网 时间:2024/05/21 09:15
今天有个同事在使用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、在多个条件组合的搜索请求(比如布尔查询)中,可以指定某些条件的权重
这些方法都是要在明确搜索需求的情况下才能做到。
- 关于elasticsearch搜索不精确问题
- 关于BigDecimal 的不精确计算问题
- 关于float计算结果不精确问题
- 关于IjkVideoView或Android VideoView seekTo不精确问题
- 不精确数字比较问题
- freemarker的数字不精确问题
- 浮点数不精确的问题
- elasticsearch对double的query_string搜索问题
- Lucene/Solr/ElasticSearch搜索问题案例分析
- 分布式搜索elasticsearch 搜索结果排序不一致性问题
- elasticsearch 搜索
- ElasticSearch搜索
- Elasticsearch 搜索
- [ElasticSearch]搜索
- 关机充电电量显示不精确问题
- 彻底解决Javascript数字计算不精确的问题
- float double浮点数不精确问题
- 解决 js 加法,乘法不精确问题
- NETDEV 协议
- MTD是干什么的
- 你要去扩大交际圈,认识可能性,成为你自己
- 哪里栽倒,哪里爬起 —— 记一次糟糕的面试
- php GD库裁剪、加水印图片处理
- 关于elasticsearch搜索不精确问题
- NETDEV 协议 二
- sql server 2005附加失败解决办法
- Android命令行打包过程
- NETDEV 协议 三
- 模板优化二——添加模板依赖谁
- U-BOOT移植过程详解: UBOOT启动过程
- 2013学习总结
- 关于 speex 和 ogg 的一个没事找事儿的回答