Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongodb update array with another field

I have a DB with a set of fields f1,f2,f3, where f3 is an array. I would like to do an update operation such as this

db.collection.update ({f1:1},{$push:{f3:{$each:[f2's value],$slice:-2}}})

I searched on the internet and was not abole to find anything. I am not sure if this is even possible. Any help would be much appreciated.

EXAMPLE:

This is my set of documents:

doc1 = { name: "User1", score: "Good",  History of scores: ["Good", "Bad", "Average", "Bad"] }
doc2 = { name: "User2", score: "Bad",  History of scores: ["Good", "Average", "Average", "Bad"] }
doc3 = { name: "User3", score: "Good",  History of scores: ["Good", "Good", "Average", "Good"] }

Now suppose we have to insert the corresponding data:

{name : "User1", score: "Good"}

I would like the document to update user1's history of scores so that doc1 becomes as follows:

doc1 = { name: "User1", score: "Good", History of scores: ["Bad", "Average", "Bad", "Good"] }

another of the same update should change doc1 to:

doc1 = { name: "User1", score: "Good", History of scores: ["Average", "Bad", "Good", "Good"] }

I hope now my question has become clearer. Thanks.

like image 290
Sai Avatar asked Nov 18 '25 17:11

Sai


1 Answers

Try this:

> db.c.find()
{ "_id" : ObjectId("51c156d25a334e9347b576a7"), "name" : "User1", "score" : "Good", "scores" : [ "Good", "Bad", "Average", "Bad" ] }
> db.c.update({}, {$push: {scores:{$each:['111', '222'], '$slice': -4}}})
> db.c.find()
{ "_id" : ObjectId("51c156d25a334e9347b576a7"), "name" : "User1", "score" : "Good", "scores" : [ "Average", "Bad", "111", "222" ] }

btw, I there is a problem with this kind of updates: if new object is grater then previous in size, it cause moving this object to another location on disk(e.g. you pushed "Average" and popped "Bad"). Updates "in-place" is faster, you can preallocate space for objects on first insert, like so:

> db.c.insert({ "_id" : ObjectId("51c156d25a334e9347b576a7"), "name" : "<big_tmp_string>", "score" : "<big_tmp_string>", "scores" : [ "<big_tmp_string>", "<big_tmp_string>", "<big_tmp_string>", "<big_tmp_string>" ] })
> db.c.update({ "_id" : ObjectId("51c156d25a334e9347b576a7")}, {<your_real_obj>}
like image 115
Artem Mezhenin Avatar answered Nov 21 '25 09:11

Artem Mezhenin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!