How to iterate a mongo db document and update a nested array - mongodb

I need to remove entries inside a 2d array of documents structure in mongodb.
Sample is as below
{
"_id" : ObjectId("5ffef283f1f06ff8524aa2c2"),
"applicationName" : "TestApp",
"pName" : "",
"environments" : [],
"stages" : [],
"createdAt" : ISODate("2021-01-15T09:51:35.546Z"),
"workflows" : [
[
{
"pName" : "Test1",
"wName" : "TestApp_Test1",
"agent" : ""
},
{
"pName" : "Test2",
"wName" : "TestApp_Test2",
"agent" : ""
}
],
[
{
"pName" : "Test1",
"wName" : "TestApp_Test1",
"agent" : ""
}
]
],
"updatedAt" : Date(-62135596800000)
}
So, I want to remove all document occurences of
{
"pName" : "Test1",
"wName" : "TestApp_Test1",
"agent" : ""
}
from both the arrays.
pName:Test1 can be used to filter it out.
What's the query which can be used to find this and delete it ?
I am ok to do a find and then iterate over the collection , find the matching entry and then update the document. I have to do this using Go mongodb driver
Since this is kind of complex for me as I am new to both golang and mongo db, I am stuck.
Update:
1.Tried {$pull: {workflows: {pName:"Test1"}}}, {multi: true} in the update() call as suggested but didn't work.
2.Tried something like this
db.getCollection('workflows').update({_id:ObjectId('5ffef283f1f06ff8524aa2c2')}, {$pull:{workflows: { $elemMatch: {pName:'Test2'}}}} )
This is removing the entire array as shown below because Test2 is present in that. I need to remove only the Test2 document
[
{
"pName" : "Test1",
"wName" : "TestApp_Test1",
"agent" : ""
},
{
"pName" : "Test2",
"wName" : "TestApp_Test2",
"agent" : ""
}
]

I'll give you a hint as you are new and you haven't posted the tried things.
You could use $pull to remove documents matching the conditions.
similar example
And you could use official mongodb driver for go or most used gopkg
An example SO post

Related

MongoDB: How to query nested array specific elements?

I've a complex collection in MongoDB. In this, I want to query departments data based on the subDeptName. I used query like below db.getCollection('users').find({"departments.subDeptName" : "Java"}), but its fetching all the array elements of the department. I only wants to query such department where "subDeptName" : "Java". How can we do that ?
{
"firstName" : "John",
"lastName" : "Kerr",
"email" : "john.kerr#gmail.com",
"countryName" : "USA",
"usRestrictionSw" : "N",
"status" : "Active",
"effDate" : ISODate("2012-08-24T01:46:33.000Z"),
"departments" : [
{
"subDeptCd" : "AB",
"languageCd" : "en",
"desc" : "Development Group",
"subDeptName" : "Java",
"status" : "Active"
},
{
"subDivisionAlpha2Cd" : "KG",
"subDivisionCd" : "B",
"languageCd" : "ru",
"desc" : "Testing Group",
"subDeptName" : "Python",
"status" : "Active"
},
..........
..........
..........
..........
}
}
db.getCollection('users').find({"departments.subDeptName" : "Java"})
Will match all users with a sub deperament java.
Easiest way to achieve the result you want is this:
db.getCollection('users').aggregate([
{
$unwind: "$departments"
},
{
$match: {
"departments.subDeptName" : "Java"
}
])
Now you can also add a $project phase to get only the specific fields you want.
Try this:-
db.getCollection('users').find({"departments.subDeptName" : "Java"})
i have checked this on command line work fine.
Please check your mongo version and mongo shell version
mongod --version (check mongo version)
mongo --version // check mongo shell version.
And also check error log for have unother issue.

mongodb extracting values from array

Following is example of table in mongodb, I have multiple records for companies like this, which I need help with.
I wanted to query the below table wherein using value from company I should be able to retrieve the name of all the cars.
"vehicles" : [
{
"source" : "jeep",
"tag" : [
{
"company" : "toyota",
"name" : "fortuner"
},
{
"company" : "rangerover",
"name" : "discovery"
]
}
]
Thanks...
try this :
db.vehicles.find({tag: {$elemMatch: {company:'toyota'}}}).pretty();
read more here : https://docs.mongodb.com/manual/reference/operator/query/elemMatch/

How to query an array in an array of objects in mongodb?

I am pretty new to mongodb, and I am not able to query in my mongo collection.
Structure :
"chapterId":1,
"videos" : [
{
"videoId" : "1",
"videoName" : "about",
"duration" : "12:36",
"tags":["business", "design"]
},
{
"videoId" : "2",
"videoName" : "course",
"duration" : "04:00",
"tags":["technology", "design"]
}
]
I need to select all videos with the tag "business" in chapterId 1.
Can this be done without changing the structure of my collection ?
You should use aggregation so below query will help you
db.collectionName.aggregate(
{"$unwind":"$videos"},
{"$match":{"chapterId":1,"videos.tags":"business"}}
)

Get specific object in array of array in MongoDB

I need get a specific object in array of array in MongoDB.
I need get only the task object = [_id = ObjectId("543429a2cb38b1d83c3ff2c2")].
My document (projects):
{
"_id" : ObjectId("543428c2cb38b1d83c3ff2bd"),
"name" : "new project",
"author" : ObjectId("5424ac37eb0ea85d4c921f8b"),
"members" : [
ObjectId("5424ac37eb0ea85d4c921f8b")
],
"US" : [
{
"_id" : ObjectId("5434297fcb38b1d83c3ff2c0"),
"name" : "Test Story",
"author" : ObjectId("5424ac37eb0ea85d4c921f8b"),
"tasks" : [
{
"_id" : ObjectId("54342987cb38b1d83c3ff2c1"),
"name" : "teste3",
"author" : ObjectId("5424ac37eb0ea85d4c921f8b")
},
{
"_id" : ObjectId("543429a2cb38b1d83c3ff2c2"),
"name" : "jklasdfa_XXX",
"author" : ObjectId("5424ac37eb0ea85d4c921f8b")
}
]
}
]
}
Result expected:
{
"_id" : ObjectId("543429a2cb38b1d83c3ff2c2"),
"name" : "jklasdfa_XXX",
"author" : ObjectId("5424ac37eb0ea85d4c921f8b")
}
But i not getting it.
I still testing with no success:
db.projects.find({
"US.tasks._id" : ObjectId("543429a2cb38b1d83c3ff2c2")
}, { "US.tasks.$" : 1 })
I tryed with $elemMatch too, but return nothing.
db.projects.find({
"US" : {
"tasks" : {
$elemMatch : {
"_id" : ObjectId("543429a2cb38b1d83c3ff2c2")
}
}
}
})
Can i get ONLY my result expected using find()? If not, what and how use?
Thanks!
You will need an aggregation for that:
db.projects.aggregate([{$unwind:"$US"},
{$unwind:"$US.tasks"},
{$match:{"US.tasks._id":ObjectId("543429a2cb38b1d83c3ff2c2")}},
{$project:{_id:0,"task":"$US.tasks"}}])
should return
{ task : {
"_id" : ObjectId("543429a2cb38b1d83c3ff2c2"),
"name" : "jklasdfa_XXX",
"author" : ObjectId("5424ac37eb0ea85d4c921f8b")
}
Explanation:
$unwind creates a new (virtual) document for each array element
$match is the query part of your find
$project is similar as to project part in find i.e. it specifies the fields you want to get in the results
You might want to add a second $match before the $unwind if you know the document you are searching (look at performance metrics).
Edit: added a second $unwind since US is an array.
Don't know what you are doing (so realy can't tell and just sugesting) but you might want to examine if your schema (and mongodb) is ideal for your task because the document looks just like denormalized relational data probably a relational database would be better for you.

Mongodb + Mongoose: trying to add a sub-sub-item

Does this makes any sense when trying to add a sub-sub-item? (I'm new to mongo - be merciful :-))
question = db.questions.findOne({_id: ObjectId("529c5d44211c9a8c11000006")})
question.answers[0].votes.insert(...)
When I run this from the mongo console the result is an error saying [object object] does not have the method insert.
I have the following mongoDB Question Schema.
{
"__v" : 2,
"_creator" : ObjectId("529c5d2d211c9a8c11000005"),
"_id" : ObjectId("529c5d44211c9a8c11000006"),
"answers" : [
{
"postDate" : ISODate("2013-12-02T10:14:19.060Z"),
"postDateText" : "15min ago",
"authorEmail" : "guys#pix.com",
"authorName" : "guys#pix.com",
"body" : "You need magic powder",
"isWinner" : false,
"_creator" : ObjectId("529c5d2d211c9a8c11000005"),
"_id" : ObjectId("529c5d7b211c9a8c11000008"),
"votes" : [
{
"voteType" : "up",
"_creator" : ObjectId("529c5d2d211c9a8c11000005"),
"_id" : ObjectId("529c5d5b211c9a8c11000007")
}
]
}
],
"authorEmail" : "guys#wix.com",
"authorName" : "guys#wix.com",
"body" : "I'm trying to fly...\n\n<pre class=\"brush: js;\">\nfunction logName(name) {\n console.log(name);\n}\n</pre>",
"isResolved" : false,
"postDate" : ISODate("2013-12-02T10:13:24.235Z"),
"tags" : [
"fly"
],
"title" : "How do I fly?",
"views" : [],
"votes" : [
{
"voteType" : "up",
"_creator" : ObjectId("529c5d2d211c9a8c11000005"),
"_id" : ObjectId("529c5d5b211c9a8c11000007")
}
]
}
I'm trying, given a questionId and an answerId to add a vote to the votes array (which is inside the answer). I can't seem to do it. Help?
insert is for adding whole new documents; when you just want to add a new element to an array field of an existing document, you can use update along with an operator like $push.
So, in the shell you would use something like this:
db.questions.update(
{_id: ObjectId("529c5d44211c9a8c11000006")},
{'answers.0.votes': {$push: voteToPush}})