鉴于以下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()
为在各官方语言司机弃用的highlighed。 另一件事是,语法和选项是跨越司机相当一致的.findOneAndUpdate()
随着.findAndModify()
大部分司机不使用带有“查询/更新/田”键相同的单个对象。 所以这是一个少一点混乱,当有人适用于另一种语言要一致。 对于标准化的API的变化.findOneAndUpdate()
实际上对应于服务器3.x版,而不是3.2.x. 完整的区别在于外壳的方法实际上与其他车手落后于(一次吧!)在实施方法。 因此,大多数司机竟然出现了与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
在其他返回新值。
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
}
]
}