MongoDB-更新数组的子文档以包括计算值

时间:2019-12-07 16:47:20

标签: mongodb mongodb-query aggregation-framework

基本上,我想从输入文档的数组字段中的每个子对象中减去两个字段,然后更新文档以包括计算出的值。

例如

{   
    "title" : "The Hobbit",

    "rating_average" : "???",
    "ratings" : [
        {
            "title" : "best book ever",
            "start" : 5,
            "finish" : 7
        },
        {
            "title" : "good book",
            "start" : 4,
            "finish" : 8
        }
    ]
}

我要减去每个对象的完成起点,然后然后将新计算出的字段保存到我的现有文档中。

因此,更新我的文档后,它应该像:

{   
    "title" : "The Hobbit",
    "rating_average" : "???",
    "ratings" : [
        {
            "title" : "best book ever",
            "start" : 5,
            "finish" : 7
             “diff”:2
        },
        {
            "title" : "good book",
            "start" : 4,
            "finish" : 8
             “diff”:4

        }
    ]
}

那我该怎么办?

先谢谢了。

3 个答案:

答案 0 :(得分:2)

这是 4.2版更新方法,它支持聚合管道阶段$setfunction wp_check_password_changed( $value ) { $current_user = wp_get_current_user(); $users = $current_user->my_country; return $users; } 投影运算符用于为每个数组元素派生$map字段:

diff

答案 1 :(得分:1)

以下聚合管道将使用数组中的diff字段创建一个新集合。

db.books.aggregate([
    {
        $unwind: "$ratings"
    },
    {
        $addFields: {
            "ratings.diff": {
                $subtract: ["$ratings.finish", "$ratings.start"]
            }
        }
    },
    {
        $group: {
            _id: "$_id",
            title: {
                $first: "$title"
            },
            rating_average: {
                $first: "$rating_average"
            },
            ratings: {
                $addToSet: "$ratings"
            }
        }
    },
    {
        $out: "modified-books"
    }
])

您甚至可以通过在最后一个阶段指定$out: "books"来替换现有大学。

这不是完成此任务的理想方法,但我认为没有其他选择。

答案 2 :(得分:0)

请在mongoDB 4.2或更高版本上尝试:

db.yourCollectionName.aggregate([{ $match: { title: 'The Hobbit' } }, { $unwind: '$ratings' }, {
    $addFields: {
        'ratings.diff': { $subtract: ["$ratings.finish", '$ratings.start'] }
    }
}, {
    $group: {
        _id: '$_id', title: { $first: '$title' },
        rating_average: { $first: '$rating_average' }, ratings: { $push: '$ratings' }
    }
}, { $merge: { into: "yourCollectionName", on: "_id"} }])

如果您有更多字段并且不想在$group阶段单独列出所有字段,请尝试以下方法:

db.yourCollectionName.aggregate([{ $match: { title: 'The Hobbit' } }, { $unwind: '$ratings' }, {
    $addFields: {
        'ratings.diff': { $subtract: ["$ratings.finish", '$ratings.start'] }
    }
}, {
    $group: {
        _id: '$_id', "doc": { $first: '$$ROOT' }, ratings: { $push: '$ratings' }
    }
}, { $addFields: { 'doc.ratings': '$ratings' } }, { $replaceRoot: { newRoot: "$doc" } },
   { $merge: { into: "yourCollectionName", on: "_id"} }])

如果希望在整个收藏夹中完成此操作,则可以将$match删除为第一阶段。 $merge能够基于给定的匹配字段在同一文档上合并新字段或使用聚合结果(默认行为)更新现有字段。

参考: mongoDB aggregation-pipeline