鉴于以下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 ...如何在更新后获得这个新值?
答案 0 :(得分:12)
如果您使用的是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开始,您需要使用findAndModify
和fields
选项,您还需要在其他选项中将new
设置为true
以返回新值。< / p>
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
}
]
}