组合条件查询是基于叶子查询条件,将叶子条件作为子条件,形成一个多字段多条件的组合条件.
一、bool条件
1.功能及参数功能:通过多个叶子条件形成一个bool条件树
参数:must : 必须满足指定的条件(各子条件是AND关系)
filter : 指定必须满足的条件(不统计相关度评分)
should : 满足一个子条件即可(各子条件是OR关系)
must_not : 不满足条件(NOT)
must/filter/shoud/must_not 等的子条件是通过 term/terms/range/ids/exists/match 等叶子条件为参数的
注:以上参数,当只有一个搜索条件时,must等对应的是一个对象,当是多个条件时,对应的是一个数组
2.must
通过must来查询状态为1的用户列表
GET user/_doc/_search
{
"_source":["user_id","status"],
"query":{
"bool":{
"must":{
"term":{
"status":1
}
}
}
}
}
查询结果:
{
"took":2,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"skipped":0,
"failed":0
},
"hits":{
"total":4,
"max_score":1.0,
"hits":[
{
"_index":"user",
"_type":"_doc",
"_id":"5",
"_score":1.0,
"_source":{
"user_id":5,
"status":1
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"4",
"_score":1.0,
"_source":{
"user_id":4,
"status":1
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"6",
"_score":1.0,
"_source":{
"user_id":6,
"status":1
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"1",
"_score":1.0,
"_source":{
"user_id":1,
"status":1
}
}
]
}
}
3.filter
filter与其他子查询条件不同,它不计算_score即相关度评分,效率更高
GET user/_doc/_search
{
"_source":["user_id","status"],
"query":{
"bool":{
"filter":{
"term":{
"status":1
}
}
}
}
}
查询结果:
{
"took":4,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"skipped":0,
"failed":0
},
"hits":{
"total":4,
"max_score":0.0,
"hits":[
{
"_index":"user",
"_type":"_doc",
"_id":"5",
"_score":0.0,
"_source":{
"user_id":5,
"status":1
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"4",
"_score":0.0,
"_source":{
"user_id":4,
"status":1
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"6",
"_score":0.0,
"_source":{
"user_id":6,
"status":1
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"1",
"_score":0.0,
"_source":{
"user_id":1,
"status":1
}
}
]
}
}
通过结果的_score字段可以看出,没有计算_score的值
4.should
当多个条件之间是OR的关系时,使用should
如查询address中包含”zhejiang”或”nickname”为”shixinke”的记录
GET user/_doc/_search
{
"_source":[
"user_id",
"nickname",
"address"
],
"query":{
"bool":{
"should":[
{
"match":{
"address":"zhejiang"
}
},
{
"term":{
"nickname":"shixinke"
}
}
]
}
}
}
查询结果:
{
"took":4,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"skipped":0,
"failed":0
},
"hits":{
"total":2,
"max_score":0.5753642,
"hits":[
{
"_index":"user",
"_type":"_doc",
"_id":"1",
"_score":0.5753642,
"_source":{
"address":"HangZhou,ZheJiang,China",
"user_id":1,
"nickname":"shixinke"
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"5",
"_score":0.2876821,
"_source":{
"address":"NingBo,ZheJiang,China",
"user_id":5,
"nickname":"jet"
}
}
]
}
}
5.must_not
must_not用于排除某个条件的记录
如:查询状态不为0的用户列表
GET user/_doc/_search
{
"_source":[
"user_id",
"status"
],
"query":{
"bool":{
"must_not":{
"term":{
"status":0
}
}
}
}
}
查询结果:
{
"took":2,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"skipped":0,
"failed":0
},
"hits":{
"total":4,
"max_score":1.0,
"hits":[
{
"_index":"user",
"_type":"_doc",
"_id":"5",
"_score":1.0,
"_source":{
"user_id":5,
"status":1
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"4",
"_score":1.0,
"_source":{
"user_id":4,
"status":1
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"6",
"_score":1.0,
"_source":{
"user_id":6,
"status":1
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"1",
"_score":1.0,
"_source":{
"user_id":1,
"status":1
}
}
]
}
}
二、constant_score
给每条记录以一条固定的评分,即不计算相关度评分,所能constant_score只支持filter上下文
GET user/_doc/_search
{
"_source":[
"user_id",
"status"
],
"query":{
"constant_score":{
"filter":{
"term":{
"status":1
}
}
}
}
}
查询结果:
{
"took":1,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"skipped":0,
"failed":0
},
"hits":{
"total":4,
"max_score":1.0,
"hits":[
{
"_index":"user",
"_type":"_doc",
"_id":"5",
"_score":1.0,
"_source":{
"user_id":5,
"status":1
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"4",
"_score":1.0,
"_source":{
"user_id":4,
"status":1
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"6",
"_score":1.0,
"_source":{
"user_id":6,
"status":1
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"1",
"_score":1.0,
"_source":{
"user_id":1,
"status":1
}
}
]
}
}
从结果可以看出_score是一个固定的值”1.0”
三、dis_max
在多字段全文检索时,固定相关度评分,即不计算相关度评分,而不是尽可能多的field匹配了少数的关键词(取分数最高的那个字段的分数)
如下:查询status为1或address中包含zhejiang的记录,有的记录匹配status=1,有的记录匹配addres包含zhejiang,这时取最匹配的那个字段的分数
GET user/_doc/_search
{
"_source":[
"user_id",
"address"
],
"query":{
"dis_max":{
"queries":[
{
"term":{
"status":1
}
},
{
"match":{
"address":"zhejiang"
}
}
]
}
}
}
查询结果:
{
"took":1,
"timed_out":false,
"_shards":{
"total":5,
"successful":5,
"skipped":0,
"failed":0
},
"hits":{
"total":4,
"max_score":1.0,
"hits":[
{
"_index":"user",
"_type":"_doc",
"_id":"5",
"_score":1.0,
"_source":{
"address":"NingBo,ZheJiang,China",
"user_id":5
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"4",
"_score":1.0,
"_source":{
"address":"PuDong,ShangHai,China",
"user_id":4
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"6",
"_score":1.0,
"_source":{
"address":"SuZhou,JiangSu,China",
"user_id":6
}
},
{
"_index":"user",
"_type":"_doc",
"_id":"1",
"_score":1.0,
"_source":{
"address":"HangZhou,ZheJiang,China",
"user_id":1
}
}
]
}
}