美文网首页
Elasticsearch中布尔查询(bool query)注意

Elasticsearch中布尔查询(bool query)注意

作者: Nzkalhbxx | 来源:发表于2022-08-20 01:40 被阅读0次

    在ES中,bool查询存在着一些比较坑的点需要注意:

    基础知识点

    布尔查询是最常用的组合查询,根据子查询的规则,只有当文档满足所有子查询条件时(即bool查询中的所有子查询的最后需要作and),elasticsearch引擎才将结果返回。布尔查询支持的子查询条件共4种:

    • must(and)返回的文档必须满足must中所有子句的条件,并且参与计算分值
    # 查询文档中desc精确匹配“中国人”,
    # 而且desc必须能够到
    # 匹配“哈哈嘻嘻呼呼方面中国传统”的文档。
    # (match会对关键词进行分词,有满足的即返回)
    GET /dangdang/books/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "desc": {
                  "value": "中国人"
                }
              }
            },
            {
              "match": {
                "desc": "哈哈嘻嘻呼呼方面中国传统"
              }
            }
          ]
        }
      }
    }
    
    • should(or)返回的文档可能满足should子句的条件,在一个bool查询中,如果没有must或者filter,当should有一个或多个条件时,默认那么只要满足一个就可以返回。
    # 查询文档中desc包含了“中国人”
    # 或者包含了“引用”的文档
    GET /dangdang/books/_search
    {
      "query": {
        "bool": {
          "should": [
            {
              "term": {
                "desc": {
                  "value": "中国人"
                }
              }
            },
            {
              "term": {
                "desc": {
                  "value": "引用"
                }
              }
            }
          ],
    # 不写的话默认为1(即shoule的所有条件中,
    # 只要有1个条件满足,那么即判定该文档匹配)
    # =2的话即代表所有条件中
    # 必须有>=2个条件满足才判断匹配成功
          "minimum_should_match": 1
        }
      }
    }
    
    • must_not(not)返回的文档必须不满足定义的所有条件
    # 查询文档中desc没有“美国”且没有“修养”的记录
    GET /dangdang/books/_search
    {
      "query": {
        "bool": {
          "must_not": [
            {
              "term": {
                "desc": {
                  "value": "美国"
                }
              }
            },
            {
              "term": {
                "desc": {
                  "value": "修养"
                }
              }
            }
          ]
        }
      }
    }
    
    • filter 返回的文档必须满足filter子句的条件,但是不参与计算分值
    # 查找文档中desc包含“人”的记录
    GET /dangdang/books/_search
    {
      "query": {
        "bool": {
          "filter": {
            "term": {
              "desc": "人"
            }
          }
        }
      }
    }
    

    组合查询

    非常需要注意的点:

    在组合查询中,即由must、must not、filter、should组合而成的bool查询,有一个很重要的点时,当使用should查询时,且除了should查询之外还有must、filter中的任意一个时(也可以must、filter同时都有),should的条件默认会被自动忽略(即minimum_should_match此时被设置成0)。
    举个简单的例子,现要查询文档中a=1,b=2,(c=8或c=9)的记录,此时可能会这么写:

    GET /dangdang/books/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "a": {
                  "value": "1"
                }
              }
            },
            {
              "term": {
                "b": {
                  "value": "2"
                }
              }
            }
          ],
          "should": [
            {
              "term": {
                "c": {
                  "value": "8"
                }
              }
            },
            {
              "term": {
                "c": {
                  "value": "9"
                }
              }
            }
          ]
        }
      }
    }
    

    但是结果会跟实际预期的不一样,当有should又有must/filter时,如果一条记录满足a=1,b=2,但即使c=999,该记录依然会被匹配成功,即should的条件会被视为无效,相当于minimum_should_match=0。如果想要达到预期的效果,可以将minimum_should_match设置为1,此时是满足该需求的。

    GET /dangdang/books/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "a": {
                  "value": "1"
                }
              }
            },
            {
              "term": {
                "b": {
                  "value": "2"
                }
              }
            }
          ],
          "should": [
            {
              "term": {
                "c": {
                  "value": "8"
                }
              }
            },
            {
              "term": {
                "c": {
                  "value": "9"
                }
              }
            }
          ],
      # 满足should所有条件中的一个
          "minimum_should_match": 1
        }
      }
    }
    

    嵌套bool查询

    # 筛选出desc包含“人”且包含“鬼”的记录,
    # 且记录中至少包含了“蔡元培”,“中国人”,
    # “引用” 条件中至少2个条件的记录
    GET /dangdang/books/_search
    {
      "query": {
        "bool": {
          "filter": {
            "bool": {
              "must": [
                {
                  "term": {
                    "desc": {
                      "value": "人"
                    }
                  }
                },
                {
                  "term": {
                    "desc": {
                      "value": "鬼"
                    }
                  }
                }
              ]
            }
          },
          "should": [
            {
              "term": {
                "desc": {
                  "value": "引用"
                }
              }
            },
            {
              "term": {
                "desc": {
                  "value": "中国人"
                }
              }
            },
            {
              "term": {
                "desc": {
                  "value": "蔡元培"
                }
              }
            }
          ],
          "minimum_should_match": 2
        }
      }
    }
    

    相关文章

      网友评论

          本文标题:Elasticsearch中布尔查询(bool query)注意

          本文链接:https://www.haomeiwen.com/subject/gnjpgrtx.html