Elasticsearch 组合查询的使用

这里介绍Elasticsearch 中的组合查询的使用细节,Elasticsearch支持类似于在SQL中使用AND、OR以及NOT的运算符,可以通过组合嵌套这些条件进行复杂的数据筛选。

数据准备

复用上篇文章的mapping和数据供这里的demo使用。
mapping:

PUT /phones
{
  "mappings": {
    "properties": {
      "price":{
        "type":"long"
      },
      "color":{
        "type": "keyword"
      },
      "brand":{
        "type": "keyword"
      },
      "release_date":{
        "type": "date"
      }
    }
  }
}

数据:

PUT /phones/_bulk
{"index":{}}
{"price":100,"color":"白色","brand":"小米","release_date":"2022-02-06"}
{"index":{}}
{"price":150,"color":"白色","brand":"小米","release_date":"2022-02-06"}
{"index":{}}
{"price":200,"color":"黑色","brand":"小米","release_date":"2022-02-08"}
{"index":{}}
{"price":250,"color":"黑色","brand":"小米","release_date":"2022-02-08"}
{"index":{}}
{"price":300,"color":"白色","brand":"华为","release_date":"2022-02-08"}
{"index":{}}
{"price":400,"color":"黑色","brand":"华为","release_date":"2022-02-10"}
{"index":{}}
{"price":500,"color":"灰色","brand":"华为","release_date":"2022-02-11"}
{"index":{}}
{"price":250,"color":"白色","brand":"苹果","release_date":"2022-02-11"}
filter的用法

在使用filter查询的时候,会使用一个二进制数组bitset保存倒排索引中的document list,符合条件的document置为1,不符合的document对应的位置为0,并且会将filter的bitset缓存起来,相同的filter条件进来的话会直接读取之前的bitset缓存,当document有新增或者修改的时候,Elasticsearch会维护对应的bitset。
filter是仅仅过滤需要的数据,不会使用TF/IDF进行分数计算。
filter会在普通的query之前执行,这是filter的效率更快,可以先过滤掉一些数据。

组合查询中的使用:查询品牌是小米,且价格大于等于200的手机。

GET /phones/_search
{
    "query":{
        "bool":{
            "must":{
                "term":{
                    "brand":"小米"
                }
            },
            "filter":{
                "range":{
                    "price":{
                        "gte":200
                    }
                }
            }
        }
    }
}

单独使用filter:搜索价格大于400的手机。
query里面不能直接用filter,需要包一层constant_score,表示忽略评分

GET /phones/_search
{
    "query":{
        "constant_score":{
            "filter":{
                "range":{
                    "price":{
                        "gte":400
                    }
                }
            }
        }
    }
}
bool组合查询

在bool中可以嵌套should、must、must_not,它们分别sql中的or、and、not条件。

搜索品牌是小米或者华为且发布日期不能是2022-02-08的手机。

GET /phones/_search
{
    "query":{
        "constant_score":{
            "filter":{
                "bool":{
                    "should":[
                        {
                            "term":{
                                "brand":"小米"
                            }
                        },
                        {
                            "term":{
                                "brand":"华为"
                            }
                        }
                    ],
                    "must_not":[
                      {
                          "term":{
                            "release_date":"2022-02-08"
                          }
                      }
                    ]
                }
            }
        }
    }
}

搜素品牌是苹果 或者品牌是小米且颜色为黑色的手机

GET /phones/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "brand": {
              "value": "苹果"
            }
          }
        },
        {
          "bool": {
            "must": [
              {
                "term": {
                  "brand": {
                    "value": "小米"
                  }
                }
              },
              {
                "term": {
                  "color": {
                    "value": "黑色"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}
should和must 用法的总结

must和should平级的话,should的条件是不参与过滤数据的,只参与分数计算。这时的分数是must和should搜索对应的分数加起来除以must和should的总和。
默认情况下should的条件是可以一个都不满足的,可以通过mininum_should_match指定should中必须满足的条件个数。当没有must的时候,should必须匹配一个。

单独使用should:查询发布日期是2022-02-10或2022-02-11的手机

GET /phones/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "release_date": {
              "value": "2022-02-10"
            }
          }
        },
        {
          "term": {
            "release_date": {
              "value": "2022-02-11"
            }
          }
        }
      ]
    }
  }
}

should和must同时使用,可以看到不存在满足should中条件的数据,但只要满足must条件的数据都会被返回。

GET /phones/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "brand": {
              "value": "三星"
            }
          }
        },
        {
          "term": {
            "color": {
              "value": "绿色"
            }
          }
        }
      ],
      "must": [
        {
          "term": {
            "price": {
              "value": 250
            }
          }
        }
      ]
    }
  }
}
评分权重自定义

默认情况下每个must和should条件的权重都是1,可以通过boost进行权重的修改。

这里必须要满足的条件是发布时间为2022-02-08,由于是term查询所以分数最低的是1,价格为200所占评分权重最高。

GET /phones/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "release_date": {
              "value": "2022-02-08"
            }
          }
        }
      ],
      "should": [
        {
          "term": {
            "brand": {
              "value": "华为"
              , "boost": 2
            }
          }
        },
        {
          "term": {
            "price": {
              "value": "200",
              "boost": 5
            }
          }
        }
      ]
    }
  }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值