前言

布尔查询是最常见的组合查询,根据子查询的规则,只有当文档满足所有子查询条件时,Elastic Search 引擎才会将结果返回。布尔查询支持的子查询条件共4种:

  • must(and)
  • should(or)
  • must_not(not)
  • filter

准备数据

PUT zhifou/doc/1
{
  "name":"顾老二",
  "age":30,
  "from":"gu",
  "desc":"皮肤黑、武器长、性格直",
  "tags":["黑","长","直"]
}

PUT zhifou/doc/2
{
  "name":"大娘子",
  "age":18,
  "from":"sheng",
  "desc":"貌美肤白、娇憨可爱",
  "tags":["白","富","美"]
}

PUT zhifou/doc/3
{
  "name":"龙套偏房",
  "age":22,
  "from":"gu",
  "desc":"mmp,没怎么看清,不知道怎么形容",
  "tags":["造数据","真","难"]
}

PUT zhifou/doc/4
{
  "name":"石头",
  "age":29,
  "from":"gu",
  "desc":"粗中有细、狐假虎威",
  "tags":["粗","大","猛"]
}

PUT zhifou/doc/5
{
  "name":"魏行者",
  "age":25,
  "from":"广云台",
  "desc":"后悔没能嫁给顾老二~",
  "tags":["闭月","羞花"]
}

must

现在我们使用布尔查询所有from属性为gu的数据

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
GET zhifou/doc/_search
{
  "query":{
    "bool": {
      "must": [
        {
          "match": {
            "from": "gu"
          }
        }
      ]
    }
  }
}

结果如下:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 0.82876295,
    "hits" : [
      {
        "_index" : "zhifou",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.82876295,
        "_source" : {
          "name" : "顾老二",
          "age" : 30,
          "from" : "gu",
          "desc" : "皮肤黑、武器长、性格直",
          "tags" : [
            "黑",
            "长",
            "直"
          ]
        }
      },
      {
        "_index" : "zhifou",
        "_type" : "doc",
        "_id" : "3",
        "_score" : 0.82876295,
        "_source" : {
          "name" : "龙套偏房",
          "age" : 22,
          "from" : "gu",
          "desc" : "mmp,没怎么看清,不知道怎么形容",
          "tags" : [
            "造数据",
            "真",
            "难"
          ]
        }
      },
      {
        "_index" : "zhifou",
        "_type" : "doc",
        "_id" : "4",
        "_score" : 0.82876295,
        "_source" : {
          "name" : "石头",
          "age" : 29,
          "from" : "gu",
          "desc" : "粗中有细、狐假虎威",
          "tags" : [
            "粗",
            "大",
            "猛"
          ]
        }
      }
    ]
  }
}

在上面的例子中,通过bool属性字段内使用must来作为查询条件,这里需要注意的是must字段对应的是个列表,也就是说可以有多个并列的查询条件,一个文档满足各个子条件后才最终返回。

栗子:如果想要查询from为gu,并且年龄为30的数据应该怎样操作?

GET zhifou/doc/_search
{
  "query":{
    "bool": {
      "must": [
        {
          "match": {
            "from": "gu"
          }
        },
        {
          "match": {
            "age": 30
          }
        }
      ]
    }
  }
}

结果返回:

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.828763,
    "hits" : [
      {
        "_index" : "zhifou",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 1.828763,
        "_source" : {
          "name" : "顾老二",
          "age" : 30,
          "from" : "gu",
          "desc" : "皮肤黑、武器长、性格直",
          "tags" : [
            "黑",
            "长",
            "直"
          ]
        }
      }
    ]
  }
}

should

那么,如果查询只要是fromgu或者tags闭月的数据呢?

GET zhifou/doc/_search
{
  "query":{
    "bool": {
      "should": [
        {
          "match": {
            "from": "gu"
          }
        },
        {
          "match": {
            "tags": "闭月"
          }
        }
      ]
    }
  }
}

结果返回:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 1.9854019,
    "hits" : [
      {
        "_index" : "zhifou",
        "_type" : "doc",
        "_id" : "5",
        "_score" : 1.9854019,
        "_source" : {
          "name" : "魏行者",
          "age" : 25,
          "from" : "广云台",
          "desc" : "后悔没能嫁给顾老二~",
          "tags" : [
            "闭月",
            "羞花"
          ]
        }
      },
      {
        "_index" : "zhifou",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.82876295,
        "_source" : {
          "name" : "顾老二",
          "age" : 30,
          "from" : "gu",
          "desc" : "皮肤黑、武器长、性格直",
          "tags" : [
            "黑",
            "长",
            "直"
          ]
        }
      },
      {
        "_index" : "zhifou",
        "_type" : "doc",
        "_id" : "3",
        "_score" : 0.82876295,
        "_source" : {
          "name" : "龙套偏房",
          "age" : 22,
          "from" : "gu",
          "desc" : "mmp,没怎么看清,不知道怎么形容",
          "tags" : [
            "造数据",
            "真",
            "难"
          ]
        }
      },
      {
        "_index" : "zhifou",
        "_type" : "doc",
        "_id" : "4",
        "_score" : 0.82876295,
        "_source" : {
          "name" : "石头",
          "age" : 29,
          "from" : "gu",
          "desc" : "粗中有细、狐假虎威",
          "tags" : [
            "粗",
            "大",
            "猛"
          ]
        }
      }
    ]
  }
}

以上栗子中,只要符合其中一个条件就可返回。

must_not

那么,如果我想要查询from既不是gu并且tags也不是可爱,还有age不是18的数据

GET zhifou/doc/_search
{
  "query":{
    "bool": {
      "must_not": [
        {
          "match": {
            "from": "gu"
          }
        },
        {
          "match": {
            "tags": "可爱"
          }
        },
        {
          "match": {
            "age": 18
          }
        }
      ]
    }
  }
}

结果返回:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.0,
    "hits" : [
      {
        "_index" : "zhifou",
        "_type" : "doc",
        "_id" : "5",
        "_score" : 0.0,
        "_source" : {
          "name" : "魏行者",
          "age" : 25,
          "from" : "广云台",
          "desc" : "后悔没能嫁给顾老二~",
          "tags" : [
            "闭月",
            "羞花"
          ]
        }
      }
    ]
  }
}

以上例子中,只有魏行者满足要求,因为魏行者既不是顾家的人

,标签里也没有可爱的那一项,年龄也不等于18~

filter

那么,要查询fromguage大于25的数据该怎么查?

GET zhifou/doc/_search
{
  "query":{
    "bool": {
      "must": [
        {
          "match": {
            "from": "gu"
          }
        }
      ],
      "filter": {
        "range": {
          "age": {
            "gt":25
            
          }
        }
      }
    }
  }
}

结果返回:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 0.82876295,
    "hits" : [
      {
        "_index" : "zhifou",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.82876295,
        "_source" : {
          "name" : "顾老二",
          "age" : 30,
          "from" : "gu",
          "desc" : "皮肤黑、武器长、性格直",
          "tags" : [
            "黑",
            "长",
            "直"
          ]
        }
      },
      {
        "_index" : "zhifou",
        "_type" : "doc",
        "_id" : "4",
        "_score" : 0.82876295,
        "_source" : {
          "name" : "石头",
          "age" : 29,
          "from" : "gu",
          "desc" : "粗中有细、狐假虎威",
          "tags" : [
            "粗",
            "大",
            "猛"
          ]
        }
      }
    ]
  }
}

小结:

  • must:与关系,相当于and
  • Should:或关系,相当于or
  • must_not:非关系,相当于not
  • filter:过滤条件
  • range:条件筛选范围
  • gt(getter than):大于
  • gte(geeter than equals):大于等于
  • lt(less than):小于
  • lte(less than equals):小于等于
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄