MST
星途 面试题库

面试题:ElasticSearch聚合查询中如何处理嵌套文档的结果分析

假设你有一个ElasticSearch索引,其中文档包含嵌套对象。例如,一个“订单”文档包含多个“订单项”的嵌套数组。请描述如何使用聚合查询统计每个订单的订单项总数,并分析聚合结果的结构。
11.3万 热度难度
数据库ElasticSearch

知识考点

AI 面试

面试题答案

一键面试
  1. 使用聚合查询统计每个订单的订单项总数

    • 在Elasticsearch中,可以使用nested聚合来处理嵌套对象。以下是一个示例的聚合查询DSL(Domain - Specific Language):
    {
        "aggs": {
            "order_item_count": {
                "nested": {
                    "path": "order_items"
                },
                "aggs": {
                    "total_items_per_order": {
                        "value_count": {
                            "field": "order_items.id"
                        }
                    }
                }
            }
        }
    }
    
    • 解释:
      • nested聚合:因为“订单项”是嵌套在“订单”文档中的,所以首先使用nested聚合,path指定为嵌套对象的路径,这里是order_items
      • value_count聚合:在nested聚合内部,使用value_count聚合来统计每个订单中订单项的数量。field指定为嵌套对象中某个字段,这里假设订单项有id字段,只要该字段有值,就会被统计。
  2. 聚合结果的结构

    • 聚合结果会有如下结构:
    {
        "aggregations": {
            "order_item_count": {
                "doc_count": 100, // 包含订单项的订单文档数量(假设有100个相关订单文档)
                "total_items_per_order": {
                    "value": 500 // 所有订单中订单项的总数
                }
            }
        }
    }
    
    • 解释:
      • order_item_count:这是外层nested聚合的名称,它包含了关于嵌套对象聚合的相关信息。
        • doc_count:表示包含嵌套对象(订单项)的文档(订单)数量。
        • total_items_per_order:这是内层value_count聚合的名称,其value字段表示所有订单中订单项的总数。

如果想要按订单分别统计订单项数量,可以使用terms聚合结合nested聚合:

{
    "aggs": {
        "orders": {
            "terms": {
                "field": "order_id"
            },
            "aggs": {
                "order_item_count": {
                    "nested": {
                        "path": "order_items"
                    },
                    "aggs": {
                        "total_items": {
                            "value_count": {
                                "field": "order_items.id"
                            }
                        }
                    }
                }
            }
        }
    }
}

聚合结果结构如下:

{
    "aggregations": {
        "orders": {
            "buckets": [
                {
                    "key": "order1_id",
                    "doc_count": 1,
                    "order_item_count": {
                        "doc_count": 3,
                        "total_items": {
                            "value": 3
                        }
                    }
                },
                {
                    "key": "order2_id",
                    "doc_count": 1,
                    "order_item_count": {
                        "doc_count": 2,
                        "total_items": {
                            "value": 2
                        }
                    }
                }
            ]
        }
    }
}

解释:

  • ordersterms聚合的名称,按order_id对订单进行分组。
  • buckets:每个桶代表一个订单,key是订单的order_iddoc_count表示该订单文档出现的次数(通常为1)。
  • order_item_countnested聚合,统计每个订单内的订单项,doc_count表示该订单内包含订单项的文档数量(通常为1),total_itemsvalue表示该订单的订单项总数。