mongodb - 在执行 $unwind 时过滤掉一些值

use*_*ser 5 mongodb aggregation-framework

我在 mongodb 中有以下客户订单数据

 "_id" : 7,
 "customer name" : "John Smith",
 "OrderItem" : [
         {
                 "product_category" : "Mobile",
                 "price" : 900
         },
         {
                 "product_category" : "Computer",
                 "price" : 4200.48
         },
         {
                 "product_category" : "TV",
                 "price" : 670.20
         },
         {
                 "product_category" : "TV",
                 "price" : 960.52
         }
 ]
Run Code Online (Sandbox Code Playgroud)

我需要对每个产品类别进行平均,如下所示:

 "_id" : 7,
 "customer name" : "John Smith",
 "OrderItem" : [
         {
                 "product_category" : "Mobile",
                 "price" : 900
         },
         {
                 "product_category" : "Computer",
                 "price" : 4200.48
         },
         {
                 "product_category" : "TV",
                 "price" : 815.36
         }
 ]
Run Code Online (Sandbox Code Playgroud)

我尝试使用 $unwind 但不知道如何对它们进行分组。有什么帮助吗?

chr*_*dam 1

使用包含以下阶段的管道的聚合框架$match:第一个管道阶段中的操作过滤文档流,以仅允许匹配的文档(_id = 7在您的情况下为文档)未经修改地传递到下一个管道阶段,即操作$unwind。这会OrderItem从输入文档中解构所需的数组字段,以输出每个元素的文档,然后您可以对其进行分组并执行聚合操作以查找类别价格的平均值。管道的下一个阶段是 $group 操作,该操作然后对输入文档进行分组product_category并将$avg表达式应用于price. 最后一个阶段$project会重塑流中的每个文档以产生所需的结果。因此,您的聚合将如下所示:

db.collection.aggregate([
    {
        "$match": {"_id": 7}
    },
    {   
        "$unwind": "$OrderItem"
    },
    {
        "$group": {
            "_id": "$OrderItem.product_category",
            "average_price": {
                "$avg": "$OrderItem.price"
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "product_category" : "$_id",
            "average_price": 1
        }

    }
])
Run Code Online (Sandbox Code Playgroud)

结果

{
    "result" : [ 
        {
            "average_price" : 4200.48,
            "product_category" : "Computer"
        }, 
        {
            "average_price" : 815.36,
            "product_category" : "TV"
        }, 
        {
            "average_price" : 900,
            "product_category" : "Mobile"
        }
    ],
    "ok" : 1
}
Run Code Online (Sandbox Code Playgroud)