当你的需求是condition A & condition B & (condition C || condition D)时,在ES中使用must与should组合可解决,话不都说,直接上正确的查询语句:
{ "query":{ "bool":{ "must":[ { "bool":{ "should":[ { "match":{ "conditionA":{ "query":"A" } } } ] } }, { "bool":{ "should":[ { "match":{ "conditionB":{ "query":"B" } } } ] } }, { "bool":{ "should":[ { "constant_score":{ "filter":{ "match":{ "conditionC":{ "query":"C" } } } } }, { "constant_score":{ "filter":{ "match":{ "conditionD":{ "query":"D" } } } } } ] } } ] } } }
重点就是所有条件都包含在must中,将or的条件放到一个should中,而不是must和should平级。
下面举一个更直白的示例:
先保存如下数据
name | sex | score |
---|---|---|
张三 | 男 | 60 |
李四 | 男 | 70 |
王五 | 女 | 80 |
赵六 | 男 | 80 |
需求:查询分数是70或80的男生
用人的正常逻辑思维,会觉得应该这么写 sex==男&&(score==70||socre==80),最终理想值是得到李四和赵六
{ "query": { "bool": { "must": [ {"term": {"sex": {"value": "男"}}} ], "should": [ {"term": { "score": {"value": "70"}}}, {"term": {"score": {"value": "80"}}} ] } } }
执行后发现should失效了,张三、李四、赵六都被查询出来了
有两种写法可以解决should失效的问题
第一种:(sex==男&&score==70)||(sex==男&&socre==80)
{ "query": { "bool": { "should": [ { "bool": { "must": [ {"term": {"sex": "男"}}, {"term": {"score": "70"}} ] } }, { "bool": { "must": [ {"term": {"sex": "男"}}, {"term": {"score": "80"}} ] } } ] } } }
第二种:在must中再嵌套一层bool来做should过滤
{ "query": { "bool": { "must": [ {"term": {"sex": {"value": "男"}}}, { "bool": { "should": [ {"term": {"score": {"value": "70"}}}, {"term": {"score": {"value": "80"}}} ] } } ] } } }