潍坊论坛:【Elasticsearch学习】文档搜索全过程

admin 8个月前 (05-17) 科技 66 1

  在ES执行漫衍式搜索时,漫衍式搜索操作需要涣散到所有相关分片,若一个索引有3个主分片,每个主分片有一个副本分片,那么搜索请求会在这6个分片中随机选择3个分片,这3个分片有可能是主分片也可能是副本分片,然后网络所有分片的查询效果。以是ES的搜索历程分为两个阶段,Query阶段和Fetch阶段;ES有两种搜索类型:query_then_fetch,dfs_query_then_fetch。

  1.Query阶段

  1)转发请求。在Query阶段客户端向ES节点发送,搜索请求,Coordinate节点接受客户端搜索请求,Coordinate节点卖力剖析搜索请求,并在索引的所有主副本分片中随机选择分片,而且发送给分片所在的数据节点。

  2)执行查询。接收到查询请求的数据节点执行查询操作,并对查询效果举行排序,每个节点都市凭据请求中参数返回from+size个排序后的文档Id和排序值给Coordinate节点。

  2.Fetch阶段

  1)重排序。Coordinate节点收到数据节点返回的数据后,会根据返回的排序值对从所有分片取回的值重新举行排序,最终只选取客户端需要的from+size个文档的Id。

  2)获取文档数据。Coordinate节点凭据选取的文档的Id,到响应的分片获取详细的文档数据,最终将查询到的效果返回给客户端。

查询效果解读:

{
    "took":3, 查询所用的毫秒数
    "timed_out":false, 是否有分片超时,即是否只返回了部门效果
    "_shards":{
        "total":1, 一共查询了若干分片
        "successful":1, 若干分片乐成返回
        "skipped":0,跳过了若干分片
        "failed":0  若干分片查询失败
    },
    "hits":{  
        "total":{ 
            "value":1, 该搜索请求中返回的所有匹配的数目
            "relation":"eq" 文档与搜索值的关系,eq示意相等
        },
        "max_score":8.044733, 返回效果中文档的最大得分
        "hits":[  查询效果的文档数组
            {
                "_index":"kibana_sample_data_ecommerce", 查询的索引
                "_type":"_doc",  查询的类型
                "_id":"4X-j7XEB-r_IFm6PISqV", 返回文档的主键
                "_score":8.044733,  返回文档的评分
                "_source":{  文档的原始内容
                    "currency":"EUR",
                    "customer_first_name":"Eddie",
                    "customer_full_name":"Eddie Underwood",
                    "customer_gender":"MALE"
                    ......
                }
            }
        ]
    }
}    

 Query Then Fetch潜在的问题

1.深度分页

  ES索引数据漫衍在多个分片上,在查询时,每个分片都要查询from+size个文档,Coordinate节点会聚合所有的效果,以是Coordinate节点要处置查询分片数*(from+size)个文档纪录,对这些纪录举行重新排序,需要的size个文档,from+size的值越大占用内存越多,称为深度分页问题,ES默认限制分页的深度不能超过10000条,可通过max_result_window设置。

  深度分页解决办法:

  1)Search After

  可以使用Search After制止深度分页的性能问题,实时获取下一页的文档信息,search_after凭据上一页最后一个文档的sort值来查询下一页,而且当索引数据有变化时,也可以同步被查到,是一个实时查询的方式。

  例:http://127.0.0.1:9200/kibana_sample_data_ecommerce/_search

    查询参数:在使用Search_After查询时,第一步查询时需要指定sort字段,而且该sort字段的排序效果是唯一的,建议使用_id来举行sort,可以指定多个sort字段。

{
  "size": 1,
  "query": {
    "match": {
      "currency": "EUR"
    }
  },
  "sort": [
    {
      "order_id": {
        "order": "asc"
      }
    }
  ]
}

   返回中可以看到第一页查询返回的sort值,查询下一页时使用该sort值举行文档的定位,尔后每个查询都市返回一个sort值,供下一页举行定位使用。

"sort": [
     "550375"
]

  下一页查询:

{
  "size": 1,
  "query": {
    "match": {
      "currency": "EUR"
    }
  },
  "search_after": [
    550375
  ],
  "sort": [
    {
      "order_id": {
        "order": "asc"
      }
    }
  ]
}

  Search_After存在的限制:

    a.不能指定from值,即不能想翻到哪一页就直接跳转到那一页,只能一页一页根据顺序翻;

    b.只能往后翻页,不能往前翻页。

  2)Scroll API

  scroll api可以用于从单个搜索请求中检索大量的效果,其原理是确立索引在某个时间点的快照,当快照确立后,之后的每次搜索都市在该快照上举行,对索引的所有新增操作都市被忽略,索引Scroll适合于处置大量数据,然则不能保证数据的实时性。

  POST http://127.0.0.1:9200/kibana_sample_data_ecommerce/_search?scroll=1m

  首次查询时指定scroll=5m,示意当前搜索过时时间为5分钟,即查询效果在搜到下一次请求之前会保留多次时间,scroll的值不需要长到把整个快照的数据都处置完,只需保证下一次搜索请求到来之前能处置完前一批查询效果即可。

{
    "size": 2,
    "query": {
        "match" : {
            "currency" : "EUR"
        }
    }
}

  返回中可以看到_scroll_id,total.value,scroll_id用于获取下一批的查询效果,total.value示意该查询有总共若干个效果。

{
   "_scroll_id":"DXF1ZXJ5QW5kRmV0Y2gBAAAAAAABAGUWdks0dUtFMHZTYmE1Rl9ucGp5X0hoUQ==", 
  "took": 1,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 4675,
            "relation": "eq"
        },
   }
}

  下一页:

  http://127.0.0.1:9200/_search/scroll

  下一页查询的时刻不用指定索引和查询参数,只需要指定scroll时间和上一次请求返回的scroll_id,由于快照已经建好,只需要在快照上往下翻页即可。每次执行该请求都市往下举行翻页,直到查询的效果为空。

{
  "scroll":"5m",
 "scroll_id":"DXF1ZXJ5QW5kRmV0Y2gBAAAAAAABAGUWdks0dUtFMHZTYmE1Rl9ucGp5X0hoUQ=="
}

  Scroll API存在的限制:当快照确立后,对索引有新的操作时,无法被查询到,以是不适合做实时查询。

差别查询的使用场景

  一样平常查询:需要获取顶部的部门文档,查询索引最新的数据。

  全量查询:使用scroll,当需要导出所有数据,且对数据的实时性要求不高时。

  分页查询:使用from+size,当from+size过大时,使用search after。

2.相关度评分禁绝问题

  当搜索请求在多个shard举行数据查找时,每个分片都市基于自己分片上的文档数据举行相关度的盘算,盘算方式为TD/IDF,

  TF:词频,示意词条在一个文档中泛起的频率;IDF:逆文档频率,log(全本文档数/词条在所有文档中泛起的次数),示意该term在所有文档中泛起的频率;若是查询词条在某一个文档中泛起的频率(即TF)高,在所有文档中泛起的频率低(即IDF)低,则解释该文档的相关性高。

  每个分片盘算IDF的时刻只会基于自己分片上的数据举行盘算,并不会包罗其他分片上的数据,以是这样会导致相关性评分禁绝的情形;特别在文档总数很少情形下,主分片数越多,相关性算分会越禁绝。

  解决相关度评分禁绝问题的方式:

  1)合理设置分片数目,保证数据平均漫衍。

   当数据量不大时,可以思量仅设置一个主分数;当数据量较大时,保证文档平均的漫衍在各个分片上。ES提供了routing_partition_size参数,routing_partition_size越大,数据的漫衍越平均(【Elasticsearch学习】之一图读懂文档索引全历程 中有提及)。

  2)使用dfs_query_then_fetch

  在搜索时,指定搜索的类型search_type=dfs_query_the_fetch,在搜索的时刻,每个分片会把每个分片的TF和IDF举行搜集,然后综合所有的数据举行一次完整的相关性评分盘算,然则一样平常不推荐,由于这样会花费较多的CPU和内存。

 

 

,

Sunbet

www.ipvps.cn信誉来自于每一位客户的口碑,Sunbet携手江苏安腾科技有限公将致力服务好每位Sunbet会员。!

allbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:潍坊论坛:【Elasticsearch学习】文档搜索全过程

网友评论

  • (*)

最新评论

标签列表

    文章归档

      站点信息

      • 文章总数:808
      • 页面总数:0
      • 分类总数:8
      • 标签总数:1156
      • 评论总数:619
      • 浏览总数:31745