给定以下MongoDB集合:

{
    "_id": ObjectId("56d6a7292c06e85687f44541"),
    "name": "My ranking list",
    "rankings": [
        {
            "_id": ObjectId("46d6a7292c06e85687f55542"),
            "name": "Ranking 1",
            "score": 1
        },
        {
            "_id": ObjectId("46d6a7292c06e85687f55543"),
            "name": "Ranking 2",
            "score": 10
        },
        {
            "_id": ObjectId("46d6a7292c06e85687f55544"),
            "name": "Ranking 3",
            "score": 15
        },
    ]
}

以下是我如何提高给定排名的分数:
db.collection.update(
    { "_id": ObjectId("56d6a7292c06e85687f44541"), "rankings._id" : ObjectId("46d6a7292c06e85687f55543") },
    { $inc : { "rankings.$.score" : 1 } }
);

如何获得新的分数值?在上一个查询中,我将第二个排名从10增加到11…更新后如何获取这个新值?

最佳答案

如果您在MongoDB 3.0或更高版本上,则需要使用.findOneAndUpdate()并使用projection选项指定要返回的字段子集。您还需要将returnNewDocument设置为true。当然,您需要在这里使用$elemMatch投影运算符,因为您不能使用位置投影并返回新文档。
正如有人指出的:
您应该使用.findOneAndUpdate(),因为.findAndModify()在每个官方语言驱动程序中都被高调标记为已弃用。另一件事是,.findOneAndUpdate()的驱动程序的语法和选项非常一致。对于.findAndModify(),大多数驱动程序不使用具有“query/update/fields”键的同一单个对象。所以当有人应用到另一种语言以保持一致时,就不那么令人困惑了。.findOneAndUpdate()的标准化API更改实际上对应于服务器3.x版,而不是3.2.x版。完全区别在于shell方法实际上落后于其他驱动程序(仅此一次!)在实现方法时。因此,大多数驱动程序实际上都有一个与3.x版本相对应的主要版本凸起,并进行了这样的更改。

db.collection.findOneAndUpdate(
    {
        "_id": ObjectId("56d6a7292c06e85687f44541"),
         "rankings._id" : ObjectId("46d6a7292c06e85687f55543")
    },
    { $inc : { "rankings.$.score" : 1 } },
    {
        "projection": {
            "rankings": {
                "$elemMatch": { "_id" : ObjectId("46d6a7292c06e85687f55543") }
            }
        },
        "returnNewDocument": true
    }
)

从MongoDB 3.0开始,您需要使用findAndModifyfields选项,还需要在Other中将new设置为true以返回新值。
db.collection.findAndModify({
    query: {
        "_id": ObjectId("56d6a7292c06e85687f44541"),
        "rankings._id" : ObjectId("46d6a7292c06e85687f55543")
    },
    update: { $inc : { "rankings.$.score" : 1 } },
    new: true,
    fields: {
        "rankings": {
            "$elemMatch": { "_id" : ObjectId("46d6a7292c06e85687f55543") }
        }
    }
})

两个查询都产生:
{
        "_id" : ObjectId("56d6a7292c06e85687f44541"),
        "rankings" : [
                {
                        "_id" : ObjectId("46d6a7292c06e85687f55543"),
                        "name" : "Ranking 2",
                        "score" : 11
                }
        ]
}

09-25 19:24