当你的需求是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"}}}
                  ]
               }
            }
         ]
      }
   }
}