检索排序 & 分页
1.测试数据准备
首先,我们创建一个名为 blog_posts
的索引,并插入一些测试数据:
PUT /blog_posts
{
"mappings": {
"properties": {
"title": { "type": "text" },
"content": { "type": "text" },
"author": { "type": "keyword" },
"views": { "type": "integer" },
"publish_date": { "type": "date" },
"tags": { "type": "keyword" }
}
}
}
POST /blog_posts/_bulk
{"index":{}}
{"title":"Elasticsearch Basics","content":"Learn the basics of Elasticsearch and how to perform simple queries.","author":"John Doe","views":1500,"publish_date":"2023-01-15","tags":["search","database"]}
{"index":{}}
{"title":"Advanced Search Techniques","content":"Explore advanced search techniques in Elasticsearch including aggregations and filters.","author":"Jane Smith","views":3200,"publish_date":"2023-02-20","tags":["search","advanced"]}
{"index":{}}
{"title":"Data Analytics with ELK","content":"How to use the ELK stack for data analytics and visualization.","author":"John Doe","views":2800,"publish_date":"2023-03-10","tags":["analytics","elk"]}
{"index":{}}
{"title":"Elasticsearch Performance Tuning","content":"Tips and tricks for optimizing Elasticsearch performance in production environments.","author":"Mike Johnson","views":4200,"publish_date":"2023-04-05","tags":["performance","optimization"]}
{"index":{}}
{"title":"Kibana Dashboard Guide","content":"Creating effective dashboards in Kibana for monitoring and analysis.","author":"Jane Smith","views":1900,"publish_date":"2023-05-12","tags":["kibana","visualization"]}
2.排序功能
能排序的字段都具备正排索引,单 text
类型字段是不可以排序的。如果要使 text
字段支持排序、聚合,则需要开启 fielddata
。
sort
是和 query
平级的,并不会被 query
包含。
2.1 简单字段排序
GET /blog_posts/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"views": {
"order": "desc"
}
}
]
}
2.2 多字段排序
GET /blog_posts/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"author": {
"order": "asc"
}
},
{
"views": {
"order": "desc"
}
}
]
}
2.3 日期排序
GET /blog_posts/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"publish_date": {
"order": "desc"
}
}
]
}
3.分页功能
Elasticsearch 支持对查询结果进行分页处理,允许用户逐步获取和浏览大量数据。
在编写查询语句时,可通过再请求体中添加 from
和 size
字段实现分页。from
表示结果集的起始位置,而 size
表示每页返回的文档数量。
如果将 from
设置为
11
11
11,size
设置为
5
5
5,则返回的是第
10
10
10 ~
14
14
14 条数据(默认从第
0
0
0 条开始)。
3.1 基础分页
GET /blog_posts/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 2,
"sort": [
{
"publish_date": {
"order": "desc"
}
}
]
}
3.2 深度分页(不推荐大数据量使用)
深度分页 指的是在 Elasticsearch 中查询结果集 非常靠后的页码(例如第
1000
1000
1000 页,每页
10
10
10 条数据,即 from=10000
)。它通常表现为使用 from + size
参数组合来获取远端的分页数据。
❌ 不推荐的详细原因可参考我的另一篇博客:《【Elasticsearch】深度分页及其替代方案》。
当然,我们这里测试的数据没有那么多。
GET /blog_posts/_search
{
"query": {
"match_all": {}
},
"from": 3,
"size": 2
}
3.3 使用 search_after 进行高效分页
首先获取第一页:
GET /blog_posts/_search
{
"query": {
"match_all": {}
},
"size": 2,
"sort": [
{
"views": {
"order": "desc"
}
},
{
"_id": {
"order": "asc"
}
}
]
}
然后使用最后一个结果的排序值获取下一页:
GET /blog_posts/_search
{
"query": {
"match_all": {}
},
"size": 2,
"search_after": [3200, "上一页最后一个文档的ID"],
"sort": [
{
"views": {
"order": "desc"
}
},
{
"_id": {
"order": "asc"
}
}
]
}
4.综合示例:高亮+排序+分页
GET /blog_posts/_search
{
"query": {
"multi_match": {
"query": "search",
"fields": ["title", "content"]
}
},
"highlight": {
"fields": {
"title": {},
"content": {
"fragment_size": 100,
"number_of_fragments": 2
}
}
},
"sort": [
{
"views": {
"order": "desc"
}
}
],
"from": 0,
"size": 3
}
5.实践建议
功能 |
|
---|---|
高亮 |
|
排序 |
|
分页 |
|