文章目录

      • 前言
        • 1、search_after原理
        • 2、特点
      • 使用
        • 1、kibana中测试示例
        • 2、Java代码示例
          • `首次调用`:
          • `后续调用`:

转载请标明出处:
http://blog.csdn/qq_27818541/article/details/109208235
本文出自:【BigManing的博客】

前言

1、search_after原理

search_after 分页的方式和 scroll 基本类似, 比较明显的区别 就是首先根据排序等条件查询,然后根据上一页中任何一条数据(sort结果),来确定下一页开始的位置

2、特点

  1. 可以深查询
  2. 实时查询 :在查询期间 ,有索引数据增删改查,这些变更也会实时的反映到相应的分页中。
  3. 需要文档有全局唯一值字段:用于排序中。例如使用业务层字段 id。

使用

1、kibana中测试示例

第一次查询: 需要设置查询条件,排序条件 ,我这里的排序是按照timestamp_id 字段排序的。

GET book/_search
{
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "name": "明朝的那些事"
          }
        }
      ]
    }
  },
  "sort": [
    {
      "timestamp": "asc"
    },
    {
      "_id": "asc"
    }
  ]
}

响应: 每条数据后面有个sort字段,

{
    "took":3,
    "timed_out":false,
    "_shards":{
        "total":1,
        "successful":1,
        "skipped":0,
        "failed":0
    },
    "hits":{
        "total":7721,
        "max_score":null,
        "hits":[
            Object{...},
            Object{...},
            Object{...},
            Object{...},
            Object{...},
            Object{...},
            Object{...},
            Object{...},
            Object{...},
            {
                "_index":"log-20191017",
                "_type":"_doc",
                "_id":"1297720911377862657",
                "_score":null,
                "_source":{
                     ...
                    "id":"1297720911377862657",
                    "ip":"127.0.0.1",
                    ...
                    "timestamp":1571254494349
                },
                "sort":[
                    1571254494349,
                    "1297720911377862657"
                ]
            }
        ]
    }
}

后续查询: 增加一个查询字段search_after,里面使用上面任一sort值(如果是分页查询,那就用最后一个)

GET book/_search
{
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "name": "明朝的那些事"
          }
        }
      ]
    }
  },
  "search_after": [1571254494349, "1297720911377862657"],
  "sort": [
    {
      "timestamp": "asc"
    },
    {
      "_id": "asc"
    }
  ]
}

查询结果如上页。

2、Java代码示例

首次调用

searchAfter 不需要打开


//查询条件
 BoolQueryBuilder boolQueryBuild = QueryBuilders.boolQuery();
QueryBuilder matchQuery = QueryBuilders.matchQuery("title", "BigManing");
boolQueryBuild.filter(matchQuery);
// 构建请求  设置查询条件 排序条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 
requestBuilder.setQuery(boolQueryBuild);
requestBuilder.addSort(SortBuilders.fieldSort("timestamp").order(SortOrder.ASC));
requestBuilder.addSort(SortBuilders.fieldSort("_id").order(SortOrder.ASC));
requestBuilder.setSize(pageSize);
//requestBuilder.searchAfter(null);   
// 请求 es
SearchRequest searchRequest = new SearchRequest("book");
searchRequest.source(requestBuilder);
return client.search(searchRequest, RequestOptions.DEFAULT)
    

响应结果同上。

后续调用

需要传入上页最后一个数据的sort值。 新加requestBuilder.searchAfter(sortData) 这句话。

 BoolQueryBuilder boolQueryBuild = QueryBuilders.boolQuery();
QueryBuilder matchQuery = QueryBuilders.matchQuery("title", "BigManing");
boolQueryBuild.filter(matchQuery);
// 构建请求  设置查询条件 排序条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 
requestBuilder.setQuery(boolQueryBuild);
requestBuilder.addSort(SortBuilders.fieldSort("timestamp").order(SortOrder.ASC));
requestBuilder.addSort(SortBuilders.fieldSort("_id").order(SortOrder.ASC));
requestBuilder.setSize(pageSize);
// 接受上面的sort值 ,进行分页查询
Object[] sortData; 
requestBuilder.searchAfter(sortData);   
// 请求 es
SearchRequest searchRequest = new SearchRequest("book");
searchRequest.source(requestBuilder);
return client.search(searchRequest, RequestOptions.DEFAULT)
    

更多推荐

ElasticSearch - 分页查询方式三 【search_after】滚动查询(kibana、Java示例)