当前位置:  首页>> 技术小册>> ElasticSearch零基础到实战

ElasticSearch提供了多种方式实现分页,本文将介绍三种常用的方法:from+size、search after、scroll api,并提供Python代码示例。

1.from+size
from和size是ElasticSearch分页的基本概念,from表示从第几条记录开始,size表示返回多少条记录。例如,我们要查询前100条数据,可以使用如下的ElasticSearch查询语句:

  1. GET /my_index/_search
  2. {
  3. "from": 0,
  4. "size": 100,
  5. "query": {
  6. "match_all": {}
  7. }
  8. }

这个查询语句中,from为0,size为100,表示从第0条记录开始,返回100条记录。如果我们要查询第101-200条数据,只需要将from改为100,size还是100即可。

下面是使用Python实现ElasticSearch分页的示例代码:

  1. from elasticsearch import Elasticsearch
  2. es = Elasticsearch()
  3. query = {
  4. "from": 0,
  5. "size": 100,
  6. "query": {
  7. "match_all": {}
  8. }
  9. }
  10. res = es.search(index="my_index", body=query)
  11. hits = res["hits"]["hits"]
  12. for hit in hits:
  13. # 处理每一条记录

这段代码中,使用Elasticsearch库创建一个ElasticSearch客户端,然后定义查询语句query,调用search方法进行查询,最后获取查询结果中的hits字段,遍历每一条记录进行处理。

2.search after
from+size虽然是ElasticSearch最基本的分页方法,但是它的缺点也很明显:分页查询效率低下。因为每次查询需要跳过前面的记录,查询的效率会随着from的增加而降低。在查询大量数据时,使用search after方法可以解决这个问题。

search after方法的原理是:将上一页的最后一条记录的排序值作为下一页查询的search after参数,这样就可以直接跳过前面的记录,查询效率大大提高。例如,我们要查询第101-200条记录,可以先查询前100条记录,获取最后一条记录的排序值,然后使用search after参数查询第101-200条记录:

  1. GET /my_index/_search
  2. {
  3. "size": 100,
  4. "sort": [
  5. {"timestamp": "asc"},
  6. {"_id": "asc"}
  7. ]
  8. }
  9. GET /my_index/_search
  10. {
  11. "size": 100,
  12. "sort": [
  13. {"timestamp": "asc"},
  14. {"_id": "asc"}
  15. ],
  16. "search_after": [last_timestamp, last_id]
  17. }

这个查询语句中,sort参数指定按照timestamp升序、_id升序排序,然后使用search after参数指定上一页最后一条记录的timestamp和_id。

下面是使用Python实现ElasticSearch search after方法的示例代码:

  1. from elasticsearch import Elasticsearch
  2. es = Elasticsearch()
  3. query = {
  4. "size": 100,
  5. "sort": [
  6. {"timestamp": "asc"},
  7. {"_id": "asc"}
  8. ]
  9. }
  10. res = es.search(index="my_index", body=query)
  11. hits = res["hits"]["hits"]
  12. for hit in hits:
  13. # 处理每一条记录
  14. last_hit = hits[-1] # 获取最后一条记录
  15. last_timestamp = last_hit["_source"]["timestamp"]
  16. last_id = last_hit["_id"]
  17. while len(hits) == 100:
  18. query["search_after"] = [last_timestamp, last_id]
  19. res = es.search(index="my_index", body=query)
  20. hits = res["hits"]["hits"]
  21. for hit in hits:
  22. # 处理每一条记录
  23. last_hit = hits[-1]
  24. last_timestamp = last_hit["_source"]["timestamp"]
  25. last_id = last_hit["_id"]

这段代码中,首先查询前100条记录,获取最后一条记录的timestamp和_id作为下一页查询的search after参数。然后在循环中使用这个search after参数进行查询,直到查询结果不足100条为止。在循环中处理每一条记录即可。

3.scroll api
scroll api是ElasticSearch提供的另一种分页方式,它与search after方法不同的是,search after方法是基于排序值的分页方式,而scroll api是基于游标的分页方式。使用scroll api需要先创建一个游标,然后使用游标进行分页查询。例如,我们要查询前1000条记录,可以使用如下的ElasticSearch查询语句:

  1. POST /my_index/_search?scroll=1m
  2. {
  3. "size": 100,
  4. "query": {
  5. "match_all": {}
  6. }
  7. }

这个查询语句中,scroll参数指定游标的存活时间,每次查询返回的结果中会包含一个scroll_id,使用这个scroll_id进行下一次查询即可。

下面是使用Python实现ElasticSearch scroll api的示例代码:

  1. from elasticsearch import Elasticsearch
  2. es = Elasticsearch()
  3. query = {
  4. "size": 100,
  5. "query": {
  6. "match_all": {}
  7. }
  8. }
  9. res = es.search(index="my_index", body=query, scroll="1m")
  10. scroll_id = res["_scroll_id"]
  11. hits = res["hits"]["hits"]
  12. for hit in hits:
  13. # 处理每一条记录
  14. while len(hits) > 0:
  15. res = es.scroll(scroll_id=scroll_id, scroll="1m")
  16. scroll_id = res["_scroll_id"]
  17. hits = res["hits"]["hits"]
  18. for hit in hits:
  19. # 处理每一条记录

这段代码中,首先查询前100条记录,获取scroll_id和查询结果中的hits字段。然后在循环中使用scroll_id进行查询,直到查询结果为空为止。在循环中处理每一条记录即可。

小结:

本文介绍了ElasticSearch分页的三种常用方法:from+size、search after、scroll api,并提供了Python代码示例。在使用分页查询时,应根据实际情况选择合适的方法,以提高查询效率。


该分类下的相关小册推荐: