美文网首页
ElasticSearch 使用详解:组合查询怎么玩

ElasticSearch 使用详解:组合查询怎么玩

作者: you的日常 | 来源:发表于2021-12-22 16:12 被阅读0次

    查询是一个复杂过程,特别是当查询过程中有多个条件,在 ES 中当有多个条件的时候,就得使用组合查询了。

    组合查询是通过 bool 关键字来实现的,通过 mustmust_notshould 将不同的条件组合到一起,再用 bool 包裹一下作为一个整体。用来实现各种且、非、或的条件组合。

    “且”条件

    给定需求:

    查询 class 索引中姓 deng 并且年龄是 16 的学生。

    下面的查询语句中不难看出,bool 包裹了条件整体,使用 must 组合两个条件实现了“且”。

    GET class/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "name": "deng"
              }
            },
            {
              "term": {
                "age": 16
              }
            }
          ]
        }
      }
    }
    
    
    image

    “非”条件

    给定需求:

    查找姓名中不包含 deng,且年龄要大于 16 岁的。

    下面这条查询语句,使用 must_not 不难理解是对里面的条件做了一个“非”操作。首先使用 match Phrase查询姓名中包含 deng 的,然后再用范围查询,查询年龄小于 16 的,再取个“非”,达到了我们想要的效果。

    GET class/_search
    {
      "query": {
        "bool": {
          "must_not": [
            {
              "match": {
                "name": "deng"
              }
            },
            {
              "range": {
                "age": {
                  "lte": 16
                }
              }
            }
          ]
        }
      }
    }
    
    
    image

    “或”条件

    给定需求:

    查询性别为“男性”或者“女性”的学生数据。

    因为性别是确定的字符串,要么是 man 要么是 female,所以这是一个精确值查询的需求,因此使用 term 查询,并且因为是 sex 的字段类型是“字符串”所以加上 keyword。(这里思考一下,上个课时中说了如果不加 keyword 将不会返回查询结果,但是这里如果把 keyword 去掉也能查询相同的数据,请问是为什么?结合上节课对 keyword 的解释,你一定会找到答案的。)

    GET class/_search
    {
      "query": {
        "bool": {
          "should": [
            {
              "term": {
                "sex.keyword": "man"
              }
            },
            {
              "term": {
                "sex.keyword":"female"
              }
            }
          ]
        }
      }
    }
    
    
    image

    对于性别的过滤这里使用了两个 term 查询,但是是对同一个字段做出的判断,写两个 term 查询条件显得比较繁琐,这里对于同一个字段的条件判断有更简洁的写法,就是把条件放到数组中去。

    这里有两个地方需要注意,第一就是 terms 而不是之前的 term,第二个就是字段后面加的是数组,而不是之前的花括号。

    GET class/_search
    {
      "query": {
        "bool": {
          "should": [
            {
              "terms": {
                "sex.keyword": [
                  "man",
                  "famale"
                ]
              }
            }
          ]
        }
      }
    }
    
    

    mustshould 的组合

    这里一定要注意,ES 中的条件组合跟 SQL 的逻辑稍微有点不同,ES 中 mustshould 不能够同时使用,当使用了 must 后,should 将不会在发生作用

    因为 should 只是一个增加相关性分数的一个条件,当你只使用 should 的时候,如果不满足条件,那么相关性分数会比较低,就不会返回数据给你。像下面这个条件,稍微把性别改成一个不存在的 a 和 b,跟我们想的一样,并没有返回任何数据。

    GET class/_search
    {
      "query": {
        "bool": {
          "should": [
            {
              "terms": {
                "sex.keyword": [
                  "a",
                  "b"
                ]
              }
            }
          ]
        }
      }
    }
    
    
    image

    这里我再加上一个 must 条件做测试,结果返回了很多数据,仔细观察 _score 字段都是有值的,这些值都是来源于 must 条件,should 条件因为没有满足的所以对 _score 没有任何贡献,因此 should 字段只是能影响 _score 字段,当其他条件能够给 _score 字段带来相关性分数时候,should 条件将不会对查询结果有任何贡献,只能够让 _score 变得大一点或者没有。

    GET class/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "name": "deng"
              }
            }
          ],
          "should": [
            {
              "terms": {
                "sex.keyword": [
                  "a",
                  "b"
                ]
              }
            }
          ]
        }
      }
    }
    
    
    image

    这个问题怎么解决呢?mustshould 组合是经常会遇到的问题。

    相关文章

      网友评论

          本文标题:ElasticSearch 使用详解:组合查询怎么玩

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