Update nested object based on "name" field - mongodb

I'm new in MongoDB, so forgive my ignorance.Suppose you have the document:
{ "_id" : ObjectId("..."),
"google" : { "googleId" : ..., "username" : "Johnny",
"followers" : [ { name:"niklas", email:"niklas#hotmail.com" } ] },
"__v" : 0 }
When admin "Johny" obtains a new follower, i can add him using
User.update(query,
{$addToSet:{google.followers:{name:"Maria" , email:"Maria#hotmail.com"}}},
{upsert:true,new:true}...
My problem occurs when "niklas" changes his email. Using $addToSet simply adds a new object. How can i update the existing email of "niklas" or add it if there is no such entry;
Thanks in advance

To update existing email of "niklas", you can the positional "$" operator. Something like:
db.User.update(
{"followers.name" : "niklasaa"},
{$set: {"followers.$.email": "new-email"}}
)

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 already exists array added another value query

I have notification click table like this:
{
"_id" : ObjectId("5d00d4e1d720cc4cb1b24566"),
"createdOn" : ISODate("2019-06-12T10:33:05.866Z"),
"notification_center_id" : [
ObjectId("5c59343523f05e2ff13938d6")
],
"user_id" : ObjectId("5bc5dc03f6d24d29077dd362"),
"__v" : 0
}
I want to check if user_id "5bc5dc03f6d24d29077dd362" is already exists then added another notification_center_id in already exists record.
like this
{
"_id" : ObjectId("5d00d4e1d720cc4cb1b24566"),
"createdOn" : ISODate("2019-06-12T10:33:05.866Z"),
"notification_center_id" : [
ObjectId("5c59343523f05e2ff13938d6"),
ObjectId("5c5c4610c6d91403f38eda52")
],
"user_id" : ObjectId("5bc5dc03f6d24d29077dd362"),
"__v" : 0
}
I want query that first check user id exists if exists then added another notification record in notification_center_id field.
If user is not exists then I want add another record in collection
one more condition here, if notification_center_id is not inserted duplicate. if it's exist then not added.
Please help me.
db.getCollection('test').update(
{"user_id" : ObjectId("5bc5dc03f6d24d29077dd362")},
{"$push" : {"notification_center_id" : new ObjectId()}}
)
In your question, you have not mentioned what to do if user_id doesn't exist. So doing nothing in that case.
After your comment
db.getCollection('test').update(
{"user_id" : ObjectId("5c59343523f05e2ff13938d6")},
{
"$push" : {"notification_center_id" : new ObjectId()},
"$setOnInsert" : {"createdOn" : new ISODate(), "__v" : 0}
},
{"upsert" : true}
)
$addToSet update operator is used to append an element to an array and preserves uniqueness of values into an array.
db.notifications.update({"_id" : ObjectId("5d00d4e1d720cc4cb1b24566")}
, { $addToSet: { notification_center_id: new ObjectId() } })

MongoDB - update an existing document in a collection

I have a collection called user_roles and it contains a field called rights which is an array of strings.
I want to update a document within user_roles collection that has _id = 5b1509f8b95b4bfe2b638508 by appending a new string element into the rights field.
So basically, after this update collection should hold the additional element "ui.dealers.measures.retrieve" as shown below.
{
"_id" : ObjectId("5b1509f8b95b4bfe2b638508"),
"type" : "coach",
"name" : "Coach",
"flavours" : {
"coach" : NumberInt(1)
},
"rights" : [
"ui.dealers.retrieve",
"ui.dealers.dossier.retrieve",
"ui.dealers.dossier.update",
"ui.dealers.documents.retrieve",
"ui.dealers.documents.create",
"ui.dealers.documents.delete",
"ui.dealers.events.retrieve",
"ui.dealers.events.create",
"ui.dealers.events.update",
"ui.dealers.events.export",
"ui.dealers.events.delete",
"ui.dealers.kpis.retrieve",
"ui.dealers.kpis.update",
"ui.dealers.blueprints.retrieve",
"ui.dealers.blueprints.create",
"ui.dealers.gap.retrieve",
"ui.dealers.gap.update",
"ui.dealers.measures.create",
"ui.dealers.surveys.retrieve",
"ui.dealers.surveys.update",
"ui.dealers.measures.retrieve"
],
"createdAt" : ISODate("2018-06-04T09:44:24.394+0000"),
"updatedAt" : ISODate("2018-06-04T10:01:56.428+0000")
}
Please try this
db.collection.update({_id:ObjectId("5b1509f8b95b4bfe2b638508")},{
$push:{
"rights":"ui.dealers.measures.retrieve"
}
})

MongoDB update a subdocument attribute

Let me start by saying I'm sorry if this has been answered, but I can't get other questions on this site to fit my needs and, more importantly, work.
I have the below example document, with a subdocument of 'address':
{
"_id" : ObjectId("....")
,"addresses" :
[{
"start" : ISODate("1973-07-10T00:11:51.111Z")
,"value" : "123 long road"
}]
}
What I need to do is to close the existing address record with an end attribute, and add a new line for the new address with a new start and value attribute. Eventually, I'll need to do this again so the code needs to update the subdocument record where end does not exist.
The below code does not work, but it's about as far as I can get:
db.sites.update(
{"_id" : ObjectId("....")
, "addresses.end" : {"$exists" : false}}
,{"$set": {"addresses.$.end" : "fdsa"}});
This gives the error:
Cannot apply the positional operator without a corresponding query field containing an array.
Can anyone point me in the right direction?
Juste replace in your query "addresses.end" : {"$exists" : false} with:
addresses: {$elemMatch: {end: {$exists: false}}}
Your address field is poorly defined. you need make it a subdocument or an array of subdocuments. ie {
"_id" : ObjectId("....")
,"addresses" :
[
{
"start" : ISODate("1973-07-10T00:11:51.111Z")
,"value" : "123 long road"
}
]
}
your query should then work!
I think that the Query should be more specific
**Updated **
db.sites.update ( {"_id" : ObjectId("...."), addresses: { "$elemMatch" : { end:{$exists : false}} } }, {"$set": {"addresses.$.end" : "fdsa"}});
db.sites.find()
results:
{
"_id" : ObjectId("53df93da560b7815e1237934"),
"addresses" : [
{
"start" : ISODate("1973-07-10T00:11:51.111Z"),
"value" : "123 long road",
"end" : "fdsa"
}
]
}
but you can update only one
Take a look http://docs.mongodb.org/manual/reference/operator/projection/positional/#proj.S
You can t update more element in Array https://jira.mongodb.org/browse/SERVER-1243