Elasticsearch,同样的检索条件查询语句,结果得分不同

问题

  • 问题的现象是这样的,搜索结果有17条,分页参数为10,查询第二页时,有时候出现5条结果,有时候出现10条结果,就不是正确的7条
  • 使用search_after搜索,先得到sortValue再请求第二页数据,发现sortValue的值里score每次都有微妙不同

处理

原因探究

  • search_after搜索,对于第一页以外的搜索,都是两次搜索(超过10000条会触发多次搜索),由于两次搜索请求对同一条数据的得分不同,导致根据得分search_after搜索结果出现错误
  • scroll搜索,是一次性把结果请求到,缓存起来,这期间的数据变动不会影响分页效果,所以不适用于实时搜索
  • 不同于scroll搜索,search_after搜索都是实时查询的,虽然两次查询间隔非常短,但索引库数据的变动,也可能会影响到请求的得分
  • 之前为了搜索得分问题,通过设置search_typedfs_query_then_fetch排除了不同分片的干扰,通过使用constant_score搜索方法排除查询无关字段的干扰
  • 但是现在搜索条件相同,得分还是有微妙不同
  • 根据百度搜索到Elasticsearch中文站的一条问答elasticsearch多次查询得分不一致,解释说,参与最后统分的不是全集,而是每个 shard 取的 topN,这就可能造成一定偶然性
  • 除了不同分片对得分的影响,使用副本也会产生对评分的影响
  • 我们使用的是3个节点的ES集群,索引设置为3分片1副本,数据实时变动时,不同分片和副本里的数据是不同的,搜索时查询到不同分片得分可能就不太一样

解决

  • 为了解决这种影响,使用setPreference指定优先主分片.setPreference("_primary_first"),但这并不保证问题不再发生,只是大概率不会发生,修改部署后确实解决了当前遇到的问题
searchResponse = searchRequestBuilder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH).setPreference("_primary_first").get();
  • 对于preference的设值,有5种
  • _primary : 指查询只在主分片中查询
  • _primary_first : 指查询会先在主分片中查询,如果主分片找不到(挂了),就会在副本中查询
  • _local : 指查询操作会优先在本地节点有的分片中查询,没有的话再在其它节点查询
  • _only_node : 指在指定id的节点里面进行查询,如果该节点只有要查询索引的部分分片,就只在这部分分片中查找,所以查询结果可能不完整。如_only_node:123在节点id为123的节点中查询
  • Custom (string) value : 用户自定义值,指在参数cluster.routing.allocation.awareness.attributes指定的值
  • 我们采用了优先主分片的查询方式
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坚持是一种态度

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值