• Elasticsearch 复合查询——多字符串多字段查询


    前言

    有时我们在搜索电影的时候,包含了多个条件,比如主演是周星驰,打分8分以上,上映时间是1990年~2001年的,那么Elasticsearch又该如何帮我们做查询呢?这里我们可以用 bool 查询来实现需求。这种查询将多查询组合在一起,成为用户自己想要的 bool 查询。

    bool 查询

    一个 bool 查询,可以包含一个或多个查询语句进行组合。

    有4种参数

    • must:文档必须匹配这些条件才能被包含进来。贡献算分。
    • should:文档选择性匹配,如果满足这些语句中的任意语句,将增加 _score ,否则,无任何影响。贡献算分。
    • must_not:文档必须不匹配这些条件才能被包含进来。
    • filter:必须 匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档。不贡献算分。

    基本语法

    • bool 里面的子查询继续嵌套 bool 查询
    • 子查询可以以任意顺序出现
    • 如果没有 must 语句,那么至少需要能够匹配其中的一条 should 语句。但如果存在至少一条 must 语句,则对 should 语句的匹配没有要求。
    • must等可以跟一个对象(“{}”),也可以跟数组(“[]”)
    {
        "bool": {
            "must":     { "match": { "title": "how to make millions" }},
            "must_not": { "match": { "tag":   "spam" }},
            "should": [
                { "match": { "tag": "starred" }}
            ],
            "filter": {
              "bool": { 
                  "must": [
                      { "range": { "date": { "gte": "2014-01-01" }}},
                      { "range": { "price": { "lte": 29.99 }}}
                  ],
                  "must_not": [
                      { "term": { "category": "ebooks" }}
                  ]
              }
            }
        }
    }
    

    一个航班查询的例子,搜索去往美国的,当地天气是晴朗的,不从日本出发的,票价小于等于1000的航班。

    GET kibana_sample_data_flights/_search
    {
      "size": 5,
      "query": {
        "bool": {
          "must": [
            {
              "term": {
                "DestCountry": "US"
              }
            },
            {
              "term": {
                "DestWeather": "Sunny"
              }
            }
          ],
          "must_not": {
            "term": {
                "OriginCountry": "JP"
              }
          }, 
          "filter": {
            "range": {
              "AvgTicketPrice": {
                "lte": 1000
              }
            }
          }
        }
      }
    }
    

    控制相关性

    那么多个字段的查询,我们该如何影响其相关性的算分呢?

    层级嵌套

    同一层级下的字段是竞争关系,具有相同权重,可以通过嵌套改变对算分的影响。

    GET animals/_search
    {
      "query": {
        "bool": {
          "should": [
            {"term": {"text": "brown"}},
            {"term": {"text": "red"}},
            {"term": {"text": "quick"}},
            {"term": {"text": "dog"}}
          ]
        }
      }
    }
    
    GET animals/_search
    {
      "query": {
        "bool": {
          "should": [
            {"term": {"text": "brown"}},
            {"term": {"text": "red"}},
            {"bool": {
                "should": [
                    {"term": {"text": "quick"}},
                    {"term": {"text": "dog"}}
                ]
              }
            }
          ]
        }
      }
    }
    

    boosting

    控制字段的权重,可以使用boosting,默认值是1,可正可负。

    • 当boost>1时,打分的相关性相对提升
    • 当0<boost<1时,打分的相关性相对降低
    • 当boost<0时,贡献负分

    精简语法,可以在match里面指定boost,比如上面的航班信息DestCountry部分字段设置权重。

    GET kibana_sample_data_flights/_search
    {
      "explain": true,
      "size": 5,
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "DestCountry": {
                  "query": "US",
                  "boost": 10
                }
              }
            },
            {
              "term": {
                "DestWeather": "Sunny"
              }
            }
          ],
          "must_not": {
            "term": {
              "OriginCountry": "JP"
            }
          },
          "filter": {
            "range": {
              "AvgTicketPrice": {
                "lte": 1000
              }
            }
          }
        }
      }
    }
    

    完整boosting语法,positive正向作用,negative负向作用,negative_boost负向作用的权重,可以用来降级匹配的文档,不像“NOT”逻辑运算直接去除相关的文档

    GET movies/_search
    {
      //"explain": true, 
      "query": {
        "boosting": {
          "positive": {
            "term": {
              "title": {
                "value": "beautiful"
              }
            }
          },
          "negative": {
            "term": {
              "title": {
                "value": "mind"
              }
            }
          },
          "negative_boost": 0.2
        }
      }
    }
    

    constant_score 查询

    尽管没有 bool 查询使用这么频繁,constant_score 查询也是我们工具箱里有用的查询工具。它将一个不变的常量评分应用于所有匹配的文档。它被经常用于你只需要执行一个 filter 而没有其它查询(例如,评分查询)的情况下。

    GET movies/_search
    {
      "query": {
        "constant_score": {
          "filter": {
            "term": {
              "title": "beautiful"
            }
          }
        }
      }
    }
    

    参考资料

    __EOF__

     


     

    欢迎转载,但请注明出处!
    欢迎大家一起交流学习!如果有什么疑问,大家可以在评论区一起交流!
    如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是我的最大动力!

  • 相关阅读:
    iOS数据持久化的方式
    Runtime
    <02>
    <01>
    <02>
    UIActivityIndicatorView
    <01>数据存储
    UI<10>
    UI<09>
    UI<08>
  • 原文地址:https://www.cnblogs.com/powercto/p/14532963.html
Copyright © 2020-2023  润新知