How to return a new value after an update to an inline array?

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's how I increase the rating of this rating:

 db.collection.update( { "_id": ObjectId("56d6a7292c06e85687f44541"), "rankings._id" : ObjectId("46d6a7292c06e85687f55543") }, { $inc : { "rankings.$.score" : 1 } } ); 

How do I get a new rating value? In a previous request, I increase the second rating from 10 to 11 ... How to get this new value after the update?

+5
source share
1 answer

If you are using MongoDB 3.0 or later, you need to use .findOneAndUpdate() and use the projection option to specify a subset of the field to return. You also need to set returnNewDocument to true . Of course, you need to use the $elemMatch design $elemMatch because you cannot use positional projection and return a new document.

As someone remarked:

You should use .findOneAndUpdate() because .findAndModify() highly regarded as deprecated in every official driver. Another thing is that the syntax and parameters are pretty consistent between the drivers for .findOneAndUpdate() . With .findAndModify() most drivers do not use the same single object with request / update / field keys. So this is a bit confusing when someone turns to another language to be consistent. The standard API changes for .findOneAndUpdate() actually correspond to the server version 3.x, not 3.2.x. The complete difference is that the shell methods actually lagged behind other drivers (by one time!) When implementing the method. Thus, most drivers actually had a large release corresponding to 3.x 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 } ) 

Starting with MongoDB 3.0, you need to use findAndModify and the fields option also you need to set new to true in another 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 give:

 { "_id" : ObjectId("56d6a7292c06e85687f44541"), "rankings" : [ { "_id" : ObjectId("46d6a7292c06e85687f55543"), "name" : "Ranking 2", "score" : 11 } ] } 
+9
source

Source: https://habr.com/ru/post/1244906/


All Articles