Given the following MongoDB collection:
{
"_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
},
]
}
Here is how I increase the score of a given ranking:
db.collection.update(
{ "_id": ObjectId("56d6a7292c06e85687f44541"), "rankings._id" : ObjectId("46d6a7292c06e85687f55543") },
{ $inc : { "rankings.$.score" : 1 } }
);
How do I get the new score value? In the previous query I increase the second ranking from 10 to 11... How do I get this new value back after the update?
You can use the updateOne() or updateMany() methods to add, update, or remove array elements based on the specified criteria. It is recommended to use the updateMany() method to update multiple arrays in a collection.
Update Nested Arrays in Conjunction with $[]The $[<identifier>] filtered positional operator, in conjunction with the $[] all positional operator, can be used to update nested arrays. The following updates the values that are greater than or equal to 8 in the nested grades. questions array if the associated grades.
Getting Started. You need at least 2 parameters to call findOneAndUpdate() : filter and update . MongoDB finds the first document that matches filter and applies update . By default, findOneAndUpdate() returns the document as it was before MongoDB applied update .
In MongoDB, you can use the $push operator to append a value to an array. This operator can be used with various modifiers, one of which is the $position modifier. The $position modifier allows you to specify the position within the array that you want to insert the new value.
If you are on MongoDB 3.0 or newer, you need to use the .findOneAndUpdate()
and use projection
option to specify the subset of fields to return. You also need to set returnNewDocument
to true
. Of course you need to use the $elemMatch
projection operator here because you cannot use a positional projection and return the new document.
As someone pointed out:
You should be using
.findOneAndUpdate()
because.findAndModify()
is highlighed as deprecated in every official language driver. The other thing is that the syntax and options are pretty consistent across drivers for.findOneAndUpdate()
. With.findAndModify()
, most drivers don't use the same single object with "query/update/fields" keys. So it's a bit less confusing when someone applies to another language to be consistent. Standardized API changes for.findOneAndUpdate()
actually correspond to server release 3.x rather than 3.2.x. The full distinction being that the shell methods actually lagged behind the other drivers ( for once ! ) in implementing the method. So most drivers actually had a major release bump corresponding with the 3.x release with such changes.
db.collection.findOneAndUpdate(
{
"_id": ObjectId("56d6a7292c06e85687f44541"),
"rankings._id" : ObjectId("46d6a7292c06e85687f55543")
},
{ $inc : { "rankings.$.score" : 1 } },
{
"projection": {
"rankings": {
"$elemMatch": { "_id" : ObjectId("46d6a7292c06e85687f55543") }
}
},
"returnNewDocument": true
}
)
From MongoDB 3.0 onwards, you need to use findAndModify
and the fields
options also you need to set new
to true
in other to return the new value.
db.collection.findAndModify({
query: {
"_id": ObjectId("56d6a7292c06e85687f44541"),
"rankings._id" : ObjectId("46d6a7292c06e85687f55543")
},
update: { $inc : { "rankings.$.score" : 1 } },
new: true,
fields: {
"rankings": {
"$elemMatch": { "_id" : ObjectId("46d6a7292c06e85687f55543") }
}
}
})
Both queries yield:
{
"_id" : ObjectId("56d6a7292c06e85687f44541"),
"rankings" : [
{
"_id" : ObjectId("46d6a7292c06e85687f55543"),
"name" : "Ranking 2",
"score" : 11
}
]
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With