1.  From + size 查询优缺点及适用场景

From + size 查询优点

  • 支持随机翻页。

From + size 查询缺点

  • 受制于 max_result_window 设置,不能无限制翻页。
  • 存在深度翻页问题,越往后翻页越慢。

From + size 查询适用场景

第一:非常适合小型数据集或者大数据集返回 Top N(N <= 10000)结果集的业务场景。

第二:类似主流 PC 搜索引擎(谷歌、bing、百度、360、sogou等)支持随机跳转分页的业务场景。

语句

GET /xxxx/_search
{
  "sort": [
    {
      "id.keyword": {
        "order": "asc"
      }
    }
  ],
  "_source": ["id","name"], 
  "from": 0,  ---从0开始. 不是1
  "size": 5
}

第二页
GET /xxxx/_search
{
  "sort": [
    {
      "id.keyword": {
        "order": "asc"
      }
    }
  ],
  "_source": ["id","name"], 
  "from": 5,   ---第二页 0+5=5, 第三页5+5=10
  "size": 5
}

from:未指定,默认值是 0,注意不是1,代表当前页返回数据的起始值。 
size:未指定,默认值是 10,代表当前页返回数据的条数。

默认的深度分页限制是1万,from + size 大于 10000会报错,如何处理

默认的深度分页限制是1万,from + size 大于 10000会报错,可以通过index.max_result_window参数进行修改。

在索引中增加配置
PUT mr_zcy/_settings
{
  "index":{
    "max_result_window":200000
  }
}

from=10000 就不报错了

GET /mr_zcy/_search
{
  "sort": [
   ],
  
  "from": 10000,
  "size": 2
}

2. search_after 查询优缺点及适用场景

使用search_after必须要设置from=0

search_after 优点

  • 不严格受制于 max_result_window,可以无限制往后翻页。

ps:不严格含义:单次请求值不能超过 max_result_window;但总翻页结果集可以超过。

search_after 缺点

  • 只支持向后翻页,不支持随机翻页。

search_after 适用场景

  • 类似:今日头条分页搜索 

不支持随机翻页,更适合手机端应用的场景。

语句

第一页
GET /mr_zcy/_search
{
  "sort": [
   
    {
      "id.keyword": {
        "order": "desc"
      }
    }
  ],
  "_source": [
    "id",
    "updateTime"
  ],
  
  "size": 6
}
第二页
GET /mr_zcy/_search
{
  "sort": [
   
    {
      "id.keyword": {
        "order": "desc"
      }
    }
  ],
  "_source": [
    "id",
    "updateTime"
  ],
  "size": 6,
  "search_after": [
          745,
          "2022-07-28 14:18:46"
         
        ]
}

--
search_after 中是 第一次查询结果里面 
"sort" : [
          745,
          "2022-07-28 14:18:46"
        ]

在返回的结果中,最后一个文档有类似下面的数据,由于我们排序用的是两个字段,返回的是两个值

"sort" : [
  1614561419000,
  "6FxZJXgBE6QbUWetnarH"
]

Scroll 遍历查询优缺点及适用场景

from+size查询在10000-50000条数据(1000到5000页)以内的时候还是可以的,但是如果数据过多的话,就会出现深分页问题。

为了解决上面的问题,elasticsearch提出了一个scroll滚动的方式。

scroll 类似于sql中的cursor,使用scroll,每次只能获取一页的内容,然后会返回一个scroll_id。根据返回的这个scroll_id可以不断地获取下一页的内容,所以scroll并不适用于有跳页的情景。

    scroll 查询优点

  • 支持全量遍历。

ps:单次遍历的 size 值也不能超过 max_result_window 大小。

    scroll 查询缺点

  • 响应时间非实时。
  • 保留上下文需要足够的堆内存空间。

scroll 查询适用场景

  • 全量或数据量很大时遍历结果数据,而非分页查询。
  • 官方文档强调:不再建议使用scroll API进行深度分页。如果要分页检索超过 Top 10,000+ 结果时,推荐使用:PIT + search_after。
  • 数据导出功能

从 Scroll 请求返回的结果反映了发出初始搜索请求时索引的状态,类似在那一个时刻做了快照。随后对文档的更改(写入、更新或删除)只会影响以后的搜索请求。

第一次
GET project_base_info/_search?scroll=4m
{
  
  "query": {
   ....
  },
  "sort": [
    {
      "alarmNum": {
        "order": "asc",
         "missing": 0
      }
    },
    {
      "priority_code":{
        "order": "asc"
      }
    },{
      "id.keyword":{
        "order": "desc"
      }
    }
  ],


 "size":100
}
执行结果有
 "_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAABlXwoWbVFramtrLTNTTU9IUHBSM3d6bGtSZw==",

后续执行, 循环执行,直到没有数据返回表示已经全部数据了
POST _search/scroll
{
  "scroll" : "1m",
  "scroll_id" :"DXF1ZXJ5QW5kRmV0Y2gBAAAAAABlXwoWbVFramtrLTNTTU9IUHBSM3d6bGtSZw=="
}

上面的scroll指定搜索上下文保留的时间,1m代表1分钟,还有其他时间可以选择,有d、h、m、s等,分别代表天、时、分钟、秒。

搜索上下文有过期自动删除,但如果自己知道什么时候该删,可以自己手动删除,减少资源占用
DELETE /_search/scroll
{
  "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAA6UWWVJRTk9TUXFTLUdnU28xVFN6bEM4QQ=="
}
  • scroll=5m表示设置scroll_id保留5分钟可用。
  • 使用scroll必须要将from设置为0。
  • size决定后面每次调用_search搜索返回的数量

然后我们可以通过数据返回的_scroll_id读取下一页内容,每次请求将会读取下10条数据,直到数据读取完毕或者scroll_id保留时间截止:

根据官方文档的说法,scroll的搜索上下文会在scroll的保留时间截止后自动清除,但是我们知道scroll是非常消耗资源的,所以一个建议就是当不需要了scroll数据的时候,尽可能快的把scroll_id显式删除掉。

清除所有的scroll:

DELETE _search/scroll/_all