Elasticsearch 排序与评分问题

遇到的问题

我们es中保存了商户所有的商品信息,在一个下拉框中需要能多维度的定位到商品信息(如输入商品名+规格等等),因为涉及字段较多,所以我们还为每个字段单独设置了权重,且在使用should + multi_match 时指定了minimum_should_match(最小的匹配数量),以此来避免出现无关数据。
测试发现我们输入与第一项匹配值与预想有一定差距,比如下图:
在这里插入图片描述
我们输入了全脂牛奶15ml,可是预想的15ml排到了第三行,一个50ml排到了第一行。我们在不停调整权重后也不能解决。

问题查询思路

没办法我们只能将第一行数据和第三行数据的评分细则拿出来,

post /索引名/_search/_explain/数据id

获取到两个数据的具体评分数据

在这里我们看到一个有意思的问题,在计算相同字段的相同数据时,居然评分还不一致,比如:商品名字段中的“全脂”
第一行数据:
在这里插入图片描述
目标行数据
在这里插入图片描述
不是啊,咱两都叫“全脂”你的全脂为啥还尊贵点???

看了下这里在计算IDF,n是包含关键词的文档数。

简单介绍下es的(TF/IDF模型)评分机制:

  • TF:TF(Term Frequency),即词频,表示词条在文本中出现的频率。考虑一篇文档得分的首要方式,是查看一个词条在当前文档(注意IDF统计的范围是所有文档)中出现的次数,比如某篇文章围绕ES的打分展开的,那么文章中肯定会多次出现相关字眼,当查询时,我们认为该篇文档更符合,所以这篇文档的得分会更高。TF的值通常会被归一化,一般是词频除以文章总词数,以防止它偏向长的文件(同一个词语在长文件里可能会比短文件有更高的词频,而不管该词语重要与否)。

  • IDF:IDF(Inverse Document Frequency),即逆文档频率,反应了一个词在所有文档中出现的频率,如果一个词在很多的文本中出现,那么它的IDF值应该低。而反过来如果一个词在比较少的文本中出现,那么它的IDF值应该高。

简单来说就是:一个词语在某一篇文档中出现次数越多,同时在所有文档中出现次数越少,那么该文档越能与其它文章区分开来,评分就会越高。

那就更奇怪了相同关键词,在同一个es中,出现次数还能不一样???

查了半天终于发现了端倪,我们在创建es索引的时候指定了数据分片,数据可能被分到了不同的分片中!!!

POST /索引名/_search?preference=_shards:分片号(1-N)

目标行在1分片中,里面文本“全脂”较多
在这里插入图片描述
第一行数据在分片2中,里面文本“全脂”较少
在这里插入图片描述
所以在计算idf(逆文档频率)时第一行数据集分数更高.

知道问题后,那就简单了,那有没有分片聚集查询呢?有,但官方不建议,我们做分片就是为了数据分散提升查询效率,聚集后会导致查询效率变慢
官网说明:search_type说明
在这里插入图片描述
那我们试试吧

POST /索引名/_search?search_type=dfs_query_then_fetch

分数排序确实变了,但…变了后还不是预期模样
在这里插入图片描述
现在分数一致了,但我们想要的到了第二行。那么在分数一致时是如何排序的呢?问了问万能的gpt
在这里插入图片描述

如何解决

既然修改权重,相同分数等无法解决,我们就只能按照业务来自定义评分规则
这里推荐几篇大佬的参考文档
ElasticSearch自定义评分
Elasticsearch自定义评分的N种方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值