python 使用elasticsearch 实现翻页的三种方式


Posted in Python onJuly 31, 2020

python 使用elasticsearch 实现翻页的三种方式

使用ES做搜索引擎拉取数据的时候,如果数据量太大,通过传统的from + size的方式并不能获取所有的数据(默认最大记录数10000),因为随着页数的增加,会消耗大量的内存,导致ES集群不稳定。因此延伸出了scroll,search_after等翻页方式。

一、from + size 浅分页

"浅"分页可以理解为简单意义上的分页。它的原理很简单,就是查询前20条数据,然后截断前10条,只返回10-20的数据。这样其实白白浪费了前10条的查询。

GET test/_search
{
 "query": {
 "bool": {
  "filter": [
  {
   "term": {
   "age": 28
   }
  }
  ]
 }
 },
 "size": 10,
 "from": 20,
 "sort": [
 {
  "timestamp": {
  "order": "desc"
  },
  "_id": {
  "order": "desc"
  }
 }
 ]
}

from定义了目标数据的偏移值,size定义当前返回的数目。默认from为0,size为10,即所有的查询默认仅仅返回前10条数据。

在这里有必要了解一下from/size的原理:
因为es是基于分片的,假设有5个分片,from=100,size=10。则会根据排序规则从5个分片中各取回100条数据数据,然后汇总成500条数据后选择最后面的10条数据。

做过测试,越往后的分页,执行的效率越低。总体上会随着from的增加,消耗时间也会增加。而且数据量越大,就越明显!

二、scroll 深分页

 from+size查询在10000-50000条数据(1000到5000页)以内的时候还是可以的,但是如果数据过多的话,就会出现深分页问题。为了解决上面的问题,elasticsearch提出了一个scroll滚动的方式。
scroll 类似于sql中的cursor,使用scroll,每次只能获取一页的内容,然后会返回一个scroll_id。根据返回的这个scroll_id可以不断地获取下一页的内容,所以scroll并不适用于有跳页的情景。

# -*- coding: utf-8 -*-
# @Time : 
# @Author :
 
from elasticsearch import Elasticsearch
 
es = Elasticsearch(hosts="ip:9200", timeout=20, max_retries=10, retry_on_timeout=True)
 
# Elasticsearch 需要保持搜索的上下文环境多久 游标查询过期时间为10分钟(10m)
page = es.search(
    index="source_keyword_message", doc_type="source_keyword_message",
    scroll='10m',
    size=100,
    body={
     "query": {"match_all": {}},
    }
   )
# 游标用于输出es查询出的所有结果
sid = page['_scroll_id']
# es查询出的结果总量
scroll_size = page['hits']['total']
# es查询出的结果第一页
datas = page.get('hits').get('hits')
 
while (scroll_size > 0):
  page = es.scroll(scroll_id=sid, scroll='5m')
  sid = page['_scroll_id']
  scroll_size = len(page['hits']['hits'])
  datas = page.get('hits').get('hits')
  1. scroll=5m表示设置scroll_id保留5分钟可用。
  2. 使用scroll必须要将from设置为0。默认0
  3. size决定后面每次调用_search搜索返回的数量

三、search_after 深分页

scroll 的方式,官方的建议不用于实时的请求(一般用于数据导出),因为每一个 scroll_id 不仅会占用大量的资源,而且会生成历史快照,对于数据的变更不会反映到快照上。

search_after 分页的方式是根据上一页的最后一条数据来确定下一页的位置,同时在分页请求的过程中,如果有索引数据的增删改查,这些变更也会实时的反映到游标上。但是需要注意,因为每一页的数据依赖于上一页最后一条数据,所以无法跳页请求。

为了找到每一页最后一条数据,每个文档必须有一个全局唯一值,官方推荐使用 _uid 作为全局唯一值,其实使用业务层的 id 也可以。

GET test/_search
{
 "query": {
 "bool": {
  "filter": [
  {
   "term": {
   "age": 28
   }
  }
  ]
 }
 },
 "size": 20,
 "from": 0,
 "sort": [
 {
  "timestamp": {
  "order": "desc"
  },
  "_id": {
  "order": "desc"
  }
 }
 ]
}
  1. 使用search_after必须要设置from=0。
  2. 这里我使用timestamp和_id作为唯一值排序。
  3. 我们在返回的最后一条数据里拿到sort属性的值传入到search_after。

使用sort返回的值搜索下一页:

GET test/_search
{
 "query": {
 "bool": {
  "filter": [
  {
   "term": {
   "age": 28
   }
  }
  ]
 }
 },
 "size": 10,
 "from": 0,
 "search_after": [
 1541495312521,
 "d0xH6GYBBtbwbQSP0j1A"
 ],
 "sort": [
 {
  "timestamp": {
  "order": "desc"
  },
  "_id": {
  "order": "desc"
  }
 }
 ]
}

 到此这篇关于python 使用elasticsearch 实现翻页的三种方式的文章就介绍到这了,更多相关python elasticsearch 翻页内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python2中的raw_input() 与 input()
Jun 12 Python
CentOS下使用yum安装python-pip失败的完美解决方法
Aug 16 Python
Python插件virtualenv搭建虚拟环境
Nov 20 Python
pytorch 把MNIST数据集转换成图片和txt的方法
May 20 Python
python 通过可变参数计算n个数的乘积方法
Jun 13 Python
Python利用requests模块下载图片实例代码
Aug 12 Python
python数据化运营的重要意义
Nov 25 Python
Python编译为二进制so可执行文件实例
Dec 23 Python
Python对称的二叉树多种思路实现方法
Feb 28 Python
基于Python的OCR实现示例
Apr 03 Python
解决python中import文件夹下面py文件报错问题
Jun 01 Python
分享7个 Python 实战项目练习
Mar 03 Python
Python爬虫获取豆瓣电影并写入excel
Jul 31 #Python
深入浅析Python代码规范性检测
Jul 31 #Python
python使用Word2Vec进行情感分析解析
Jul 31 #Python
Python爬虫基于lxml解决数据编码乱码问题
Jul 31 #Python
Python如何定义有可选参数的元类
Jul 31 #Python
Python爬虫爬取糗事百科段子实例分享
Jul 31 #Python
Python如何对齐字符串
Jul 30 #Python
You might like
删除数组元素实用的PHP数组函数
2008/08/18 PHP
PHP搭建大文件切割分块上传功能示例
2017/01/04 PHP
12款经典的白富美型—jquery图片轮播插件—前端开发必备
2013/01/08 Javascript
用按钮控制iframe显示的网页实现方法
2013/02/04 Javascript
JavaScript极简入门教程(三):数组
2014/10/25 Javascript
JavaScript中的some()方法使用详解
2015/06/09 Javascript
如何判断Javascript对象是否存在的简单实例
2016/05/18 Javascript
jquery插件锦集【推荐】
2016/12/16 Javascript
手把手教你把nodejs部署到linux上跑出hello world
2017/06/19 NodeJs
vue 将页面公用的头部组件化的方法
2017/12/18 Javascript
快速了解vue-cli 3.0 新特性
2018/02/28 Javascript
基于vue2.0的活动倒计时组件countdown(附源码下载)
2018/10/09 Javascript
JQuery获取元素尺寸、位置及页面滚动事件应用示例
2019/05/14 jQuery
使用VueCli3+TypeScript+Vuex一步步构建todoList的方法
2019/07/25 Javascript
JS实现无限轮播无倒退效果
2020/09/21 Javascript
nuxt 每个页面head标签内容设置方式
2020/11/05 Javascript
[03:43]2014DOTA2西雅图国际邀请赛 newbee战队巡礼
2014/07/07 DOTA
[43:18]NB vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.22
2019/09/05 DOTA
python调用短信猫控件实现发短信功能实例
2014/07/04 Python
Python爬虫中urllib库的进阶学习
2018/01/05 Python
Python 数据处理库 pandas 入门教程基本操作
2018/04/19 Python
详解Python中的分组函数groupby和itertools)
2018/07/11 Python
python3.7 sys模块的具体使用
2019/07/22 Python
tensorflow 变长序列存储实例
2020/01/20 Python
美国知名日用品连锁超市:Dollar General(多来店)
2017/01/14 全球购物
纪伊国屋泰国网上书店:Kinokuniya泰国
2017/12/24 全球购物
Melissa鞋英国官方网站:Nonnon
2019/05/01 全球购物
英语系本科生个人求职信
2013/09/21 职场文书
土建资料员岗位职责
2014/01/04 职场文书
校园文明倡议书
2014/05/16 职场文书
2014年政务公开工作总结
2014/12/09 职场文书
2015小学五年级班主任工作总结
2015/05/21 职场文书
2016最新离婚协议书范本及程序
2016/03/18 职场文书
2017元旦、春节期间廉洁自律承诺书
2016/03/25 职场文书
2019毕业典礼主持词!
2019/07/05 职场文书
python中使用redis用法详解
2022/12/24 Redis