如何平均mongodb中的总和值?

时间:2014-01-01 01:35:44

标签: mongodb

使用MongoDB 2.4.8,

我有以下记录

{
    "category" : "TOYS",
    "price" : 12,
    "status" : "online",
    "_id" : "35043"
}
{
    "category" : "TOYS",
    "price" : 13,
    "status" : "offline",
    "_id" : "35044"
}
{
    "category" : "TOYS",
    "price" : 22,
    "status" : "online",
    "_id" : "35045"
}
{
    "category" : "BOOKS",
    "price" : 13,
    "status" : "offline",
    "_id" : "35046"
}
{
    "category" : "BOOKS",
    "price" : 17,
    "status" : "online",
    "_id" : "35047"
}

我想查找状态为在线且总价格超过50的每个类别的平均价格。

我不确定如何构建此查询。

到目前为止,我可以构建我总结的查询,并找出状态为在线的每个类别的总价格。

db.products.aggregate([
    {"$match":
        {           
            {status:"online"}
        }
    },
    {"$group" :
        {
            "_id": "$category",
            "total_price": {$sum:"$price"},
        }
    }
])

我不确定如何为此查询添加更多阶段以获取我正在寻找的平均值。

2 个答案:

答案 0 :(得分:2)

您只需向汇总管道添加更多阶段即可。例如:

db.items.aggregate([
    {$match:
        {           
            status:"online"
        }
    },
    {$group :
        {
            _id: "$category",
            total_price: {$sum:"$price"},
        }
    },
    {$match:
        {           
            total_price:{$gt:50}
        }
    },
    {$group :
        {
            _id: "1",
            avg_price: {$avg:"$total_price"},
        }
    },
]);

根据说明编写

答案 1 :(得分:2)

您可以使用总计计算$group步骤中每个类别的平均产品价格,然后添加额外的$match阶段,将结果限制为总数超过50的产品:

db.products.aggregate(

    // Find matching products (can take advantage of index)
    { $match: {
        status: "online"
    }},

    // Calculate total and average
    { $group: {
        "_id": "$category",
        "total_price": { $sum:"$price" },
        "avg_price": { $avg:"$price"} 
    }},

    // Limit results to price > 50
    { $match: {
        "total_price" : { $gt: 50 }
    }}
)

请注意,对于您的示例数据,$gt:50没有匹配结果(您可以尝试使用$gt:30将“TOYS”类别作为匹配,总价格为34)。

平均匹配类别的总价格

如果您想获得与限额匹配的类别的总价格的平均价格,您可以在最后添加额外的$group步骤:

// Calculate the average total price
{ $group: {
    "_id": null,
    "total_average_price": { $avg:"$total_price"} 
}}

请注意,这个额外的分组会将所有内容减少到一个数字(total_average_price),这可能与您预期的一样,也可能不是。您可能希望在使用最后一个组运行聚合之前保存中间结果,或者只计算应用程序代码中的平均值,如果没有很多数字要总结的话。