Update query in MongoDB shell - mongodb

In the shell, my query is:
db.checkin_4e95ae0926abe9ad28000001.update({location_city:"New York"}, {location_country: "FUDGE!"});
However, it doesn't actually update my records. It doesn't error either. When I do a db.checkin_4e95ae0926abe9ad28000001.find({location_city:"New York"}); after running this, I get all my results but the location_country has not changed:
{
"_id": ObjectId("4e970209a0290b70660009e9"),
"addedOn": ISODate("2011-10-13T15:21:45.772Z"),
"location_address1": "",
"location_city": "New York",
"location_country": "United States",
"location_latLong": {
"xLon": -74.007124,
"yLat": 40.71455
},
"location_source": "socialprofile",
"location_state": "New York",
"location_zip": ""
}

This is because in second parameter of update function you need to use $set operator to update location_country as in example below:
db.checkin_4e95ae0926abe9ad28000001.update(
{location_city:"New York"}, //find criteria
// this row contains fix with $set oper
{ $set : { location_country: "FUDGE!"}});
Here you can find a list of available update operators.

Changed in version 3.6.
Following is the syntax for update :
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ]
}
)
Example :
db.getCollection('products').update({},{$unset: {translate:1, qordoba_translation_version:1}}, {multi: true})
In your example :
db.checkin_4e95ae0926abe9ad28000001.update(
{location_city:"New York"}, //query
// $update query
{ $set : { location_country: "FUDGE!"}});
By default, the update() method updates a single document. Set the Multi Parameter to update all documents that match the query criteria.
Example 2 :
db.checkin_4e95ae0926abe9ad28000001.update(
{location_city:"New York"}, //query
// $update query
{ $set : { location_country: "FUDGE!"}}, {multi: true});

db.m_country.update(
{"countryId": "962a0935-bf3d-4f63-a53c-254760273ede"},
{$set: {'countryPopulation': '12540000'}})

Before Update
> db.student.find({name:"Venky"}).pretty();
{
"_id" : ObjectId("6012e64dc2979ddffe1e5df9"),
"name" : "Venky",
"dept" : "MCA",
"age" : "26",
"phone" : "89786465"
}
Update Command
> db.student.update({name:"Venky"},{$set: {name:"DODDANNA CHAWAN",dept:"MCA(CS)", age:"25", phone:"1234567890"}});
Find Command See Result
> db.student.find({name:"DODDANNA CHAWAN"}).pretty();
After Updated Result
{
"_id" : ObjectId("6012e64dc2979ddffe1e5df9"),
"name" : "DODDANNA CHAWAN",
"dept" : "MCA(CS)",
"age" : "25",
"phone" : "1234567890"
}
in real life use unique "_id" to match the document becuase names will found as duplicates

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/

insert and update a field in MongoDB

I want to update all the collection field profile.email with emails.[0].address just something like this in SQL:
update dbo.users
set profile.email=emials.[0].address
I know this stupid code won't work on SQL either. Just put it to make it sensible for what I need.
it is something like this,but is not working:
db.getCollection('users').update(
{_id: "QYoHQkTuTXnEC6Pws"},
{$set:
{'profile.email': db.getCollection('users').aggregate({$match: {_id:'QYoHQkTuTXnEC6Pws'}},
{$project: {_id:0,email: {$arrayElemAt:
['$emails.address',0]}}})
}
}
)
the result is not true :
"email" : {
"_batch" : [
{
"email" : "deleted_sadaf#ham.com"
}
],
"_useReadCommands" : true,
"_cursorid" : NumberLong(0),
"_batchSize" : undefined,
"_ns" : "meteor.users",
"_db" : {
"_mongo" : {
"slaveOk" : true,
"host" : "localhost:3001",
"defaultDB" : "",
"_readMode" : "commands",
"_writeMode" : "commands"
},
"_name" : "meteor"
},
"_collName" : "users",
"_cursorHandle" : {}
}
You have to iterate over each document and update to achieve expected result.
db.users.find({}).forEach(function (user) {
db.users.update({_id: user._id}, {$set: {'profile.email': user.emails[0].address}});
});
db.users.update({_id: "doc id"},
{$set: {'profile.email': db.users.find({_id: "doc id"}).emails[0].address}
})
Your task has 2 steps:
1. get the email address, which is performed by "db.users.find"
2. update the document, which is performed by "db.users.update"

MongoDB: updating the value of an inner BSON

I have a document with a schema in mongodb that looks like this:
{
"_id" : ObjectId("572f88424de8c74a69d4558c"),
"storecode" : "ABC",
"credit" : true,
"group" : [
{
"group_name" : "Frequent_Buyer",
"time" : NumberLong("1462732865712"),
}
],
}
I want to add on the _id part for the first object in the array under group so it looks like this:
{
"_id" : ObjectId("572f88424de8c74a69d4558c"),
"storecode" : "ABC",
"credit" : true,
"group" : [
{
"group_name" : "Frequent_Buyer",
"time" : NumberLong("1462732865712"),
"_id" : "573216fee4430577cf35e885"
}
],
}
When I try this code it fails:
db.customer.update({ "_id": ObjectId("572f88424de8c74a69d4558c") },{ "$set": { "group.$._id": "573216fee4430577cf35e885"} })
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 16837,
"errmsg" : "The positional operator did not find the match needed from the query. Unexpanded update: groups.$._id"
}
})
However, if I adjust the code slightly and add on an extra criteria for querying, it works:
db.customer.update({ "_id": ObjectId("572f88424de8c74a69d4558c"), "group.groupname": "Frequent_Buyer" },{ "$set": { "group.$._id": "573216fee4430577cf35e885"} })
Results:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Why did the first command not work but the second command work?
This is the expected result. To use the positional $ update operator, the array field must appear as part of the query document as mentioned in the documentation.
When used with update operations, e.g. db.collection.update() and db.collection.findAndModify(),
the positional $ operator acts as a placeholder for the first element that matches the query document, and
the array field must appear as part of the query document.
For example If you don't want to filter your documents using group_name, simply add group: { "$exists": true } or "group.0": { "$exists": true } to your query criteria. You query will then look like this:
db.customer.updateOne(
{
"_id": ObjectId("572f88424de8c74a69d4558c"),
"group.0": { "$exists": true}
},
{ "$set": { "group.$._id": "573216fee4430577cf35e885" } }
)
Last and not least, you should be using updateOne or updateMany because update is deprecated in official language driver.

Yet another MongoDB findAndModify

Please consider the following document, a part of the Runtime collection:
{
"entity_id" : 10,
"features" : [
{
"10" : "Test System 2"
},
{
"20" : "System 2 Description"
},
{
"180" : ISODate("2013-12-25T18:19:40.589Z")
},
{
"190" : ISODate("2013-12-25T18:19:40.589Z")
}
],
"_id" : ObjectId("52bb21bc8a2ebdc01c000001")
}
My goal is to update the value of the element of the "features" array having the key "20".
Here are the things I've tried (in mongo shell):
db.Runtime.findAndModify({ "query" : {"_id": "52bb21bc8a2ebdc01c000001"}, "update" : {$set : {"features.$.20":"Updated Description"}}} );
db.Runtime.findAndModify({ "query" : {"_id": "52bb21bc8a2ebdc01c000001"}, "update" : {$set : {"features['20']":"Updated Description"}}} );
db.Runtime.findAndModify({ "query" : {"_id": "52bb21bc8a2ebdc01c000001"}, "update" : {$set : {"features[1]":"Updated Description"}}} );
In all instances the shell prints
null
and nothing happens to the data. So, the main question is, of course, what is wrong with my code snippets. Also, how that "null" is supposed to get interpreted? And is there such a thing as mongo shell's log where one could find any clues? Many thanks for your help!
When using the $ positional operator in an update, your query needs to include a term that matches the element of the array you're updating:
db.Runtime.findAndModify({
query: {_id: ObjectId("52bb21bc8a2ebdc01c000001"),
'features.20': {$exists: true}},
update: {$set: {"features.$.20":"Updated Description"}}
})
Note that you also need to call ObjectId on your _id string to turn it into an actual ObjectId or it won't match the doc.

Remove element from array in mongodb

I am new in mongodb and i want to remove the some element in array.
my document as below
{
"_id" : ObjectId("4d525ab2924f0000000022ad"),
"name" : "hello",
"time" : [
{
"stamp" : "2010-07-01T12:01:03.75+02:00",
"reason" : "new"
},
{
"stamp" : "2010-07-02T16:03:48.187+03:00",
"reason" : "update"
},
{
"stamp" : "2010-07-02T16:03:48.187+04:00",
"reason" : "update"
},
{
"stamp" : "2010-07-02T16:03:48.187+05:00",
"reason" : "update"
},
{
"stamp" : "2010-07-02T16:03:48.187+06:00",
"reason" : "update"
}
]
}
in document, i want to remove first element(reason:new) and last element(06:00) .
and i want to do it using mongoquery, i am not using any java/php driver.
If I'm understanding you correctly, you want to remove the first and last elements of the array if the size of the array is greater than 3. You can do this by using the findAndModify query. In mongo shell you would be using this command:
db.collection.findAndModify({
query: { $where: "this.time.length > 3" },
update: { $pop: {time: 1}, $pop: {time: -1} },
new: true
});
This would find the document in your collection which matches the $where clause.
The $where field allows you to specify any valid javascript method. Please note that it applies the update only to the first matched document.
You might want to look at the following docs also:
http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-JavascriptExpressionsand%7B%7B%24where%7D%7D for more on the $where clause.
http://www.mongodb.org/display/DOCS/Updating#Updating-%24pop for
more on $pop.
http://www.mongodb.org/display/DOCS/findAndModify+Command for more
on findAndModify.
You could update it with { $pop: { time: 1 } } to remove the last one, and { $pop: { time : -1 } } to remove the first one. There is probably a better way to handle it though.
#javaamtho you cannot test for a size greater than 3 but only if it is exactly 3, for size greater than x number you should use the $inc operator and have a field you either 1 or -1 to in order to keep track when you remove or add items (use a separate field outside the array as below, time_count)
{
"_id" : ObjectId("4d525ab2924f0000000022ad"),
"name" : "hello",
"time_count" : 5,
"time" : [
{
"stamp" : "2010-07-01T12:01:03.75+02:00",
"reason" : "new"
},
{
"stamp" : "2010-07-02T16:03:48.187+03:00",
"reason" : "update"
},
{
"stamp" : "2010-07-02T16:03:48.187+04:00",
"reason" : "update"
},
{
"stamp" : "2010-07-02T16:03:48.187+05:00",
"reason" : "update"
},
{
"stamp" : "2010-07-02T16:03:48.187+06:00",
"reason" : "update"
}
]
}
If you would like to leave these time elements, you can use aggregate command from mongo 2.2+ to retrieve min and max time elements, unset all time elements, and push min and max versions (with some modifications it could do your job):
smax=db.collection.aggregate([{$unwind: "$time"},
{$project: {tstamp:"$time.stamp",treason:"$time.reason"}},
{$group: {_id:"$_id",max:{$max: "$tstamp"}}},
{$sort: {max:1}}])
smin=db.collection.aggregate([{$unwind: "$time"},
{$project: {tstamp:"$time.stamp",treason:"$time.reason"}},
{$group: {_id:"$_id",min:{$min: "$tstamp"}}},
{$sort: {min:1}}])
db.students.update({},{$unset: {"scores": 1}},false,true)
smax.result.forEach(function(o)
{db.collection.update({_id:o._id},{$push:
{"time": {stamp: o.max ,reason: "new"}}},false,true)})
smin.result.forEach(function(o)
{db.collection.update({_id:o._id},{$push:
{"time": {stamp: o.min ,reason: "update"}}},false,true)})
db.collection.findAndModify({
query: {$where: "this.time.length > 3"},
update: {$pop: {time: 1}, $pop{time: -1}},
new: true });
convert to PHP