javascript - 嵌入数组的 MongoDB 平均值作为额外字段

标签 javascript node.js mongodb mongodb-query aggregation-framework

我的文档是这样的:

{
    "_id" : "53ce85eda2579da8b40c1f0f",
    "name" : "Autokino",
    "tags" : [
        "forMen"
    ],
    "ratings" : [
        { "rating" : 5, "uuid" : "..."},
        { "rating" : 4, "uuid" : "..."},
        { "rating" : 4, "uuid" : "..."},
        { "rating" : 1, "uuid" : "..."},
    ]
}

现在我需要 ratings.rating 的平均值(这里应该是 3.5)。我的查询如下所示:

activities.aggregate([
    { $match: { _id: ObjectID(req.params.id) } },
    { $unwind: '$ratings' },                                                                                                                                                                          
    { $group: {
        _id: '$_id',
        rating: { $avg: '$ratings.rating'},
    }},
]);

它有效,但我得到的是:

{
  "_id" : "53ce85eda2579da8b40c1f0f",
  "rating" : 3.5
}

这就是我需要得到的:

{
    "_id" : "53ce85eda2579da8b40c1f0f",
    "name" : "Autokino",
    "tags" : [
        "forMen"
    ],
    "rating" : 3.5
}

(没有评分数组但有评分平均值的原始文档)

我该如何解决这个问题?

最佳答案

流水线阶段,如 $group $project 是“绝对”的,因为只发出声明的字段。你需要另一个接线员。 $first 会做:

activities.aggregate([
    { "$match": { "_id": ObjectID(req.params.id) } },
    { "$unwind": "$ratings" },                                                                                                                                                                          
    { "$group": {
        "_id": "$_id",
        "name": { "$first": "$name" },
        "tags": { "$first": "$tags" },
        "rating": { "$avg": "$ratings.rating" },
    }},
]);

$unwind 使数组内容中的许多文档反规范化,您可以使用 $first此处仅取您未以其他方式聚合的附加字段的“第一次”出现。

如果您担心很多字段以这种方式声明,MongoDB 2.6 确实提供了 $$ROOT 多变的。它的用法和输出可能不是您真正想要的:

activities.aggregate([
    { "$match": { "_id": ObjectID(req.params.id) } },
    { "$project": {
        "_id": "$$ROOT",
        "ratings": 1
    }},
    { "$unwind": "$ratings" },                                                                                                                                                                          
    { "$group": {
        "_id": "$_id",
        "rating": { "$avg": "$ratings.rating" },
    }},
]);

这给你类似的东西:

{
    "_id" : {
        "_id": "53ce85eda2579da8b40c1f0f",
        "name" : "Autokino",
        "tags" : [
            "forMen"
        ],
        "ratings" : [
            { "rating" : 5, "uuid" : "..."},
            { "rating" : 4, "uuid" : "..."},
            { "rating" : 4, "uuid" : "..."},
            { "rating" : 1, "uuid" : "..."},
        ]
    },
    "rating": 3.5
}

这里没问题,因为按 _id 分组与对整个文档进行分组相同。所以你总是可以添加最后一个 $project回到相似的状态。但是这里没有通配符。

关于javascript - 嵌入数组的 MongoDB 平均值作为额外字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24906890/

相关文章:

javascript - 当 Babel 和 Traceur 转译 ES6 解构时,额外变量的目的是什么?

sql - 如何使用 SQL 从 MongoDB ObjectId 检索日期

javascript - 计算 mongodb 字段内的对象数量

javascript - 计算两个碰撞物体的重叠?

javascript - 将 Google Analytics 点击(事件)跟踪代码添加到 Javascript window.open

javascript - 为什么这个 "next"不起作用?

node.js - HTTP 身份验证不适用于 passport-http

javascript - 在 Sails.js 中使用 Waterline ORM 时出现 ER_BAD_FIELD_ERROR

javascript - Vue.js 到 Node.js 服务器 : How can I secure my POST call?

javascript - Node.js:如何处理新 URL 解析器弃用警告?