首页 > 解决方案 > 如何忽略具有空值或不存在的嵌套对象

问题描述

我有以下聚合查询。

{
    "aggs": {
        "selected_brand": {
            "filter": {
                "term": {
                    "brandId": "b1d28821-3730-4266-8f55-eb69596004fb"
                }
            }
        },
        "sponsorshipSets": {
            "nested": {
                "path": "sponsorshipSets"
            },
            "aggs": {
                "sponsorships": {
                    "nested": {
                        "path": "sponsorshipSets.sponsorships"
                    },
                    "aggs": {
                        "count": {
                            "value_count": {
                                "field": "sponsorshipSets.sponsorships.id"
                            }
                        }
                    }
                }
            }
        }
    }
}

响应如下。

{
  "hits": {
    "total": {
      "value": 2980,
      "relation": "eq"
    }
  },
  "aggregations": {
    "selected_brand": {
      "doc_count": 314
    },
    "sponsorshipSets": {
      "doc_count": 2635,
      "sponsorships": {
        "doc_count": 1076,
        "count": {
          "value": 1076
        }
      }
    }
  }
}

响应显示赞助文档的数量为 1076,现在我想检索这些文档的文档并尝试使用以下查询。

{
    "query": {
        "bool": {
            "must": {
                "nested": {
                    "path": "sponsorshipSets",
                    "query": {
                        "nested": {
                            "path": "sponsorshipSets.sponsorships",
                            "query": {
                                "bool": {
                                    "must_not": [
                                        {
                                            "match": {
                                                "sponsorshipSets.sponsorships": "null"
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            },
            "filter": [
                {
                    "term": {
                        "brandId": "b1d28821-3730-4266-8f55-eb69596004fb"
                    }
                }
            ]
        }
    }
}

第二个查询的有趣之处在于下面的点击量只有 82。

"hits": {
    "total": {
      "value": 82,
      "relation": "eq"
    },

我真正想要的是检索所有不为空或不存在的ponsorshipSets.sponsorships 文档的计数。SponsorshipSets 也可能会丢失。

在缩写模板下方找到。

{
  "index_patterns": "campaigns*",
  "order": 4,
  "version": 4,
  "aliases": {
    "campaigns": {

    }
  },
  "settings": {
    "number_of_shards": 5
  },
  "mappings": {
    "dynamic": "false",
    "properties": {
      "brandId": {
        "type": "keyword"
      },
      "sponsorshipSets": {
        "type": "nested",
        "properties": {
          "id": {
            "type": "keyword"
          },
          "sponsorships": {
            "type": "nested",
            "properties": {
              "id": {
                "type": "keyword"
              }
            }
          }
        }
      }
    }

标签: elasticsearch

解决方案


您可以使用exists查询来过滤此类文档。下面的查询应该有帮助。

查询请求:

POST <your_index_name>/_search
{
   "query":{
      "bool":{
         "must":{
            "nested":{
               "path":"sponsorshipSets",
               "query":{
                  "nested":{
                     "path":"sponsorshipSets.sponsorships",
                     "query":{
                        "bool":{
                           "must_not":[
                              {
                                 "exists":{
                                    "field":"sponsorshipSets.sponsorships"
                                 }
                              }
                           ]
                        }
                     }
                  }
               }
            }
         },
         "filter":[
            {
               "term":{
                  "brandId":"b1d28821-3730-4266-8f55-eb69596004fb"
               }
            }
         ]
      }
   }
}

这应该返回您的文档 JSON 结构的所有三种情况

  • sponsorshipSets.sponsorships: {}即你有空结构sponsorships

  • sponsorshipSets.sponsorships: null即值设置为null

  • 或者您的文档首先没有sponsorships字段。

您不需要为此使用任何聚合,因为 ES 会返回hits.total.value响应中此类文档的计数。

让我知道这是否有帮助!


推荐阅读