Elastic Search 嵌套查询不处理多个 MUST 查询

问题描述 投票:0回答:1

我有一个 ES 6.5 索引,具有以下映射 -

{
  "hotel": {
    "mappings": {
      "hotel": {
        "properties": {
          "hotelAmenities": {
            "type": "nested",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "featured": {
                "type": "boolean"
              },
              "key": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "name": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              }
            }
          },
          "hotelStatus": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "name": {
            "type": "text",
            "fields": {
              "verbatim": {
                "type": "keyword"
              }
            },
            "analyzer": "english"
          }
        }
      }
    }
  }
}

样本文件-

{
  "name": "Hotel with amenities",
  "hotelStatus": "BOOKABLE",
  "hotelAmenities": [
    {
      "key": "POOL",
      "name": "Pool",
      "enabled": true,
      "featured": true
    },
    {
      "key": "LAUNDRY",
      "name": "Laundry",
      "enabled": true,
      "featured": true
    }
  ]
}

我使用嵌套查询来定位 hotelAmenities 字段,其目的是建立 AND 关系(酒店有 POOL 和 LAUNDRY 设施),但仅在搜索单个嵌套字段时才有效。

{
  "from": 0,
  "size": 200,
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "query": {
              "bool": {
                "must": [
                  // ONLY 1 works here
                  {
                    "match": {
                      "hotelAmenities.name": "laundry"
                    }
                  },
                  {
                    "match": {
                      "hotelAmenities.name": "pool"
                    }
                  }
                ],
                "adjust_pure_negative": true,
                "boost": 1.0
              }
            },
            "path": "hotelAmenities",
            "ignore_unmapped": false,
            "score_mode": "max",
            "boost": 1.0
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "hotelStatus": {
              "query": "DECOMMISSIONED",
              "operator": "OR",
              "prefix_length": 0,
              "max_expansions": 50,
              "fuzzy_transpositions": true,
              "lenient": false,
              "zero_terms_query": "NONE",
              "auto_generate_synonyms_phrase_query": true,
              "boost": 1.0
            }
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1.0
    }
  },
  "post_filter": {
    "geo_distance": {
      ...
    }
  },
  "version": true
}

我还尝试在这样的嵌套字段上使用

query
方法,它表现出相同的行为,即只能搜索一个嵌套便利设施。

{
  "from": 0,
  "size": 200,
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "query": {
              "bool": {
                "must": [
                  // ONLY 1 works here
                  {
                    "match": {
                      "hotelAmenities.name": {
                        "query": "laundry",
                        "operator": "OR",
                        "prefix_length": 0,
                        "max_expansions": 50,
                        "fuzzy_transpositions": true,
                        "lenient": false,
                        "zero_terms_query": "NONE",
                        "auto_generate_synonyms_phrase_query": true,
                        "boost": 1.0
                      }
                    }
                  },
                  {
                    "match": {
                      "hotelAmenities.name": {
                        "query": "pool",
                        "operator": "OR",
                        "prefix_length": 0,
                        "max_expansions": 50,
                        "fuzzy_transpositions": true,
                        "lenient": false,
                        "zero_terms_query": "NONE",
                        "auto_generate_synonyms_phrase_query": true,
                        "boost": 1.0
                      }
                    }
                  }
                ],
                "adjust_pure_negative": true,
                "boost": 1.0
              }
            },
            "path": "hotelAmenities",
            "ignore_unmapped": false,
            "score_mode": "max",
            "boost": 1.0
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "hotelStatus": {
              "query": "DECOMMISSIONED",
              "operator": "OR",
              "prefix_length": 0,
              "max_expansions": 50,
              "fuzzy_transpositions": true,
              "lenient": false,
              "zero_terms_query": "NONE",
              "auto_generate_synonyms_phrase_query": true,
              "boost": 1.0
            }
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1.0
    }
  },
  "post_filter": {
    "geo_distance": {
      ...
    }
  },
  "version": true
}

如果我在示例中删除其中一个或另一个,则可以正确找到文档。这可能是什么原因造成的?

elasticsearch nested
1个回答
0
投票

每个嵌套元素都存储在其自己的内部文档中,因此如果对这些元素有多个约束,则每个约束需要一个嵌套查询,如下所示:

   "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "query": {
              "match": {
                "hotelAmenities.name": "laundry"
              }
            },
            "path": "hotelAmenities",
            "ignore_unmapped": false,
            "score_mode": "max",
            "boost": 1
          }
        },
        {
          "nested": {
            "query": {
              "match": {
                "hotelAmenities.name": "pool"
              }
            },
            "path": "hotelAmenities",
            "ignore_unmapped": false,
            "score_mode": "max",
            "boost": 1
          }
        }
      ],
© www.soinside.com 2019 - 2024. All rights reserved.