{
"_source":{
"excludes":["remark"]
},
"query": {
"bool" : {
"must" : [{
"term" : { "name" : "钱军" }
},{
"term" : { "height" : "1.66" }
}],
"filter": [{
"term" : { "height" : "1.66" }
}],
"must_not" : [{
"range" : {
"age" : { "gte" : 10, "lte" : 20 }
}
}],
"should" : [
{ "term" : { "sex" : "1" } }
],
"minimum_should_match" : 1,
"boost" : 1.0
}
}
}
示例结果
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 7.5062823,
"hits": [
{
"_index": "person",
"_id": "507",
"_score": 7.5062823,
"_source": {
"id": 508,
"name": "钱军",
"age": 24,
"height": 1.66,
"birthday": "1980-08-04 08:33:00",
"sex": 1
}
}
]
}
}
minimum_should_match:指定返回文档必须匹配的子句的数量或百分比。其有效值如下
示例 | 说明 | 类型 |
---|---|---|
3 | 就是数量3 | 正整数 |
-2 | 表示可选的总数,减去这个数目的值 | 负整数 |
75% | 表示可选数量的75%,分比计算的数字向下舍入 | 百分比 |
-25% | 表示可选数量减去可选数量的25%,分比计算的数字向下舍入 | 负百分比 |
3<90% | 可选数量小于3,则都是必须的。大于3,则数量的90%为必须的 | |
2<-25% | 可选数量大于2,则除去25%,其余是必须的 | |
9<-3 | 可选数量大于9,则除去3个数量,其余是必须的 |
在处理百分比时,负值可用于在极端情况下获得不同的行为。75% 和 -25% 在处理 4 个子句时表示相同的意思,但是在处理 5 个子句时 75% 表示需要 3 个,而 -25% 表示需要 4 个。
GET /<target>/_search
GET /_search
POST /<target>/_search
POST /_search
使用 _search 接口的,from、size参数
from 和 size 两个参数可以为查询参数也可以是请求正文参数。返回数量最大为:10,000,一般情况下,既然分页应该不会超过该值。而且翻页也不能太深,其实就是 from 的值太大也是不行的,具体的原因本文下方,大量数据分页查询有解释。
GET /person/_search
{
"query": {
"match_all": {}
},
"from":0,
"size":2
}
以上示例只查询出2条结果
使用 _search 接口的 _source 参数指定查询结果字段
GET /person/_search
{
"_source":{
"excludes":["remark"]
},
"query": {
"match_all": {}
},
"from":0,
"size":2
}
示例表示查询结果不返回 “remark” 字段
使用 _search 接口的 sort 参数指定排序字段以及排序方式
GET /person/_search
{
"_source":{
"excludes":["remark"]
},
"query": {
"match_all": {}
},
"from":0,
"size":20,
"sort":[{"age":"desc"},{"sex":"asc"}]
}
该示例表示查询 person 索引,并按 “age” 降序且“sex”升序排序,取出前20条数据。
以以下请求的结果来进行说明
GET /person/_search
{
"_source":{
"excludes":["remark"]
},
"query": {
"match_all": {}
},
"from":0,
"size":20,
"sort":[{"age":"desc"},{"sex":"asc"}]
}
{
"took": 2, // 执行时间
"timed_out": false, // 是否超时
"_shards": { // 请求的分片信息
"total": 1, // 要查询的分片总数,包括未分配的分片
"successful": 1, // 成功执行的分片数量
"skipped": 0, // 跳过的分片数量
"failed": 0
// 未能执行请求的分片数。请注意,未分配的分片将被视为既不成功也不失败。
// total < successful + failed 说明某些分片未分配
},
"hits": {
"total": { // 文档数量的数据
"value": 1003, // 匹配的文档总数
"relation": "eq" // eq 准确匹配;gte 下线
},
"max_score": null,
"hits": [ // 匹配的对象数组
{
"_index": "person", // 文档所在的索引
"_id": "1391", // 当前文档对id
"_score": null, // 文档相关性分数
"_source": { // 索引时的原始Json对象 会按 _source 参数返回
"name": "龚敏"
},
"sort": [
50,
1
]
},
{
"_index": "person",
"_id": "1777",
"_score": null,
"_source": {
"name": "姚洋"
},
"sort": [
50,
1
]
}
]
}
}
官网说明中有这么一段话:避免使用 from 和 size 翻页太深(超过几千页)或一次请求太多结果。搜索请求通常跨越多个分片。每个分片必须将其请求的命中和任何先前页面的命中加载到内存中。因此对于深层页面或大型结果集,这些操作会显着增加内存和 CPU 使用率,从而导致性能下降或节点故障。
对于以上情况,请使用 search_after 来进行分页查询。
排序是最好是按照唯一键进行
{
"_source":{
"excludes":["remark"]
},
"query": {
"match_all": {}
},
"sort":[{"id":"asc"},{"age":"desc"}]
}
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1003,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "person",
"_id": "5",
"_score": null,
"_source": {
"id": 6,
"name": "戴刚",
"age": 23,
"height": 1.82,
"birthday": "2010-08-07 03:46:28",
"sex": 1
},
"sort": [
6,
23
]
},
{
"_index": "person",
"_id": "265",
"_score": null,
"_source": {
"id": 266,
"name": "文敏",
"age": 31,
"height": 1.75,
"birthday": "1987-05-07 11:47:16",
"sex": 0
},
"sort": [
266,
31
]
},
{
"_index": "person",
"_id": "267",
"_score": null,
"_source": {
"id": 268,
"name": "董超",
"age": 42,
"height": 1.67,
"birthday": "1974-09-04 12:27:55",
"sex": 0
},
"sort": [
268,
42
]
},
{
"_index": "person",
"_id": "269",
"_score": null,
"_source": {
"id": 270,
"name": "江娟",
"age": 46,
"height": 1.04,
"birthday": "1975-12-05 02:03:17",
"sex": 0
},
"sort": [
270,
46
]
},
{
"_index": "person",
"_id": "271",
"_score": null,
"_source": {
"id": 272,
"name": "梁桂英",
"age": 11,
"height": 1.35,
"birthday": "1984-02-17 04:25:18",
"sex": 0
},
"sort": [
272,
11
]
},
{
"_index": "person",
"_id": "273",
"_score": null,
"_source": {
"id": 274,
"name": "龙娜",
"age": 33,
"height": 1.26,
"birthday": "2007-05-26 12:06:33",
"sex": 1
},
"sort": [
274,
33
]
},
{
"_index": "person",
"_id": "275",
"_score": null,
"_source": {
"id": 276,
"name": "沈杰",
"age": 15,
"height": 1.68,
"birthday": "2005-05-09 13:39:45",
"sex": 0
},
"sort": [
276,
15
]
},
{
"_index": "person",
"_id": "277",
"_score": null,
"_source": {
"id": 278,
"name": "卢杰",
"age": 28,
"height": 1.73,
"birthday": "2012-01-31 01:28:44",
"sex": 0
},
"sort": [
278,
28
]
},
{
"_index": "person",
"_id": "279",
"_score": null,
"_source": {
"id": 280,
"name": "黎霞",
"age": 24,
"height": 1.61,
"birthday": "2003-09-08 10:44:28",
"sex": 0
},
"sort": [
280,
24
]
},
{
"_index": "person",
"_id": "281",
"_score": null,
"_source": {
"id": 282,
"name": "武芳",
"age": 42,
"height": 1.34,
"birthday": "1994-11-11 13:48:35",
"sex": 0
},
"sort": [
282,
42
]
}
]
}
}
{
"_source":{
"excludes":["remark"]
},
"query": {
"match_all": {}
},
"search_after": [282, 42],
"sort":[{"id":"asc"},{"age":"desc"}]
}
查询结果
{
"took": 9,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1003,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "person",
"_id": "283",
"_score": null,
"_source": {
"id": 284,
"name": "白杰",
"age": 28,
"height": 1.47,
"birthday": "2020-07-04 15:59:12",
"sex": 0
},
"sort": [
284,
28
]
},
{
"_index": "person",
"_id": "285",
"_score": null,
"_source": {
"id": 286,
"name": "高秀英",
"age": 31,
"height": 1.61,
"birthday": "1989-12-23 18:01:15",
"sex": 0
},
"sort": [
286,
31
]
},
{
"_index": "person",
"_id": "287",
"_score": null,
"_source": {
"id": 288,
"name": "易娜",
"age": 45,
"height": 1.47,
"birthday": "1983-11-27 10:35:25",
"sex": 1
},
"sort": [
288,
45
]
},
{
"_index": "person",
"_id": "289",
"_score": null,
"_source": {
"id": 290,
"name": "江丽",
"age": 21,
"height": 1.55,
"birthday": "1979-03-23 15:42:32",
"sex": 0
},
"sort": [
290,
21
]
},
{
"_index": "person",
"_id": "291",
"_score": null,
"_source": {
"id": 292,
"name": "杜霞",
"age": 40,
"height": 1.26,
"birthday": "1995-02-19 04:09:23",
"sex": 0
},
"sort": [
292,
40
]
},
{
"_index": "person",
"_id": "293",
"_score": null,
"_source": {
"id": 294,
"name": "常超",
"age": 25,
"height": 1.39,
"birthday": "2019-01-16 16:20:09",
"sex": 1
},
"sort": [
294,
25
]
},
{
"_index": "person",
"_id": "295",
"_score": null,
"_source": {
"id": 296,
"name": "胡明",
"age": 11,
"height": 1.34,
"birthday": "2006-03-10 10:05:44",
"sex": 0
},
"sort": [
296,
11
]
},
{
"_index": "person",
"_id": "297",
"_score": null,
"_source": {
"id": 298,
"name": "邵艳",
"age": 19,
"height": 1.96,
"birthday": "2016-03-23 00:39:01",
"sex": 1
},
"sort": [
298,
19
]
},
{
"_index": "person",
"_id": "299",
"_score": null,
"_source": {
"id": 300,
"name": "周伟",
"age": 15,
"height": 1.28,
"birthday": "1993-04-09 19:15:39",
"sex": 1
},
"sort": [
300,
15
]
},
{
"_index": "person",
"_id": "301",
"_score": null,
"_source": {
"id": 302,
"name": "姚静",
"age": 32,
"height": 1.91,
"birthday": "1979-09-27 13:55:29",
"sex": 0
},
"sort": [
302,
32
]
}
]
}
}
最后我们可以按照此方式查询下去。而且,我们每一页的 search_after 条件我们都可以进行缓存,在指定某一页的时候使用对应的查询数据(此方式有个前提,1:索引不变;2:如果当前只迭代到第10页,我们要直接跳转查询第282页的数据,也是比较困难的)
如果文档发生变化,那么我们使用原来的 search_after 条件查询,可能得到和原来不同的结果,此情况下,我们需要创建一个 PIT 来进行搜索
PIT:point in time (时间点),默认情况下,搜索请求针对目标索引的最新可见数据执行,这称为时间点。特别当我们使用 search_after 进行分页查询时,数据到变化可能导致分页的结果不准确,这时候我们常常创建一个时间点,让 search_after 的请求都使用该时间点的索引状态来进行查询,用以避免分页结果不准确的问题。
POST /person/_pit?keep_alive = 1m
创建一个 PIT,keep_alive 表示保持活动状态多长时间,这里为1m(1分钟),保持状态的时间用于保证下一次查询即可,无需保证整个查询的周期。
{
"id": "i_vrAwEGcGVyc29uFmdPM2JrLVd2UUttSmpMWlFCV09hTUEAFm9qNUZFaVZNUnB1V1YzODZ6ZHd5M3cAAAAAAAAAAOcWck4zNjcxWWZRaC04eDMxXzZHQWFGUQABFmdPM2JrLVd2UUttSmpMWlFCV09hTUEAAA=="
}
GET /_search
{
"_source":{
"excludes":["remark"]
},
"query": {
"match_all": {}
},
"pit":{
"id": "i_vrAwEGcGVyc29uFmdPM2JrLVd2UUttSmpMWlFCV09hTUEAFm9qNUZFaVZNUnB1V1YzODZ6ZHd5M3cAAAAAAAAAAOcWck4zNjcxWWZRaC04eDMxXzZHQWFGUQABFmdPM2JrLVd2UUttSmpMWlFCV09hTUEAAA==",
"keep_alive": "1m"
},
"sort":[{"id":"asc"},{"age":"desc"}]
}
注意:使用 PIT 时,查询需要省略掉索引名称,所以此处我们是直接调用的 _search 接口。
{
"pit_id": "i_vrAwEGcGVyc29uFmdPM2JrLVd2UUttSmpMWlFCV09hTUEAFm9qNUZFaVZNUnB1V1YzODZ6ZHd5M3cAAAAAAAAAAOcWck4zNjcxWWZRaC04eDMxXzZHQWFGUQABFmdPM2JrLVd2UUttSmpMWlFCV09hTUEAAA==",
"took": 4,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1003,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "person",
"_id": "5",
"_score": null,
"_source": {
"id": 6,
"name": "戴刚",
"age": 23,
"height": 1.82,
"birthday": "2010-08-07 03:46:28",
"sex": 1
},
"sort": [
6,
23,
0
]
},
{
"_index": "person",
"_id": "265",
"_score": null,
"_source": {
"id": 266,
"name": "文敏",
"age": 31,
"height": 1.75,
"birthday": "1987-05-07 11:47:16",
"sex": 0
},
"sort": [
266,
31,
1
]
},
{
"_index": "person",
"_id": "267",
"_score": null,
"_source": {
"id": 268,
"name": "董超",
"age": 42,
"height": 1.67,
"birthday": "1974-09-04 12:27:55",
"sex": 0
},
"sort": [
268,
42,
2
]
},
{
"_index": "person",
"_id": "269",
"_score": null,
"_source": {
"id": 270,
"name": "江娟",
"age": 46,
"height": 1.04,
"birthday": "1975-12-05 02:03:17",
"sex": 0
},
"sort": [
270,
46,
3
]
},
{
"_index": "person",
"_id": "271",
"_score": null,
"_source": {
"id": 272,
"name": "梁桂英",
"age": 11,
"height": 1.35,
"birthday": "1984-02-17 04:25:18",
"sex": 0
},
"sort": [
272,
11,
4
]
},
{
"_index": "person",
"_id": "273",
"_score": null,
"_source": {
"id": 274,
"name": "龙娜",
"age": 33,
"height": 1.26,
"birthday": "2007-05-26 12:06:33",
"sex": 1
},
"sort": [
274,
33,
5
]
},
{
"_index": "person",
"_id": "275",
"_score": null,
"_source": {
"id": 276,
"name": "沈杰",
"age": 15,
"height": 1.68,
"birthday": "2005-05-09 13:39:45",
"sex": 0
},
"sort": [
276,
15,
6
]
},
{
"_index": "person",
"_id": "277",
"_score": null,
"_source": {
"id": 278,
"name": "卢杰",
"age": 28,
"height": 1.73,
"birthday": "2012-01-31 01:28:44",
"sex": 0
},
"sort": [
278,
28,
7
]
},
{
"_index": "person",
"_id": "279",
"_score": null,
"_source": {
"id": 280,
"name": "黎霞",
"age": 24,
"height": 1.61,
"birthday": "2003-09-08 10:44:28",
"sex": 0
},
"sort": [
280,
24,
8
]
},
{
"_index": "person",
"_id": "281",
"_score": null,
"_source": {
"id": 282,
"name": "武芳",
"age": 42,
"height": 1.34,
"birthday": "1994-11-11 13:48:35",
"sex": 0
},
"sort": [
282,
42,
9
]
}
]
}
}
GET /_search
{
"_source":{
"excludes":["remark"]
},
"query": {
"match_all": {}
},
"pit":{
"id": "i_vrAwEGcGVyc29uFmdPM2JrLVd2UUttSmpMWlFCV09hTUEAFm9qNUZFaVZNUnB1V1YzODZ6ZHd5M3cAAAAAAAAAAOcWck4zNjcxWWZRaC04eDMxXzZHQWFGUQABFmdPM2JrLVd2UUttSmpMWlFCV09hTUEAAA==",
"keep_alive": "1m"
},
"search_after": [282, 42, 9],
"sort":[{"id":"asc"},{"age":"desc"}]
}
{
"pit_id": "i_vrAwEGcGVyc29uFmdPM2JrLVd2UUttSmpMWlFCV09hTUEAFm9qNUZFaVZNUnB1V1YzODZ6ZHd5M3cAAAAAAAAAAOcWck4zNjcxWWZRaC04eDMxXzZHQWFGUQABFmdPM2JrLVd2UUttSmpMWlFCV09hTUEAAA==",
"took": 6,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1003,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "person",
"_id": "283",
"_score": null,
"_source": {
"id": 284,
"name": "白杰",
"age": 28,
"height": 1.47,
"birthday": "2020-07-04 15:59:12",
"sex": 0
},
"sort": [
284,
28,
10
]
},
{
"_index": "person",
"_id": "285",
"_score": null,
"_source": {
"id": 286,
"name": "高秀英",
"age": 31,
"height": 1.61,
"birthday": "1989-12-23 18:01:15",
"sex": 0
},
"sort": [
286,
31,
11
]
},
{
"_index": "person",
"_id": "287",
"_score": null,
"_source": {
"id": 288,
"name": "易娜",
"age": 45,
"height": 1.47,
"birthday": "1983-11-27 10:35:25",
"sex": 1
},
"sort": [
288,
45,
12
]
},
{
"_index": "person",
"_id": "289",
"_score": null,
"_source": {
"id": 290,
"name": "江丽",
"age": 21,
"height": 1.55,
"birthday": "1979-03-23 15:42:32",
"sex": 0
},
"sort": [
290,
21,
13
]
},
{
"_index": "person",
"_id": "291",
"_score": null,
"_source": {
"id": 292,
"name": "杜霞",
"age": 40,
"height": 1.26,
"birthday": "1995-02-19 04:09:23",
"sex": 0
},
"sort": [
292,
40,
14
]
},
{
"_index": "person",
"_id": "293",
"_score": null,
"_source": {
"id": 294,
"name": "常超",
"age": 25,
"height": 1.39,
"birthday": "2019-01-16 16:20:09",
"sex": 1
},
"sort": [
294,
25,
15
]
},
{
"_index": "person",
"_id": "295",
"_score": null,
"_source": {
"id": 296,
"name": "胡明",
"age": 11,
"height": 1.34,
"birthday": "2006-03-10 10:05:44",
"sex": 0
},
"sort": [
296,
11,
16
]
},
{
"_index": "person",
"_id": "297",
"_score": null,
"_source": {
"id": 298,
"name": "邵艳",
"age": 19,
"height": 1.96,
"birthday": "2016-03-23 00:39:01",
"sex": 1
},
"sort": [
298,
19,
17
]
},
{
"_index": "person",
"_id": "299",
"_score": null,
"_source": {
"id": 300,
"name": "周伟",
"age": 15,
"height": 1.28,
"birthday": "1993-04-09 19:15:39",
"sex": 1
},
"sort": [
300,
15,
18
]
},
{
"_index": "person",
"_id": "301",
"_score": null,
"_source": {
"id": 302,
"name": "姚静",
"age": 32,
"height": 1.91,
"birthday": "1979-09-27 13:55:29",
"sex": 0
},
"sort": [
302,
32,
19
]
}
]
}
}
除了使用带有 PIT 参数的 search_after 查询分页之外,ES 还支持滚动搜索查询(scroll),但新版本的 ES 已经不再建议使用该方式进行分页查询,所以我们就不再讨论这个问题了。
原则上,当 keep_alive 时间到时,PIT 会自动关闭,但保持 PIT 是有代价的,所以我们不再使用 PIT 时,应该及时将其关闭
DELETE /_pit
{
"id": "i_vrAwEGcGVyc29uFmdPM2JrLVd2UUttSmpMWlFCV09hTUEAFm9qNUZFaVZNUnB1V1YzODZ6ZHd5M3cAAAAAAAAAAOcWck4zNjcxWWZRaC04eDMxXzZHQWFGUQABFmdPM2JrLVd2UUttSmpMWlFCV09hTUEAAA=="
}
{
"succeeded": true, // 是否成功关闭
"num_freed": 1 // 关闭的搜索上下文的数量
}