笔记三十六:分页与遍历 From, Size,Search After & Scorll API

From / Size

  • 默认情况下,查询按照相关度算分排序,返回前10条记录
  • 容易理解的分页方案
    • From : 开始位置
    • Size:期望获取文档的总数

分布式系统中深度分页的问题

  • ES 天生就是分布式,查询信息,但是数据分别保存在多个分片,多台机器,ES天生就需要满足排序的需要(按照相关性算分)
  • 当一个查询:From = 990 ,Size =10
    • 会在每个分片上先获取1000个文档。然后,通过Coordinating Node 聚合所有结果。最后在通过排序选取前1000个文档
    • 页数越深,占用内容越多。为了避免深度分页带来的内存开销。ES有个设定,默认限定到10000个文档

ES 笔记三十六:分页与遍历

POST tmdb/_search
{
  "from": 10000,
  "size": 1,
  "query": {
    "match_all": {}
  }
}
//

Search After 避免深度分页的问题

  • 避免深度分页的性能问题,可以实时获取下一页文档信息
    • 不支持指定页数(From)
    • 不能往下翻
  • 第一步搜索需要指定sort,并且保证值是唯一的(可以通过加入_id保证唯一性)
  • 然后使用上一次,最后一个文档的sort值进行查询
    POST users/_doc
    {"name":"user1","age":10}
    POST users/_doc
    {"name":"user2","age":11}
    POST users/_doc
    {"name":"user2","age":12}
    POST users/_doc
    {"name":"user2","age":13}
    POST users/_count
    POST users/_search
    {
      "size": 1,
      "query": {
          "match_all": {}
      },
      "sort": [
          {"age": "desc"} ,
          {"_id": "asc"}    
      ]
    }
    //返回
    {
    "took" : 0,
    "timed_out" : false,
    "_shards" : {
      "total" : 1,
      "successful" : 1,
      "skipped" : 0,
      "failed" : 0
    },
    "hits" : {
      "total" : {
        "value" : 5,
        "relation" : "eq"
      },
      "max_score" : null,
      "hits" : [
        {
          "_index" : "users",
          "_type" : "_doc",
          "_id" : "I5aMPW8Bb23XqE-8Pu1n",
          "_score" : null,
          "_source" : {
            "name" : "user2",
            "age" : 13
          },
          "sort" : [
            13,
            "I5aMPW8Bb23XqE-8Pu1n"
          ]
        }
      ]
    }
    }
    POST users/_search
    {
      "size": 1,
      "query": {
          "match_all": {}
      },
      "search_after":
           [
            10,
            "H5aMPW8Bb23XqE-8IO1c"
          ],
      "sort": [
          {"age": "desc"} ,
          {"_id": "asc"}    
      ]
    }

    Search After 是如何解决深度分页的问题

  • 假设Size是10
  • 当查询990 -100
  • 通过唯一排序值定位,将每次要处理的文档都控制在10

Scoll API

  • 创建一个快照,有新的数据写入以后,无法被查找
  • 每次查询后,输入上一次的Sroll Id
    DELETE users
    POST users/_doc
    {"name":"user1","age":10}
    POST users/_doc
    {"name":"user2","age":20}
    POST users/_doc
    {"name":"user3","age":30}
    POST users/_doc
    {"name":"user4","age":40}
    POST /users/_search?scroll=5m
    {
      "size": 1,
      "query": {
          "match_all" : {
          }
      }
    }
    POST /_search/scroll
    {
      "scroll" : "1m",
      "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAf3oEWQlQzZnpzdzlRdEdIUDFiRndaQU5BZw=="
    }

不同的搜索类型和使用场景

  • Regular
    • 需要实时获取顶部的部分文档。例如查询最新的订单
  • Scorll
    • 需要全部文档,例如导出全部数据
  • Pagination
    • From 和 Size
    • 如何需要深度分页,则选用Search After
本作品采用《CC 协议》,转载必须注明作者和本文链接
快乐就是解决一个又一个的问题!
CrazyZard
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!