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

5

我在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
         }
 ]

我需要将每个产品类别平均化,如下所示:
 "_id" : 7,
 "customer name" : "John Smith",
 "OrderItem" : [
         {
                 "product_category" : "Mobile",
                 "price" : 900
         },
         {
                 "product_category" : "Computer",
                 "price" : 4200.48
         },
         {
                 "product_category" : "TV",
                 "price" : 815.36
         }
 ]

我尝试使用$unwind,但不确定如何对它们进行分组。有帮助吗?

4
你尝试过什么方法?请详细说明。 - Salvador Dali
3
“product_category” 或者 “product_name”? - Neo-coder
3个回答

1
使用包含以下阶段的管道的聚合框架:第一个管道阶段中的$match操作过滤文档流,以允许只有匹配的文档(在您的情况下是_id = 7的文档)通过未经修改地传递到下一个管道阶段,即$unwind操作。这会从输入文档中拆解所需的OrderItem数组字段,输出每个元素的文档,然后可以对其进行分组并执行查找类别价格平均值的聚合操作。管道中的下一个阶段是$group操作,它将输入文档按product_category分组,并在price上应用$avg表达式。最后一个阶段$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
        }

    }
])

Result:

{
    "result" : [ 
        {
            "average_price" : 4200.48,
            "product_category" : "Computer"
        }, 
        {
            "average_price" : 815.36,
            "product_category" : "TV"
        }, 
        {
            "average_price" : 900,
            "product_category" : "Mobile"
        }
    ],
    "ok" : 1
}

0

首先你需要展开OrderItem,然后将它们分组,并使用mongo $avg来计算平均值。以下聚合操作将计算平均值

    db.collectionName.aggregate(
                    {"$match":{"customer name":"John Smith"}}, // match specified  customername  
                    {"$unwind":"$OrderItem"}, // unwind the OrderItem

                    {"$group":{"_id":"$OrderItem.product_category",
                       "avg":  {"$avg":"$OrderItem.price"} // mongo avg method used for avrage
                }}
              ).pretty()

因此,上述查询将返回以下结果

{ "_id" : "Computer", "avg" : 4200.48 }
{ "_id" : "TV", "avg" : 815.36 }
{ "_id" : "Mobile", "avg" : 900 }

但是上述结果与您提供的期望输出不符,因此您应该进行两次分组以获得精确的输出

        db.collectionName.aggregate(
                {"$match":{"customer name":"John Smith"}},  //match given criteria
                {"$unwind":"$OrderItem"},           //unwind $OrderItem

                {"$group":{"_id":"$OrderItem.product_category",
                           "customerName":{"$first":"$customer name"}, // group all data with calculating avg
                           "id":{"$first":"$_id"}, 
                               "avg":{"$avg":"$OrderItem.price"}}},

                    {"$group":{"_id":"$id",
                       "customer Name":{"$first":"$customerName"},
                           "OrderItem":{"$push":   {"product_category":"$_id","price":"$avg"}}}} // group them for expected output

               ).pretty()

0
.aggregate([
    {$unwind: "$OrderItem"},
    {$group: {
        _id: {id: "$_id", cat: "$OrderItem.product_category"}, 
        name: {$first: "$customer name"}, 
        price: {$avg: "$OrderItem.price"}
    }}, 
    {$group: {
        _id: "$_id.id", 
        OrderItem: {$push: {product_category: "$_id.cat", price: "$price"}}, 
        "customer name": {$first: "$name"}
    }}
])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接