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

2022-08-20  本文已影响0人  Nzkalhbxx

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

基础知识点

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

# 查询文档中desc精确匹配“中国人”,
# 而且desc必须能够到
# 匹配“哈哈嘻嘻呼呼方面中国传统”的文档。
# (match会对关键词进行分词,有满足的即返回)
GET /dangdang/books/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "desc": {
              "value": "中国人"
            }
          }
        },
        {
          "match": {
            "desc": "哈哈嘻嘻呼呼方面中国传统"
          }
        }
      ]
    }
  }
}
# 查询文档中desc包含了“中国人”
# 或者包含了“引用”的文档
GET /dangdang/books/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "desc": {
              "value": "中国人"
            }
          }
        },
        {
          "term": {
            "desc": {
              "value": "引用"
            }
          }
        }
      ],
# 不写的话默认为1(即shoule的所有条件中,
# 只要有1个条件满足,那么即判定该文档匹配)
# =2的话即代表所有条件中
# 必须有>=2个条件满足才判断匹配成功
      "minimum_should_match": 1
    }
  }
}
# 查询文档中desc没有“美国”且没有“修养”的记录
GET /dangdang/books/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "term": {
            "desc": {
              "value": "美国"
            }
          }
        },
        {
          "term": {
            "desc": {
              "value": "修养"
            }
          }
        }
      ]
    }
  }
}
# 查找文档中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
    }
  }
}
上一篇下一篇

猜你喜欢

热点阅读