Elasticsearch搭配Searchkick查询返回结果评分相同异常问题求助
问题原因
当前返回的两条记录得分一致是因为你开启了word_middle中缀匹配规则,Krog作为Krogness的子串可被中缀匹配命中,默认的中缀匹配逻辑没有对完整匹配、更长匹配的结果做额外加权,且你已经将分片数调整为1排除了分片间得分归一化差异的影响,所以最终得分完全一致。
解决方案
方案1:开启Searchkick内置精确匹配加权(推荐)
Searchkick自带boost_exact参数,开启后会自动为完全匹配搜索词的结果叠加额外权重,只需在查询参数中新增对应配置即可:
Grave.search "Krogness", fields: ["name^10", "plot_number"], where: {grave_status: [:accepted, :claimed], hidden: false}, operator: :or, page: "1", per_page: 30, misspellings: false, boost_exact: true, # 新增此行 debug: true
方案2:手动添加精确字段权重
Searchkick默认会为每个文本字段生成.exact后缀的精确匹配字段,你可以将该字段加入查询列表并设置高于普通分词字段的权重:
fields: ["name.exact^20", "name^10", "plot_number"]
权重数值可根据业务排序需求调整,确保精确匹配的权重高于普通分词字段即可。
方案3:调整匹配规则(如无需中缀匹配)
如果你的业务场景不需要查询字段中间位置的子串,只需要前缀匹配,可以将模型配置中的word_middle改为word_start:
searchkick word_start: %i[name plot_number], callbacks: :async, settings: {number_of_shards: 1}
修改后需要执行Grave.reindex重建索引,此时只有以搜索词为前缀的内容会被命中,不会出现短子串匹配长词的情况。
方案4:自定义得分规则
如果以上方案不满足需求,可通过custom_score参数自定义得分逻辑,例如为包含完整搜索词的结果额外加权:
Grave.search "Krogness", # 其余原有参数不变 custom_score: "doc['name.keyword'].value.contains(params[:q]) ? _score * 2 : _score"
内容的提问来源于stack exchange,提问作者Akshay Parekh
相关产品推荐
相关产品推荐

