Update nested array document in mongoDB [duplicate] - mongodb

This question already has answers here:
Updating a Nested Array with MongoDB
(2 answers)
Closed 5 years ago.
I have mongo document like
{
"_id" : ObjectId("59ad2dbd7549de7c69ef0132"),
"customerId" : "TELEFONICA",
"organization" : "TELEFONICA",
"description" : "",
"events" : [
{
"id" : "abandonCartEvent",
"name" : "Abandoned Cart Event",
"attributes" : [
{
"attrId" : "geoLocation",
"attrName" : "Customer Location",
"defaultValue" : "London"
},
{
"attrId" : "traits",
"attrName" : "Customer Traits",
"defaultValue" : "Sports Lover"
}
]
},
{
"id" : "resumeEvent",
"name" : "Resume Event",
"attributes" : [
{
"attrId" : "geoLocation",
"attrName" : "Customer Location",
"defaultValue" : "London"
},
{
"attrId" : "traits",
"attrName" : "Customer Traits",
"defaultValue" : "Sports Lover"
}
]
},
{
"id" : "cancelEvent",
"name" : "Cancel Event",
"attributes" : [
{
"attrId" : "geoLocation",
"attrName" : "Customer Location",
"defaultValue" : "London"
},
{
"attrId" : "traits_",
"attrName" : "Customer Traits",
"defaultValue" : "Sports Lover"
}
]
}
]
}
Here I want to update "attributes" array, i.e, I need to modify any one object of attributes array.
Can someone provide me solution for updating this nested document

You have to wait for the next version of mongodb to this. Check this.
Untill that time, redesign your document structure in a way so that it has one array(not double nested array) or traverse second array on application level.

Above you given same document I mentioned output scenario,
If are you going to update id : "abandonCartEvent" & attrId : "geoLocation" ,
update({ "customerId" : "TELEFONICA", "events.id":"abandonCartEvent"}, {$set: {"events.0.attributes.0.attrId": "CustLocation"}})
1a. If are you going to update attrId: "traits"
update({ "customerId" : "TELEFONICA", "events.id":"abandonCartEvent"}, {$set: {"events.0.attributes.1.attrId": "traidstTest"}})
If are you going to update Id: "resumeEvent" arrtID ?
update({ "events.id":"resumeEvent"}, {$set: {"events.1.attributes.0.attrId": "GeoLocationSS"}})
Same like if are you updating cancelEvent id,
update({ "events.id":"cancelEvent"}, {$set: {"events.2.attributes.0.attrId": "GeoLocationSTested"}})
I hope, you will understand the update on array fields.
If you have any queries ask me, or call(+91-9964058121)
Thanks

Related

Delete one element from an array in MongoDB? [duplicate]

This question already has answers here:
How to remove array element in mongodb?
(6 answers)
Closed 4 years ago.
I have the below document stored in mongo DB collection,I will dynamically receive the url to be removed For eg.,I need to delete the subscribers url http://localhost.8080/FNOL/subscriber1 for the name "name" : "FNOL","country" : "US","lob" : "property" from the document.
How do i write the remove command with mongo?
Do i need to redefine my document structure?
Thanks in advance.
{
"_id" : ObjectId("5b07fbbc0d7a677d2f8b2d87"),
"name" : "FNOL",
"country" : "US",
"lob" : "property",
"subscribers" : [
{
"protocol" : "REST",
"url" : "http://localhost.8080/FNOL/subscriber1"
},
{
"protocol" : "SOAP",
"url" : "http://localhost.8080/FNOL/subscriber2"
},
{
"protocol" : "JMS",
"url" : "NOTIFICATION.TOPIC.FNOL"
}
]
}
After removal:
{
"_id" : ObjectId("5b07fbbc0d7a677d2f8b2d87"),
"name" : "FNOL",
"country" : "US",
"lob" : "property",
"subscribers" : [
{
"protocol" : "SOAP",
"url" : "http://localhost.8080/FNOL/subscriber2"
},
{
"protocol" : "JMS",
"url" : "NOTIFICATION.TOPIC.FNOL"
}
]
}
You can use $pull operator specifying mentioned conditions to get matching document and url as a parameter of $pull like below:
let urlToRemove = "http://localhost.8080/FNOL/subscriber1";
db.col.update(
{ name: "FNOL", country: "US", lob: "property" },
{ $pull: { subscribers: {url: urlToRemove }}})

How to query for and delete embedded objects in an array field in MongoDB?

I am trying to run an update command that finds an object in an array field for all documents and then pulls it from that array field for all documents. I have tried the below commands, which do not return any documents (nMatched: 0).
db.users.update({"likedQuizzes.quiz": { $elemMatch: quizObj}},{$pull: {"likedQuizzes.quiz": quizObj }});
db.users.update({"likedQuizzes": { $elemMatch: quizObj}},{$pull: {"likedQuizzes": quizObj }});
In the above cases quizObj = {"title" : "2 Purple", "author" : "purple-tester1"}
Here is a sample document from the 'users' collection:
{
"_id" : ObjectId("581114330de9ac0c1445cdd6"),
"user" : "test-username1",
"likedQuizzes" : [
{
"quiz" : {
"title" : "2 Purple",
"author" : "purple-tester1"
},
"date" : ISODate("2016-10-26T20:39:02.695Z")
},
{
"quiz" : {
"title" : "1 Purple",
"author" : "purple-tester1"
},
"date" : ISODate("2016-10-26T20:39:12.374Z")
},
{
"quiz" : {
"title" : "4 Green",
"author" : "green-tester1"
},
"date" : ISODate("2016-10-26T20:39:25.304Z")
},
{
"quiz" : {
"title" : "3 Green",
"author" : "green-tester1"
},
"date" : ISODate("2016-10-26T20:39:37.326Z")
},
{
"quiz" : {
"title" : "2 Green",
"author" : "green-tester1"
},
"date" : ISODate("2016-10-26T20:40:12.964Z")
}
]
}
Said another way, I am simply trying to find if a quiz is in a users' "likedQuizzes" array, and if it is, delete it from that array (along with the "date" that it was liked).
After some researching it looks like this might not be possible, but I wanted to ask anyway because I think my schema might be different enough from the examples that came up in my research. Thanks in advance for any pointers.
You could restructure your document to be of this structure:
{
"_id" : ObjectId("581114330de9ac0c1445cdd6"),
"user" : "test-username1",
"likedQuizzes" : [
{
"title" : "2 Purple",
"author" : "purple-tester1",
"date" : ISODate("2016-10-26T20:39:02.695Z")
},
{
"title" : "1 Purple",
"author" : "purple-tester1",
"date" : ISODate("2016-10-26T20:39:12.374Z")
},
{
"title" : "4 Green",
"author" : "green-tester1",
"date" : ISODate("2016-10-26T20:39:25.304Z")
},
{
"title" : "3 Green",
"author" : "green-tester1",
"date" : ISODate("2016-10-26T20:39:37.326Z")
},
{
"title" : "2 Green",
"author" : "green-tester1",
"date" : ISODate("2016-10-26T20:40:12.964Z")
}
]
}
After that... if you run the following command:
db.users.update(
{
"likedQuizzes": {
$elemMatch: {
"title" : "2 Purple",
"author" : "purple-tester1"
}
}
},
{
$pull: {
"likedQuizzes": {
"title": "2 Purple",
"author": "purple-tester1"
}
}
}
);
Your $pull will now work. $pull doesn't seem to play nicely with $elemMatch
Well, what you are trying to do is to pass the whole quiz object to the $elemMatch and expecting it to return the match documents from MongoDB, but it won't work that way.
You have to modify your query a bit like
{"likedQuizzes.quiz.title": { $elemMatch: quizObj.title}
Reason : mongodb won't do the field by field compare for you. You should have a unique identifier based on which you can query.
Even in the RDBMS world you cannot do this.
What you are trying to do is something like:
quizObj q;
q.title = "2 Purple";
q.author = "purple-tester1";
select * from quizTable where row = q.
You can give it a try
db.users.update({"likedQuizzes": { $elemMatch: {"quiz.title" : "2 Purple", "quiz.author" : "purple-tester1"}}},
{$pull: {"likedQuizzes": {"quiz" : {"title" : "2 Purple", "author" : "purple-tester1"}}}})
What you can do is use your quizObj = {"quiz.title" : "2 Purple", "quiz.author" : "purple-tester1"}
Hope it helps.
And then below query
db.users.update({"likedQuizzes": { $elemMatch: quizObj }},{$pull: {"likedQuizzes": quizObj }})

mongodb: how to add a new property for mongo's geolocation function

I have a collection of events in mongodb, and below is on sample of the document in the collection:
{
"id" : 15178390976,
"title" : "Basics of Writing a Business Plan (Essex Office)",
"end_date" : "2015-03-18 11:00:00",
"venue" :
{
"city" : "Essex",
"name" : "WindsorEssex Small Business Centre (Essex Office)",
"country" : "Canada",
"region" : "Ontario",
"longitude" : -82.823545,
"postal_code" : "N8M 2J3",
"address" : "39 Maidstone Avenue East",
"latitude" : 42.17792,
"id" : 8864285,
"Lat-Long" : "42.17792 / -82.823545"
}
}
I want to modify the collection of documents, so that I can apply the geospatial spherical function in MongoDB. I want to modify all the documents in the collection as follows:
{
"id" : 15178390976,
"title" : "Basics of Writing a Business Plan (Essex Office)",
"end_date" : "2015-03-18 11:00:00",
"venue" :
{
"city" : "Essex",
"name" : "WindsorEssex Small Business Centre (Essex Office)",
"country" : "Canada",
"region" : "Ontario",
"longitude" : -82.823545,
"postal_code" : "N8M 2J3",
"address" : "39 Maidstone Avenue East",
"latitude" : 42.17792,
"id" : 8864285,
"Lat-Long" : "42.17792 / -82.823545"
},
location:
{
"type":"Point",
"coordinates":[-82.823545, 42.17792]
}
}
the value in the coordinates are from venue.longitude and venue.latitude.
How can I update the documents to what I want? I have tried $update and $projection in aggregation, none of them are working for the location.coordinates property. I failed to push the values into the array.
the aggregation I use is:
db.coll.aggregation([
{ $project:
{
"id": "$id",
"title":"$title",
"venue":"$venue",
"location.type": "Point",
"location.coordinate":["$venue.longitude","$venue.latitude"]
}
},
{ $out:newoutput }
])
Anyone can please help me?

need to find a way to get data inside subdocument in mongo

I need a way to find inside nested array documents.
I want to find value matching inside street_1.
this is my query:
db.phonebook.find({'address.home.street_1' : 'street 1 result'});
and my document:
{
"_id" : ObjectId("53788c0c74d3ead0098b4568"),
"first_name" : "jarod",
"last_name" : "petters",
"company" : "nostromos",
"phone_numbers" : [
{
"cell" : "0752203337"
},
{
"home" : "0850819201"
},
{
"home" : "0499955550"
}
],
"website" : "http://www.mywebsite.com",
"email" : [
{
"home" : "email.first.com"
},
{
"office" : "email.second.com"
}
],
"address" : [
{
"home" : {
"stree_1" : "street 1 result",
"stree_2" : "",
"postal_code" : "66502",
"city" : "my littre city",
"country" : "usa"
}
}
],
"nationality" : "mars",
"date_of_birth" : "1978-01-01"
}
Your query is the good one. But your document is not good, you have done a mistake in your document, you write stree_1 instead of street_1. If your document is right, change your query to :
db.phonebook.find({'address.home.stree_1' : 'street 1 result'});

How to generate mongodb object id for a sub-document on insert

Inserting a document that also has sub-documents. I am doing this through cli. How do I make mongodb generate a object id for the Alerts sub-document record? I want something like the following, but this does not work from cli.
db.user.insert(
{
"Email" : "andy+5#domain.com",
"Domain" : "other",
"Type" : "local",
"FName" : "Andy",
"Alerts" : [
{
"_id" : new ObjectId(),
"Keyword" : "sales",
"Frequency" : {
"Type" : "daily"
},
"IsActive" : true
},
{
"_id" : new ObjectId(),
"Keyword" : "customer service",
"Frequency" : {
"Type" : "daily"
},
"IsActive" : true
}
]
}
)
You can run that exact script on the console on robomongo, it would execute just fine. Don't do it on add or edit dialog.