mongodb update multi not working - mongodb

I'm tying to update a field named company, here is my query
user_collection.update({"campaing" => "mediacom"}, {"campaing" => "flatiron"}, {"multi" => true})
but the problem is the update affects only one document not all documents from collection and "multi" flag is set to true

Building on what paul referenced in the docs, you want to use a $set to change a field value:
user_collection.update({ "campaing" : "mediacom" }, { "$set" : { "campaing" : "flatiron" } }, { "multi" : true })
Updating with a document means "replace the matched document with this document":
> db.test.drop()
> db.test.insert({ "_id" : 0, "a" : 1, "b" : 0 })
> db.test.update({ "_id" : 0 }, { "b" : 1 })
> db.test.findOne()
{ "_id" : 0, "b" : 1 }

From the mongoDB documentation:
"If the document contains only field:value expressions, then update() cannot update multiple documents."
http://docs.mongodb.org/manual/reference/method/db.collection.update/

You can try updateMulti function

Related

Mongo Push - Why is only one object updated?

I have a collection with the documents like this with 25 documents
{
"_id" : ObjectId("<some id>"),
"code" : "1111",
"myArray" : ["Choocolate"]
},
{
"_id" : ObjectId("<some id>"),
"code" : "2222"
"myArray" : ["Choocolate"]
},
{
"_id" : ObjectId("<some id>"),
"code" : "3333",
"myArray" : ["Choocolate"]
},
{
"_id" : ObjectId("<some id>"),
"code" : "4444",
"myArray" : ["Choocolate"]
}
and so on
I want to add an item to an myArray only fore certain documents based on a condition. so I tried this
db.mycollection.update
({ "code":
{
"$nin": ["1111","2222"]
},
{
$push: { "myArray": "Coffee" }
}
)
I expect 'Coffee' to be added to myArray in all documents except the ones with code 1111 or 2222. But only it is added to an array only in one document.
How to I add an item to anArray in multiple documents based on a condition against a field in a document?
Based on the documentation update updates only a single element:
By default, the db.collection.update() method updates a single document. Include the option multi: true to update all documents that match the query criteria.
https://docs.mongodb.com/manual/reference/method/db.collection.update/
To update more use updateMany:
https://docs.mongodb.com/manual/reference/method/db.collection.updateMany/

Update a json document in a mongodb database

I'm trying to update an existing document in a MongoDb. There are many explanations how to do this if you want to update or add key/value pairs on the first level. But in my use-case, I need to create with the first updateOne (with upsert option set) a document with the following structure:
{
"_id" : "1234",
"raw" : {
"meas" : {
"meas1" : {
"data" : "blabla"
}
}
}
}
In the second command, I need to add - in the same document - a "meas2" field at the level of "meas1". My desired output is:
{
"_id" : "1234",
"raw" : {
"meas" : {
"meas1" : {
"data" : "blabla"
},
"meas2" : {
"data" : "foo"
}
}
}
}
I played with statements like
updateOne({"_id":"1234"},{$set:{"raw":{"meas":{"meas2":{"data":"foo"}}}}}, {"upsert":true})
and also with $push, both variants with insert - here only the document and also insertOne, but nothing produces the desired output. Is there a MongoDb expert who could give a hint ? ... I'm sure this functionality exists... Thanks in advance!
When you update {$set: {"raw":{"meas":{"meas2":{"data":"foo"}}}} you're not adding "mesa2" to "meas" but rather you're overriting "raw" completely.
In order to change / add one field in a document refer to it with dot notations.
The command you want is updateOne({"_id": "1234"}, {$set: {"raw.meas.mesa2": { "data" : "foo" }}}, {"upsert":"true"})
You need to understand the below concept first
Set Fields in Embedded Documents, with details document check at official documentation of mongo
For your problem, just look at the below execution on the mongo shell:
> db.st4.insert({
... "_id" : "1234",
... "raw" : {
... "meas" : {
... "meas1" : {
... "data" : "blabla"
... }
... }
... }
... })
WriteResult({ "nInserted" : 1 })
> db.st4.find()
{ "_id" : "1234", "raw" : { "meas" : { "meas1" : { "data" : "blabla" } } } }
>
> // Below query will replace the raw document with {"meas":{"meas2":{"data":"foo"}}}, will not add
> //db.st4.updateOne({"_id":"1234"},{$set:{"raw":{"meas":{"meas2":{"data":"foo"}}}}}, {"upsert":true})
>// By using the dot operator, you actually write the values inside the documents i.e you are replacing or adding at raw.meas.mesa2 i.e inside the document of mesa2.
> db.st4.updateOne({"_id":"1234"},{$set: {"raw.meas.mesa2": { "data" : "foo" }}}, {"upsert":"true"})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
> db.st4.find().pretty()
{
"_id" : "1234",
"raw" : {
"meas" : {
"meas1" : {
"data" : "blabla"
},
"mesa2" : {
"data" : "foo"
}
}
}
}
>

mongodb findOneAndUpdate only if a certain condition is met

Following is my mongo db entries.
my-mongo-set:PRIMARY> db.stat_collection.find({name : /s/})
{ "_id" : ObjectId("5aabf231a167b3808302b138"), "name" : "shankarmr", "email" : "abc#xyz", "rating" : 9901 }
{ "_id" : ObjectId("5aabf23da167b3808302b139"), "name" : "shankar", "email" : "abc1#xyz1", "rating" : 10011 }
{ "_id" : ObjectId("5aabf2b5a167b3808302b13a"), "name" : "shankar1", "email" : "abc2#xyz2", "rating" : 10 }
{ "_id" : ObjectId("5aabf2c2a167b3808302b13b"), "name" : "shankar2", "email" : "abc3#xyz3", "rating" : 100 }
Now i want to find an entry based on name but update a field only if a certain condition holds good.
I tried the following statement, but it gives me error at the second reference to $rating.
db.stat_collection.findOneAndUpdate({name: "shankar"}, {$set : {rating : {$cond : [ {$lt : [ "$rating", 100]}, 100, $rating]}}, $setOnInsert: fullObject}, {upsert : true} )
So in my case, it shouldnot update rating for the 2nd document as the rating is not less than 100. But for the third document, rating should be updated to 100.
How do i get it work?
$max is the operator you're looking for, try:
db.stat_collection.findOneAndUpdate( { name: "shankar1"}, { $max: { rating: 100 } }, { returnNewDocument: true } )
You'll either get old value (if is greater than 100) or modify a document and set 100
According to the documentation:
The $max operator updates the value of the field to a specified value if the specified value is greater than the current value of the field. The $max operator can compare values of different types, using the BSON comparison order.
You should put all conditions in the query part of the update:
db.stat_collections.findOneAndUpdate(
{ name: "Shankar", rating: { $lt: 100 } },
$set : { rating: 100 },
);
"If the name is Shankar and rating is less than 100, then set the rating to 100." is the above.

check if value exists in array field in mongodb

I want to check if user id exists inside an array field of mongodb (using meteor)
db.posts.find().pretty()
{
"_id" : "hT3ezqEyTaiihoh6Z",
"body" : "hey\n",
"authorId" : "AyJo5nf2Lkdqd6aRh",
"createdAt" : ISODate("2016-05-13T06:19:34.726Z"),
"updatedAt" : ISODate("2016-05-13T06:19:34.726Z"),
"likecount" : 0,
"already_voted" : [ ] }
db.posts.find( { _id:"hT3ezqEyTaiihoh6Z"},{ already_voted: { $in : ["AyJo5nf2Lkdqd6aRh"]} }).count()
1
It gives count value 1 , where as I am expecting it to be 0 .
Your logic is fine. Just the syntax is wrong.
db.posts
.find({
_id: "hT3ezqEyTaiihoh6Z",
already_voted: { $in: ["AyJo5nf2Lkdqd6aRh"] },
})
.count();
This should work.
You can just simply use count method. Don't need to use two operation like Find and then count.
db.posts
.count({
_id: "hT3ezqEyTaiihoh6Z",
already_voted: { $in: ["AyJo5nf2Lkdqd6aRh"] }
});

How come this MongoDB update doesn't work?

db.posts.update({}, {"pop_score":999});
db.posts.find({},{"pop_score":1});
{ "_id" : ObjectId("4d8eadd6df83500f3b000004"), "pop_score" : 0 }
{ "_id" : ObjectId("4d8eb1e3df83500f3b000035"), "pop_score" : 1 }
{ "_id" : ObjectId("4d8eb238df83500f3b000039"), "pop_score" : 1 }
{ "_id" : ObjectId("4d91377bdf8350063d000000"), "pop_score" : 1 }
{ "_id" : ObjectId("4d913c19df8350063d000001"), "pop_score" : 2 }
{ "_id" : ObjectId("4d8eacabdf83500f3b000000"), "pop_score" : 1 }
I update the pop_score to 999, for all posts. But when I query for them, it didn't update.
It did work, but only updates the FIRST matching document by default. I suspect you have SOME document in there that is now 999.
What you need to do is to tell MongoDB to update every matching document, by setting the optional multi flag to true:
db.posts.update({}, {"pop_score":999}, false, true)
This will update every document rather than just the first it finds.
You may wish to review the docs on updating as well which have more info on these flags.
Beware that update() replaces the found element with the one passed as argument, you should use the $set atomic operator to update a field's value (and of course, Brendan is right about the first vs. multiple match):
db.posts.update({}, { $set: { pop_score: 999 } }, false, true)