ElasticSearch:聚合以从数组中的对象中的数组中的对象获取 属性 值

ElasticSearch: Aggregation to get property values from object-in-array that is in an object which is in array

GOAL: Get the values associated with the characteristic named "ram"


示例Object/Schema:

展示路径:product{}.characteristics[].values[]

    Product {
      "characteristics": [  //1st level      
        { //1st level object
          "name": "ram",
          "values": [ //2nd level
            {"value": 2}, //to be returned in aggregation
            {"value": 4} //to be returned in aggregation
          ]
        }
      ]
    }

文件:

{
        "_index": "product",
        "_type": "_doc",
        "_id": "18",
        "_score": 1.0,
        "_source": {
          "doc": {
            "id": 18,
            "name": "iphone_11",
            "localizedName": [
              {
                "locale": "en-US",
                "value": "iPhone 11"
              }
            ],
            "productType": null,
            "shops": [
              
            ],
            "characteristics": [
              {
                "name": "ram",
                "values": [
                  {
                    "value": "2",
                    "localizedValues": [
                      
                    ]
                  },
                  {
                    "value": "4",
                    "localizedValues": [
                      
                    ]
                  }
                ],
                "localizedName": [
                  {
                    "id": 15,
                    "locale": "en-US",
                    "value": "Ram"
                  }
                ]
              }
            ]
          }
        }
      }

映射:


    {
        "product": {
            "mappings": {
                "properties": {
                    "doc": {
                        "properties": {
                            "characteristics": {
                                "type": "nested",
                                "properties": {
                                    "localizedName": {
                                        "properties": {
                                            "id": {
                                                "type": "long"
                                            },
                                            "locale": {
                                                "type": "text",
                                                "fields": {
                                                    "keyword": {
                                                        "type": "keyword",
                                                        "ignore_above": 256
                                                    }
                                                }
                                            },
                                            "value": {
                                                "type": "text",
                                                "fields": {
                                                    "keyword": {
                                                        "type": "keyword",
                                                        "ignore_above": 256
                                                    }
                                                }
                                            }
                                        }
                                    },
                                    "name": {
                                        "type": "text",
                                        "fields": {
                                            "keyword": {
                                                "type": "keyword",
                                                "ignore_above": 256
                                            }
                                        }
                                    },
                                    "values": {
                                        "type": "nested",
                                        "properties": {
                                            "value": {
                                                "type": "text",
                                                "fields": {
                                                    "keyword": {
                                                        "type": "keyword",
                                                        "ignore_above": 256
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            },
                            "id": {
                                "type": "long"
                            },
                            "name": {
                                "type": "text",
                                "fields": {
                                    "keyword": {
                                        "type": "keyword",
                                        "ignore_above": 256
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }


当前聚合遍历:


    {
      "size": 0,
      "aggs": {
        "characteristics": {
          "nested": {
            "path": "characteristics"
          },
          "aggs": {
            "ram": {
              "filter": {
                "bool": {
                  "must": [
                    {
                      "term": {
                        "characteristics.name": "ram"
                      }
                    }
                  ]
                }
              },
              "aggs": {
                "values": {
                  "nested": {
                    "path": "characteristics.values"
                  },
                  "aggs": {
                    "all_values": {
                      "terms": {
                        "field": "characteristics.values.value"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }

回复:


    {
        "took": 2,
        "timed_out": false,
        "_shards": {
            "total": 1,
            "successful": 1,
            "skipped": 0,
            "failed": 0
        },
        "hits": {
            "total": {
                "value": 0,
                "relation": "eq"
            },
            "max_score": null,
            "hits": []
        },
        "aggregations": {
            "characteristics": {
                "meta": {},
                "doc_count": 0,
                "ram": {
                    "meta": {},
                    "doc_count": 0,
                    "values": {
                        "doc_count": 0,
                        "all_values": {
                            "doc_count_error_upper_bound": 0,
                            "sum_other_doc_count": 0,
                            "buckets": []
                        }
                    }
                }
            }
        }
    }

这似乎适用于 Elasticsearch 7.15(基于您的第二个示例):

{
  "size": 0,
  "aggs": {
    "characteristics": {
      "nested": {
        "path": "characteristics"
      },
      "aggs": {
        "ram": {
          "filter": {
            "bool": {
              "must": [
                {
                  "term": {
                    "characteristics.name": "ram"
                  }
                }
              ]
            }
          },
          "aggs": {
            "values": {
              "nested": {
                "path": "characteristics.values"
              },
              "aggs": {
                "all_values": {
                  "terms": {
                    "field": "characteristics.values.value"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

虽然这很复杂,但创建一个额外的“属性值”索引可能有意义,该索引将为每个属性值创建一个文档,同时包含属性名称和产品 id/name?那么聚合就会变得更简单。