Elasticsearch——search相关知识

381 阅读4分钟
  1. timeout机制

    如果查询我们需要的所有数据时间很长,可以先返回查询到的一部分数据,就需要timeout机制。

    timeout机制,指定每个shard,只能在timeout时间范围内,将搜索到的部分数据(也可能全部搜索到),直接返回给client程序,而不是等到所有的数据都搜索出来之后再返回。

    默认情况下,没有timeout机制。

  1. 代码示例

    GET test_index/test_type/_search?timeout=10ms
  1. 分页搜索

    语法:

    1GET test_index/test_type/_search?from=0&size=6
  2. deep paging

    Elasticsearch 的分页查询在数据小于50000条还是不错的,默认每页10条数据,也就是在5000页以内,但时当数据超过50000条的话,就会出现深分页问题,也就是 deep paging。

    举个例子,总共有60000条数据,现在有3个primary shard,每个shard上分20000条,每页是10条数据,我们要搜索第1000页,实际上要拿到的是10001-10010,es会从3个shard上每个都拿10010条数据,然后对着30030条数据排序,取第10001-10010条数据。

    这样当数据很大,搜索过深的时候,在协调节点即 cordinate node 上会保存大量的数据,并且还要进行排序,排序之后,再取出我们需要的那一页。这个过程,耗费网络带宽,内存和CPU,影响性能。

  3. 解决 deep paging 问题

    为了解决上面的问题,elasticsearch提出了一个scroll滚动的方式,这个滚动的方式原理就是通过每次查询后,返回一个scroll_id。根据这个scroll_id 进行下一页的查询。可以把这个scroll_id理解为通常关系型数据库中的游标。但是,这种scroll方式的缺点是不能够进行反复查询,也就是说,只能进行下一页,不能进行上一页。

  1. scroll 使用

    使用scoll滚动搜索,可以先搜索一批数据,然后下次再搜索一批数据,以此类推,直到搜索出全部的数据来。

    scoll搜索会在第一次搜索的时候,保存一个当时的视图快照,之后只会基于该旧的视图快照提供数据搜索,如果这个期间数据变更,是不会让用户看到的
    采用基于_doc进行排序的方式,性能较高

    scoll,看起来挺像分页的,但是其实使用场景不一样。分页主要是用来一页一页搜索,给用户看的;scoll主要是用来一批一批检索数据,让系统进行处理的

    查询示例:

    1GET test_index/test_type/_search?scroll=1m
    2{
    3  "query": {
    4    "match_all": {}
    5  },
    6  "size"3
    7}

    查询所有数据,一次返回三条数据,返回结果

     1{
    2  "_scroll_id""DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAEq3Fk13bkpoWFBFUWIyQ0VxR1hhM1Y0a2cAAAAAAABKuxZNd25KaFhQRVFiMkNFcUdYYTNWNGtnAAAAAAAASroWTXduSmhYUEVRYjJDRXFHWGEzVjRrZwAAAAAAAEq5Fk13bkpoWFBFUWIyQ0VxR1hhM1Y0a2cAAAAAAABKuBZNd25KaFhQRVFiMkNFcUdYYTNWNGtn",
    3  "took"0,
    4  "timed_out"false,
    5  "_shards": {
    6    "total"5,
    7    "successful"5,
    8    "skipped"0,
    9    "failed"0
    10  },
    11  "hits": {
    12    "total"9,
    13    "max_score"1,
    14    "hits": [
    15      {
    16        "_index""test_index",
    17        "_type""test_type",
    18        "_id""AWjxCRPzFjHDLA-cm71O",
    19        "_score"1,
    20        "_source": {
    21          "test_field""create id by es"
    22        }
    23      },
    24      {
    25        "_index""test_index",
    26        "_type""test_type",
    27        "_id""5",
    28        "_score"1,
    29        "_source": {
    30          "test_field""external client2 changed"
    31        }
    32      },
    33      {
    34        "_index""test_index",
    35        "_type""test_type",
    36        "_id""8",
    37        "_score"1,
    38        "_source": {
    39          "test_field""create id 6"
    40        }
    41      }
    42    ]
    43  }
    44}

    获得的结果会有一个scoll_id,下一次再发送scoll请求的时候,必须带上这个scoll_id

    1GET _search/scroll
    2{
    3  "scroll""1m",
    4  "scroll_id""DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAEs0Fk13bkpoWFBFUWIyQ0VxR1hhM1Y0a2cAAAAAAABLOBZNd25KaFhQRVFiMkNFcUdYYTNWNGtnAAAAAAAASzYWTXduSmhYUEVRYjJDRXFHWGEzVjRrZwAAAAAAAEs1Fk13bkpoWFBFUWIyQ0VxR1hhM1Y0a2cAAAAAAABLNxZNd25KaFhQRVFiMkNFcUdYYTNWNGtn"
    5}