ElasticSearch 聚合嵌套字段作为父文档的一部分

ElasticSearch aggregate nested fields as part of parent document

我有 Product 个实体和嵌套的 Variation 个实体的索引。 Product 实体由 IdTitle 和嵌套变体组成。 Variation 实体由 ColorSizePrice 字段组成。我需要按 ColorSizePrice 字段汇总搜索结果,以获得每个颜色、尺寸和价格组的产品数量。如果我对这些字段使用嵌套聚合,我会得到正确的 bucket,但 bucket 中的文档数量是每个 bucket 的 Variation 个实体数。但我需要获取每个存储桶的 Product 个实体(根文档)的数量。

例如,第一个产品有变体(红色、小号、10 美元)、(绿色、小号、10 美元)、(红色、中号、11 美元),第二个产品有变体(绿色、中号、15 美元)。嵌套聚合 returns 2 for red and 2 for small because 2 variations has red color and small size.但是我需要每个桶的产品(根实体)数量,red 应该是 1,small.

应该是 1

由于其他要求,我也不能使用子文档代替嵌套文档。

如何编写查询以获得此结果?

这是映射:

{
  "product": {
    "properties": {
      "id": {
        "type": "long"
      },
      "title": {
        "type": "string"
      },
      "brand": {
        "type": "string"
      },
      "variations": {
        "type": "nested",
        "properties": {
          "id": {
            "type": "long"
          },
          "colour": {
            "type": "string"
          },
          "size": {
            "type": "string"
          },
          "price": {
            "type": "double"
          }
        }
      },
      "location": {
        "type": "geo_point"
      }
    }
  }
}

这是一个查询

{
  "aggs": {
    "Variations": {
      "nested": {
        "path": "variations"
      },
      "aggs": {
        "Colous": {
          "terms": {
            "field": "variations.colour"
          }
        },
        "Sizes": {
          "terms": {
            "field": "variations.size"
          }
        }
      }
    },
    "Brands": {
      "terms": {
        "field": "brand"
      }
    }
  },
  "query": {
    "match_all": {}
  }
}

Brand 聚合效果很好,因为它获取每个组的根文档数,但嵌套聚合 return 嵌套文档数而不是根文档数。

您以正确的方式解决了问题。现在您可以简单地使用 reverse_nested aggregation 来 "join back" 到根产品,并为您的变体获取每个匹配产品的数量。

{
  "aggs": {
    "Variations": {
      "nested": {
        "path": "variations"
      },
      "aggs": {
        "Colous": {
          "terms": {
            "field": "variations.colour"
          },
          "aggs": {
            "product_count": {            <--- add this reverse nested agg
              "reverse_nested": {}
            }
          }
        },
        "Sizes": {
          "terms": {
            "field": "variations.size"
          },
          "aggs": {
            "product_count": {            <--- add this reverse nested agg
              "reverse_nested": {}
            }
          }
        }
      }
    },
    "Brands": {
      "terms": {
        "field": "brand"
      }
    }
  },
  "query": {
    "match_all": {}
  }
}

在回复中,您会看到:

  • 2 个产品匹配 colour: green
  • 1 个产品匹配 colour: red
  • 2 个产品匹配 size: medium
  • 1 个产品匹配 size: small