MongoDB: How to query nested array specific elements? - mongodb

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.

Related

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

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

$nin operator doesn't work correctly

When I use this method, I get all documents from _User collection. (as expected)
db.getCollection("_User").find({ "_id" : { $nin: [] }})
However, when I add at least one string to $nin array:
db.getCollection("_User").find({ "_id" : { $nin: ["7HpHbmF5iu","ga61t3afsa"] }})
I get empty results. (expected - to get all documents without the ones with ids 7HpHbmF5iu and ga61t3afsa)
MongoDB version 3.2.6
These are two documents I want to filter from all:
{ "_id" : "7HpHbmF5iu", "expiration_date" : ISODate("2015-12-28T08:51:21.252Z"), "_created_at" : ISODate("2015-10-29T08:51:23.302Z"), "_updated_at" : ISODate("2016-03-10T17:37:45.262Z"), "gender" : "female", "firstName" : "Toma", "verification" : "verified", "birthdayDate" : ISODate("1995-02-15T00:00:00Z") }
{ "_id" : "ga61t3afsa", "expiration_date" : ISODate("2015-12-27T07:54:21.235Z"), "_created_at" : ISODate("2015-10-28T07:11:22.102Z"), "_updated_at" : ISODate("2016-03-11T16:11:10.100Z"), "gender" : "female", "firstName" : "Goda", "verification" : "verified", "birthdayDate" : ISODate("1992-09-13T00:00:00Z") }
It was an error in Azure DocumentDB with Mongo, however I've chosen not to use their services, so I don't know if they've already fixed it.

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.

Query MongoDB N-Tier Nested on every Level

I've got this structure of document, saved in MongoDB 2.6.1, running on Linux:
{
"_id" : "1",
"name" : "Level0",
"childs" : [
{
"id" : "2",
"name" : "Level1",
"childs" : [
{
"id" : "3",
"name" : "Level2",
"childs" : [
{
"id" : "4",
"name" : "Level3-1",
},
{
"id" : "5",
"name" : "Level3-2",
}
]
}
...
Every Element got his childs and every child-element got his own childs until the technical end.
Now I want to Query my MongoDB with something like:
db.categories.find({'childs':{$elemMatch:{$all:['Level19-23']}}})
This Query dont work by the way.
What is a good query to get my elements?
I dont know anything about the children or parents, I've got only the name of the element, and I need the element with all his children.
Anyone got an advise for me, the MongoDB Newbe? :)
Thanks in advance!

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}})