首页 > 解决方案 > ElasticSearch 应该嵌套和 bool must_not 存在

问题描述

使用以下映射:

"categories": {
  "type": "nested",
  "properties": {
      "category": {
          "type": "integer"
      },
      "score": {
          "type": "float"
      }
  }
},
 

我想使用该categories字段返回以下文件:

这是我的查询:

{
  "query": {
    "bool": {
      "should": [
        {
          "nested": {
            "path": "categories",
            "query": {
              "bool": {
                "must": [
                  {
                    "terms": {
                      "categories.category": [
                        <id>
                      ]
                    }
                  },
                  {
                    "range": {
                      "categories.score": {
                        "gte": 0.5
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "bool": {
            "must_not": [
              {
                "exists": {
                  "field": "categories"
                }
              }
            ]
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}

它正确返回带有和不带有类别字段的文档,并对结果进行排序,以便我想要的结果排在第一位,但它不会过滤得分低于 0.5 阈值的结果。

标签: elasticsearch

解决方案


好问题。

那是因为categories从弹性搜索的角度来看,它并不完全是一个字段[在其上创建倒排索引并用于查询/搜索的字段],而是categories.categoryand categories.scoreis。

结果categories在任何文档中都找不到,这实际上对所有文档都是正确的,您可以观察您所看到的结果。

将查询修改为以下内容,您会看到您的用例正常工作。

POST <your_index_name>/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "nested": {
            "path": "categories",
            "query": {
              "bool": {
                "must": [
                  {
                    "terms": {
                      "categories.category": [
                        "100"
                      ]
                    }
                  },
                  {
                    "range": {
                      "categories.score": {
                        "gte": 0.5
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "bool": {
            "must_not": [                        <----- Note this
              {
                "nested": {
                  "path": "categories",
                  "query": {
                    "bool": {
                      "must": [
                        {
                          "exists": {
                            "field": "categories.category"
                          }
                        },
                        {
                          "exists": {
                            "field": "categories.score"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}

推荐阅读