Elasticsearch 分页的实现方式
在 Elasticsearch 中,实现分页通常涉及到使用 from
和 size
参数,或者使用 search_after
和 search_before
游标方式。以下是各种实现方式的示例代码和解释:
from
和 size
参数from elasticsearch import Elasticsearch
# 创建Elasticsearch客户端
es = Elasticsearch([{'host': 'localhost', 'port': 9200}])
# 分页查询
def paginated_search_using_from_size(index, query, page_number, page_size):
from_value = (page_number - 1) * page_size
response = es.search(
index=index,
body=query,
from_=from_value,
size=page_size
)
return response
index_name = 'your_index'
search_query = {
"query": {
"match": {
"field": "value"
}
}
}
page_number = 2
page_size = 10
result = paginated_search_using_from_size(index_name, search_query, page_number, page_size)
print(result)
解释: 上述代码中,from_value
的计算基于当前页数和每页的文档数量,用于确定要从搜索结果中的哪个文档开始获取。size
参数用于指定每页的文档数量。该方法适用于小数据集,但对大数据集的性能可能会有问题,因为每次查询都需要跳过一定数量的文档。
search_after
游标方式from elasticsearch import Elasticsearch
# 创建Elasticsearch客户端
es = Elasticsearch([{'host': 'localhost', 'port': 9200}])
# 分页查询
def paginated_search_using_search_after(index, query, page_size, search_after=None):
body = {
"query": query,
"size": page_size,
"sort": ["_doc"]
}
if search_after:
body['search_after'] = search_after
response = es.search(
index=index,
body=body
)
return response
index_name = 'your_index'
search_query = {
"match": {
"field": "value"
}
}
page_size = 10
# 第一页查询
result_page1 = paginated_search_using_search_after(index_name, search_query, page_size)
print(result_page1)
# 获取search_after游标
search_after_cursor = result_page1['hits']['hits'][-1]['sort']
# 第二页查询
result_page2 = paginated_search_using_search_after(index_name, search_query, page_size, search_after_cursor)
print(result_page2)
解释: 这种方式使用 search_after
游标,将上一页的最后一个文档的排序值传递给下一页的查询以确定起始位置。这样做可以提高大数据集上的分页性能,因为不需要每次都跳过文档。排序字段在这里设置为 "_doc"
以确保按照文档插入顺序进行排序。
以上是 Elasticsearch 分页的两种常见实现方式。选择哪种方式取决于数据集的大小和性能要求。使用 from
和 size
对于小数据集可能是简单有效的,而使用 search_after
对于大数据集则可能更具优势。