Elasticsearch 聚合以检索与另一个值关联的值数组

Elasticsearch aggregation to retrieve array of values associated with another value

我正在使用 Elasticsearch 索引处理这样的数据:

"_source": {
    "article_number": "123456",
    "title": "Example item #1",
    "attributes": [
        {
            "key": "Type",
            "value": "Bag"
        },
        {
            "key": "Color",
            "value": "Grey"
        }
    ]
},

"_source": {
    "article_number": "654321",
    "title": "Example item #2",
    "attributes": [
        {
            "key": "Type",
            "value": "Bag"
        },
        {
            "key": "Color",
            "value": "Red"
        }
    ]
}

目标是在页面中动态生成搜索输入,其中每个 attributes.key 的唯一值都有一个搜索输入,并且在该输入中每个相应的 attributes.value 值都有一个值。因此,在这种情况下,我想渲染一个仅提供值“Bag”的“Type”输入和一个提供值“Grey”和“Red”的“Color”输入。

我正在尝试通过聚合来完成此操作,该聚合将为我提供一组唯一的 attributes.key 的所有值以及与每个键关联的 attributes.value 的所有值的数组.符合我希望的结果示例如下:

{
    [
        {
            "key": "Type",
            "values": [{
                "name": "Bag",
                "doc_count": 2
            }]
        },
        {
            "key": "Color",
            "values": [{
                "name": "Grey",
                "doc_count": 1
            },
            {
                "name": "Red",
                "doc_count": 1
            }]
        }
}

我尝试过嵌套和反向嵌套聚合,以及复合聚合,但到目前为止都没有成功。

假设您的索引映射如下所示:

PUT attrs
{
  "mappings": {
    "properties": {
      "attributes": {
        "type": "nested",
        "properties": {
          "key": {
            "type": "keyword"
          },
          "value": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

您可以通过以下 nested terms aggregation and its sub-aggregation 的组合来达到预期的效果:

POST attrs/_search
{
  "size": 0,
  "aggs": {
    "nested_context": {
      "nested": {
        "path": "attributes"
      },
      "aggs": {
        "by_keys": {
          "terms": {
            "field": "attributes.key",
            "size": 10
          },
          "aggs": {
            "by_values": {
              "terms": {
                "field": "attributes.value",
                "size": 10
              }
            }
          }
        }
      }
    }
  }
}