Elasticsearch搜索结果返回不一致问题

一、背景

这周在使用Elasticsearch搜索的时候遇到一个,对于同一个搜索请求,会出现top50返回结果和排序不一致的问题。那么为什么会出现这样的问题?

后来通过百度和google,发现这是因为Elastcisearch的分布式搜索特性导致。Elasticsearch在搜索时,会循环的选择主分片和其副本中的一个来计算和返回搜索结果,而由于主分片和副本中相关统计信息的不同,从而导致了同一个搜索串的评分的不一致,进而导致排序不一样。而造成这种主分片和副本统计信息不一致的具体原因,是因为文档删除时造成的,具体可以参考官方给出的解释:https://www.elastic.co/guide/en/elasticsearch/reference/current/consistent-scoring.html

二、解决办法

针对上述问题,Elasticsearch官方也给出了解决方案(https://www.elastic.co/guide/en/elasticsearch/guide/2.x/_search_options.html#_preference),即在搜索时设置preference特性。如下:

SearchRequestBuilder builder = client.prepareSearch(offLin.index)        .setTypes(offLin.type)        .setQuery(queryBuilder)        .setFetchSource(fetchFields, null)        .setSize(limit)        .setPreference("_primary_first");

那么preference可以取哪些值,每个值的含义是什么呢,可以参考下面解释:

(1)randomizeacross shards:随机选择分片或其副本查询数据,es的默认方式。

(2)_local:优先在本地节点上的分片查询数据然后再去其他节点上的分片查询,本地节点没有IO问题但有可能造成负载不均问题。

(3)_primary:搜索只在主分片执行搜索请求,副本不参与搜索;性能会打折扣,达不到性能的水平扩展。

(4)_primary_first:优先在主分片执行,如果主分片挂掉,会在副本执行请求。

(5)_only_node:123 :只在123这个节点执行搜索。

(6)_prefer_node:123:搜索请求优先在节点123执行。

(7)_shards:1,2:搜索只在分片2、3执行,可以与_primary参数一起使用如:_shards:2,3;_primary

(8)随机字符串:指定一个随机字符串,可以保证同样的请求,被分配到同样的副本上面,从而保证同一请求结果的稳定性。我遇到的问题就可以使用这种方式,把搜索串的hash值作为随机字符串,这样可以保证同一个搜索条件的请求的返回结果和排序一致。

原文地址:https://www.cnblogs.com/junjiang3/p/9929864.html

时间: 2024-10-01 04:15:57

Elasticsearch搜索结果返回不一致问题的相关文章

ElasticSearch搜索介绍四

ElasticSearch搜索 最基础的搜索: curl -XGET http://localhost:9200/_search 返回的结果为: { "took": 2, "timed_out": false, "_shards": { "total": 16, "successful": 16, "failed": 0 }, "hits": { "tota

通过HTTP RESTful API 操作elasticsearch搜索数据

通过HTTP RESTful API 操作elasticsearch搜索数据

elasticsearch搜索提示

elasticsearch搜索提示(补全)接口需要新增suggest字段并设type为:completion,结合到scrapy,修改es_types.py文件: from datetime import datetime from elasticsearch_dsl import DocType, Date, Nested, Boolean, analyzer, InnerObjectWrapper, Completion, Keyword, Text, Integer from elasti

网站基于ElasticSearch搜索的优化笔记 PHP

基本情况就是,媒体.试题.分类,媒体可能有多个试题,一个试题可能有多个分类,分类为三级分类加上一个综合属性.通过试题名称.分类等搜索查询媒体. 现在的问题为,搜索结果不精确,部分搜索无结果,ES的数据结构不满足搜索需求.解决方案就是,重构ES数据结构,采用父子关系的方式,建立media和question两个type. 全程使用https://github.com/mobz/elasticsearch-head,这个进行ES的管理和查看,很方便. 从ES的说明可以看出,ES是面向文档,其实所有的数

ElasticSearch搜索底层基础原理总结

1._search结果分析 GET /_search   {   "took": 6,   "timed_out": false,   "_shards": {     "total": 6,     "successful": 6,     "failed": 0   },   "hits": {     "total": 10,     &qu

ElasticSearch搜索实例含高亮显示及搜索的特殊字符过滤

应用说明见代码注解. 1.简单搜索实例展示: public void search() throws IOException {        // 自定义集群结点名称        String clusterName = "elasticsearch_pudongping"; // 获取客户端        Client client = ESClient.initClient(clusterName); // 创建查询索引,参数productindex表示要查询的索引库为prod

elasticsearch搜索类型简介

简单搜索 GET请求非常简单--你能轻松获取你想要的文档.让我们来进一步尝试一些东西,比如简单的搜索! 我们尝试一个最简单的搜索全部员工的请求: GET /megacorp/employee/_search 接下来,让我们搜索姓氏中包含"jake"的员工.要做到这一点,我们将在命令行中使用轻量级的搜索方法.这种方法常被称作查询字符串(query string)搜索,因为我们像传递URL参数一样去传递查询语句: GET /megacorp/employee/_search?q=last_

Elasticsearch搜索之cross_fields分析

cross_fields类型采用了一种以词条为中心(Term-centric)的方法,这种方法和best_fields及most_fields采用的以字段为中心(Field-centric)的方法有很大的区别. 它将所有的字段视为一个大的字段,然后在任一字段中搜索每个词条. operator:operator设为了and,表示所有的词条都需要出现: minimum_should_match:表示文本匹配度,控制搜索精度,向下取整. 相比most_fields与best_fields,解释起来可能

Elasticsearch - 搜索类型与搜索位置

一.搜索类型: Elasticsearch同意用户选择其所希望的处理查询的方式. 由于存在一些不同的情形,对其使用不同的搜索类型才是合适的.为了控制查询的运行方式,我们能够在请求中使用search_type參数,以有下类型能够选择. 1.query_and_fetch:一般是最快也是最简单的搜索类型.查询语句在全部需检查的分片上并行运行,而且全部分片返回结果的规划为size參数的取值.因此.该类型返回的文档数目最大为size參数的取值与分片数目的乘积. 2.query_then_fetch:查询