mongoDB updateOne not updating a record - mongodb

I am trying to update a record in mongoDB using updateOne, the un updating record is in array, and all fields are updating except one field which is country, I have tried to update it using MongoChef (a GUI of MongoDB for linux), but it doesn't work, also If I update one the Document using Edit in GUI then that record is ready to update after that.
I have tried with the following query in MongoChef
db.institutions.updateOne({
"campus": { "$elemMatch": { "_id": ObjectId("578500ef87e4c326183e520e")} },
"_id": ObjectId("57f25706762c06cb7d9422fc")
},
{
"$set" : { "campus.$.country" : "SS1"
}
});
Only country field is not updating If I update any other field it works fine.
The document structure is listed under
{
"_id" : ObjectId("57f26824762c06cb7d982e37"),
"campus" : [
{
"_id" : ObjectId("578500ee87e4c326183e5201"),
"country" : "GB",
"coreId" : NumberInt(1),
"city" : "Norwich",
}
]
}
Thanks in advance any help is appreciatiable

try this query
db.institutions.updateOne(
{
"campus._id": ObjectId("578500ef87e4c326183e520e"),
"_id": ObjectId("57f25706762c06cb7d9422fc")
},
{
"$set" : { "campus.$.country" : "SS1"}
}
);
N.B: if use mongodb driver or mongoose then no need to use ObjectId("") just use "578500ef87e4c326183e520e"

Related

how to use update query in mongoDb?

I have few documents in user Collection like below .I need to update ancestors field alone,Need to add few more values.
db.users.find()
{
"_id" : ObjectId("5d9fd81f3d598088d2ea5dcc"),
"DOB" : ISODate("1979-05-23T00:00:00Z"),
"userImage" : "sathish_1589780950636.jpeg",
"createdDateTime" : ISODate("2016-02-01T09:43:27Z"),
"modifiedDateTime" : ISODate("2017-04-26T15:57:09Z"),
"status" : "active",
"ancestors" : [
ObjectId("5d9fd81b3d598088d2ea5dc7")
],
"parent" : ObjectId("5d9fd81b3d598088d2ea5dc7")
}
When i tried the below query.
db.users.update({"_id" : ObjectId("5d9fd81f3d598088d2ea5dcc")},{$set:{"ancestors" : [
ObjectId("5f45f9491ff4bd74ec754e3a"),
ObjectId("5d9fd8203d598088d2ea5dcd"),
ObjectId("5d9fd8723d598088d2ea5e43")
]}})
It just replace the old one and completely adding the new one.
I need the result to be like this .old data should also remain and new one should be added.
"ancestors" : [
ObjectId("5f45f9491ff4bd74ec754e3a"),
ObjectId("5d9fd8203d598088d2ea5dcd"),
ObjectId("5d9fd81b3d598088d2ea5dc7"),
ObjectId("5d9fd8723d598088d2ea5e43")
]
This update query should be done in all documents in that collection. the above mentioned 3 values to be added in all documents, instead of find and update, I should be doing bulk updated
I think you can run the following:
db.users.updateOne({"_id" : ObjectId("5d9fd81f3d598088d2ea5dcc")},{$addToSet:{"ancestors" :{ $each: [
ObjectId("5f45f9491ff4bd74ec754e3a"),
ObjectId("5d9fd8203d598088d2ea5dcd"),
ObjectId("5d9fd8723d598088d2ea5e43")
]}}})
ref: https://docs.mongodb.com/manual/reference/operator/update/each/
You can use mongodb method $push
db.users.update({"_id" : ObjectId("5d9fd81f3d598088d2ea5dcc")},
{ $push: {ancestors:ObjectId("5f45f9491ff4bd74ec754e3a") } })
[check doc][1]
[1]: https://docs.mongodb.com/manual/reference/operator/update/push/

MongoDB get all embedded documents where condition is met

I did this in my mongodb:
db.teams.insert({name:"Alpha team",employees:[{name:"john"},{name:"david"}]});
db.teams.insert({name:"True team",employees:[{name:"oliver"},{name:"sam"}]});
db.teams.insert({name:"Blue team",employees:[{name:"jane"},{name:"raji"}]});
db.teams.find({"employees.name":/.*o.*/});
But what I got was:
{ "_id" : ObjectId("5ddf3ca83c182cc5354a15dd"), "name" : "Alpha team", "employees" : [ { "name" : "john" }, { "name" : "david" } ] }
{ "_id" : ObjectId("5ddf3ca93c182cc5354a15de"), "name" : "True team", "employees" : [ { "name" : "oliver" }, { "name" : "sam" } ] }
But what I really want is
[{"name":"john"},{"name":"oliver"}]
I'm having a hard time finding examples of this without using some kind of programmatic iterator/loop. Or examples I find return the parent document, which means I'd have to parse out the embedded array employees and do some kind of UNION statement?
Eg.
How to get embedded document in mongodb?
Retrieve only the queried element in an object array in MongoDB collection
Can someone point me in the right direction?
Please add projections to filter out the fields you don't need. Please refer the project link mongodb projections
Your find query should be constructed with the projection parameters like below:
db.teams.find({"employees.name":/.*o.*/}, {_id:0, "employees.name": 1});
This will return you:
[{"name":"john"},{"name":"oliver"}]
Can be solved with a simple aggregation pipeline.
db.teams.aggregate([
{$unwind : "$employees"},
{$match : {"employees.name":/.*o.*/}},
])
EDIT:
OP Wants to skip the parent fields. Modified query:
db.teams.aggregate([
{$unwind : "$employees"},
{$match : {"employees.name":/.*o.*/}},
{$project : {"name":"$employees.name",_id:0}}
])
Output:
{ "name" : "john" }
{ "name" : "oliver" }

MongoDB 4.0 aggregation addFields not saving documents after using toDate

I have the following documents,
{
"_id" : ObjectId("5b85312981c1634f59751604"),
"date" : "0"
},
{
"_id" : ObjectId("5b85312981c1634f59751604"),
"date" : "20180330"
},
{
"_id" : ObjectId("5b85312981c1634f59751604"),
"date" : "20180402"
},
{
"_id" : ObjectId("5b85312981c1634f59751604"),
"date" : "20180323"
},
I tried to convert date to ISODate using $toDate in aggregation,
db.documents.aggregate( [ { "$addFields": { "received_date": { "$cond": [ {"$ne": ["$date", "0"] }, {"$toDate": "$date"}, new Date("1970-01-01") ] } } } ] )
the query executed fine, but when I
db.documents.find({})
to examine all the documents, nothing changed, I am wondering how to fix it. I am using MongoDB 4.0.6 on Linux Mint 19.1 X64.
As they mentioned in the comments, aggregate doesn't update documents in the database directly (just an output of them).
If you'd like to permanently add a new field to documents via aggregation (aka update the documents in the database), use the following .forEach/.updateOne method:
Your example:
db.documents
.aggregate([{"$addFields":{"received_date":{"$cond":[{"$ne":["$date","0"]}, {"$toDate": "$date"}, new Date("1970-01-01")]}}}])
.forEach(function (x){db.documents.updateOne({_id: x._id}, {$set: {"received_date": x.received_date}})})
Since _id's value is an ObjectID(), there may be a slight modification you need to do to {_id:x._id}. If there is, let me know and I'll update it!
Another example:
db.users.find().pretty()
{ "_id" : ObjectId("5acb81b53306361018814849"), "name" : "A", "age" : 1 }
{ "_id" : ObjectId("5acb81b5330636101881484a"), "name" : "B", "age" : 2 }
{ "_id" : ObjectId("5acb81b5330636101881484b"), "name" : "C", "age" : 3 }
db.users
.aggregate([{$addFields:{totalAge:{$sum:"$age"}}}])
.forEach(function (x){db.users.updateOne({name: x.name}, {$set: {totalAge: x.totalAge}})})
Being able to update collections via the aggregation pipeline seems to be quite valuable because of what you have the power to do with aggregation (e.g. what you did in your question, doing calculations based on other fields within the document, etc.). I'm newer to MongoDB so maybe updating collections via aggregation pipeline is "bad practice", but it works and it's been quite valuable for me. I wonder why it isn't more straight-forward to do?
Note: I came up with this method after discovering Nazo's now-deprecated .save() method. Shoutout to Nazo!

Access document directly by ID

I'm used to working with firebase where I can access a document directly by fetching data from the db like so.
db.collection('collectionName/documentID').get();
I can't seem to find any documentation regarding doing something similar in mongodb. Do I have to use a find query to grab data from a mongodb or have I missed something? Thanks
I'm thinking
const collection = db.collection('collectionName');
collection.findOne({_id: ObjectId('documentID'); });
Since mongo consolse is an interactive javascript shell, One way would be to create a method similar to this:
function collectionNameGet(idToFind) {
return db.collection.find({_id: idToFind });
}
In the mongo shell you can directly get it as below:
db.st4.find({"_id" : "1234"})
Result set:
{ "_id" : "1234", "raw" : { "meas" : { "meas1" : { "data" : "blabla" }, "mesa2" : { "data" : "foo" } } } }
Or by default mongo id as:
db.st1.find({"_id" : ObjectId("5c578d57ce9ba4a066ca2fa4")})
{ "_id" : ObjectId("5c578d57ce9ba4a066ca2fa4"), "name" : "Just a name", "users" : [ "user1", "user2" ] }
For display the result in pretty format
db.st1.find({"_id" : ObjectId("5c578d57ce9ba4a066ca2fa4")}).pretty()
Result set:
{
"_id" : ObjectId("5c578d57ce9ba4a066ca2fa4"),
"name" : "Just a name",
"users" : [
"user1",
"user2"
]
}
Here st4 is my collection name in the database test, so once you are on mongo shell do the below steps before above query:
use test
db.st1.insert({"name" : "Just a name", "users" : [ "user1", "user2" ] })
and then you can query by default _id generated mongo, you can simply make a query to get the recently added documents in the collection st1 as below:
db.st1.find().sort({_id:-1}).limit(1)
Hope this will help you out to do some basic query on mongo shell

Update MongoDB objects using existing objects

I'm trying to convert my mongodb data into more simpler format, but I don't know how to check if certain field is an array and update those only.
I have this kind of objects in my database currently
{ "_id" : ObjectId("xyz"), "name" : "Yeti ", "channel" : "ABC", "showed" : { "_isAMomentObject" : true, "_i" : "25.3.2014 23:40", ... }}
I also has some rows which are in new format already:
{ "_id" : ObjectId("xyz"), "name" : "Yeti ", "channel" : "ABC", "showed" : "25.3.2014 23:40" }
I would like to update all my objects which has array type in "showed" property into an object which has showed._i in showed property.
showed._i => showed, for all objects which have array in showed property.
I tried to do this update using my backup collection, but it put null into showed property for all objects:
db.programs_bak.find({}).forEach(function(doc) { db.programs.update( { _id: doc._id }, { showed: doc.showed._i },{ }); });
db.programs_bak.find({}).forEach(function(doc) {
db.programs.update( { _id: doc._id },
{$set : { "showed" : doc.showed._i}});
});