Finding subelements in a document in mongodb - mongodb

I'm working on the following document
{
"_id" : 123344223,
"firstName" : "gopal",
"gopal" : [
{
"uuid" : "123",
"name" : "sugun",
"sudeep" : [
{
"uuid" : "add32",
"name" : "ssss"
},
{
"uuid" : "fdg456",
"name" : "gfg"
}
]
},
{
"uuid" : "222",
"name" : "kiran"
}
]
}
I want to get my output as following
{
"_id" : 456,
"gopal" : [
{
"uuid" : "123",
"name" : "sugun",
"sudeep" : [
{
"uuid" : "add32",
"name" : "ssss"
}
]
}
]
}
and I tried many things like
db.People.findOne({_id:123},{gopal:{$elemMatch:{uuid:"123",sudeep:{$elemMatch:{uuid:"add32"}}}}});
but whatever I tried it returns the document like this
{
"_id" : 123,
"gopal" : [
{
"uuid" : "123",
"name" : "sugun",
"sudeep" : [
{
"uuid" : "add32",
"name" : "ssss"
},
{
"uuid" : "fdg456",
"name" : "gfg"
}
]
}
]
}
can you please help?

Are you aware of MongoDB aggregation pipeline?
> db.people.aggregate([
{$match: {_id: 123}},
{$unwind: "$gopal"},
{$unwind: "$gopal.sudeep"},
{$match: {"gopal.uuid": "123", "gopal.sudeep.uuid" : "add32"}}
])
Output
{
"_id" : 123,
"firstName" : "gopal",
"gopal" : {
"uuid" : "123",
"name" : "sugun",
"sudeep" : {
"uuid" : "add32",
"name" : "ssss"
}
}
}

Use $unwind in aggregation pipeline
db.People.aggregate([{$match:{_id:'123'}},{$match:{gopal.uuid:'123'}},{$unwind:'$sudeep'},{$match:{uuid:'add32'}}])

Related

Update query on in the collection by "_id"

{
"_id" : "tenant/data/EMAIL/ENGLISH",
"tenantId" : "tenant2",
"channelType" : "EMAIL",
"template" : [
{
"_id" : "1",
"templateName" : "abc",
"effectiveStartDate" : ISODate("2017-01-01T12:00:00.000Z"),
"modifiedDate" : ISODate("2017-06-02T22:08:55.782Z"),
"active" : false
}
]
}
I need to update the "templateName" : "xyz" on the basis of "_id" : "tenant/data/EMAIL/ENGLISH"
I have tried these queries but got no success
db.getCollection('data').updateOne({"_id": "tenant/data/EMAIL/ENGLISH"},
{$set : { "template.$.templateName" : "XYZ"}}); 
db.getCollection('data').updateOne({"_id": "tenant/data/EMAIL/ENGLISH"},
{$set : { "template.templateName" : "XYZ"}}); 
Any help will be appreciated.
I have used positional-all operator to update the array.
Here is the query:
db.sample.update(
{
"_id": "tenant/data/EMAIL/ENGLISH"
},
{
$set:{
"template.$[].templateName":"XYZ"
}
}
)
Output
{
"_id" : "tenant/data/EMAIL/ENGLISH",
"tenantId" : "tenant2",
"channelType" : "EMAIL",
"template" : [
{
"_id" : "1",
"templateName" : "XYZ",
"effectiveStartDate" : ISODate("2017-01-01T12:00:00Z"),
"modifiedDate" : ISODate("2017-06-02T22:08:55.782Z"),
"active" : false
}
]
}
hope this will help :)

How to find Immediate Child of a node in mongo db

I have following Collection
Location Collection
[
{id : 1 name : 'l1' , 'location' : pune , parentLocation : Maharashstra},
{id : 2 name : 'l2' , 'location' : nashik , parentLocation : Maharashstra},
{id : 3 name : 'l3' , 'location' : mumbai , parentLocation : Maharashstra},
{id : 4 name : 'l4' , 'location' : Maharashstra , parentLocation : India},
{id : 5 name : 'l5' , 'location' : India , parentLocation : null}
]
Is any query we throw and get immediate node of location using above data.
Example.
When I said India it should be return
India
|---Maharashtra
|---Pune
|---..
|---Nashik
|---Mumbai
Thank you
Using Aggregation framework we can get this desired result.
The below query gives us the result and in this query I have used $lookup, $match, $project
db.location.aggregate([
{
$lookup: {
from: "location",
localField: "location",
foreignField: "parentLocation",
as:"Result"
}
},
{$match:{ "Result": {$exists:true, $ne:[]}, parentLocation: {$ne: null} }},
{$project :{ parentLocation:1, location:1, "Result.location":1}},
{$match: {location: "Maharashstra"}}
])
Documents in my collection
{ "_id" : ObjectId("5b83e4860c35ef57411a575b"), "id" : 1, "name" : "l1", "location" : "pune", "parentLocation" : "Maharashstra" }
{ "_id" : ObjectId("5b83e4860c35ef57411a575c"), "id" : 2, "name" : "l2", "location" : "nashik", "parentLocation" : "Maharashstra" }
{ "_id" : ObjectId("5b83e4860c35ef57411a575d"), "id" : 3, "name" : "l3", "location" : "mumbai", "parentLocation" : "Maharashstra" }
{ "_id" : ObjectId("5b83e4860c35ef57411a575e"), "id" : 4, "name" : "l4", "location" : "Maharashstra", "parentLocation" : "India" }
{ "_id" : ObjectId("5b83e4860c35ef57411a575f"), "id" : 5, "name" : "l5", "location" : "India", "parentLocation" : null }
{ "_id" : ObjectId("5b83fec90c35ef57411a5760"), "id" : 6, "name" : "l6", "location" : "Chennai", "parentLocation" : "Tamilnadu" }
{ "_id" : ObjectId("5b83fec90c35ef57411a5761"), "id" : 7, "name" : "l7", "location" : "Trichy", "parentLocation" : "Tamilnadu" }
{ "_id" : ObjectId("5b83fec90c35ef57411a5762"), "id" : 8, "name" : "l8", "location" : "Alapuzha", "parentLocation" : "Kerala" }
{ "_id" : ObjectId("5b83fec90c35ef57411a5763"), "id" : 9, "name" : "l9", "location" : "Kerala", "parentLocation" : "India" }
{ "_id" : ObjectId("5b83fec90c35ef57411a5764"), "id" : 10, "name" : "l10", "location" : "Tamilnadu", "parentLocation" : "India" }
After executing the above query, the result is
{
"_id" : ObjectId("5b83e4860c35ef57411a575e"),
"location" : "Maharashstra",
"parentLocation" : "India",
"Result" : [
{
"location" : "pune"
},
{
"location" : "nashik"
},
{
"location" : "mumbai"
}
]
}
If we cut down the last $match in our query, then it will return the complete the grouping of states.
db.location.aggregate([
{
$lookup: {
from: "location",
localField: "location",
foreignField: "parentLocation",
as:"Result"
}
},
{$match:{ "Result": {$exists:true, $ne:[]}, parentLocation: {$ne: null} }},
{$project :{ parentLocation:1, location:1, "Result.location":1}}
])
The result of the above query is
{
"_id" : ObjectId("5b83e4860c35ef57411a575e"),
"location" : "Maharashstra",
"parentLocation" : "India",
"Result" : [
{
"location" : "pune"
},
{
"location" : "nashik"
},
{
"location" : "mumbai"
}
]
}
{
"_id" : ObjectId("5b83fec90c35ef57411a5763"),
"location" : "Kerala",
"parentLocation" : "India",
"Result" : [
{
"location" : "Alapuzha"
}
]
}
{
"_id" : ObjectId("5b83fec90c35ef57411a5764"),
"location" : "Tamilnadu",
"parentLocation" : "India",
"Result" : [
{
"location" : "Chennai"
},
{
"location" : "Trichy"
}
]
}

How to join deeply nested array?

Here is my actual database schema.
company_id is reference object of companies collection and booking_days.consultants.consultant_id is reference object of users collection.
I want to join embedded document with company_id and booking_days.consultants.consultant_id.
{
"_id" : ObjectId("5a7040d664544e1bb877deae"),
"company_id" : ObjectId("5a6eb43f437e6a0d9e00c92f"),
"booking_days" : [
{
"booking_date" : ISODate("2018-01-31T00:00:00.000Z"),
"_id" : ObjectId("5a7040d664544e1bb877deca"),
"consultants" : [
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52c"),
"_id" : ObjectId("5a7040d664544e1bb877decc")
},
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52f"),
"_id" : ObjectId("5a7040d664544e1bb877decb")
}
]
},
{
"booking_date" : ISODate("2018-02-01T00:00:00.000Z"),
"_id" : ObjectId("5a7040d664544e1bb877dec6"),
"consultants" : [
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52f"),
"_id" : ObjectId("5a7040d664544e1bb877dec9")
},
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52c"),
"_id" : ObjectId("5a7040d664544e1bb877dec8")
},
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52c"),
"_id" : ObjectId("5a7040d664544e1bb877dec7")
}
]
},
{
"booking_date" : ISODate("2018-02-02T00:00:00.000Z"),
"_id" : ObjectId("5a7040d664544e1bb877dec4"),
"consultants" : [
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52c"),
"_id" : ObjectId("5a7040d664544e1bb877dec5")
}
]
},
],
"__v" : 0
}
I am using below query.
db.getCollection('booking_days').aggregate(
[
{ $match: { company_id:ObjectId("5a6eb43f437e6a0d9e00c92f") } },
{
$lookup: {
localField: "company_id",
from: "companies",
foreignField: "_id",
as: "companies"
},
},
{
$lookup: {
localField: "booking_days.consultants.consultant_id",
from: "users",
foreignField: "_id",
as: "userssss"
},
},
{
$unwind:"$companies"
},
]
)
Actual Output
{
"_id" : ObjectId("5a7040d664544e1bb877deae"),
"company_id" : ObjectId("5a6eb43f437e6a0d9e00c92f"),
"booking_days" : [
{
"booking_date" : ISODate("2018-01-31T00:00:00.000Z"),
"_id" : ObjectId("5a7040d664544e1bb877deca"),
"consultants" : [
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52c"),
"_id" : ObjectId("5a7040d664544e1bb877decc")
},
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52f"),
"_id" : ObjectId("5a7040d664544e1bb877decb")
}
]
},
{
"booking_date" : ISODate("2018-02-01T00:00:00.000Z"),
"_id" : ObjectId("5a7040d664544e1bb877dec6"),
"consultants" : [
{
"consultant_id" : ObjectId("5a6f2854ce7d6938de1dd52f"),
"_id" : ObjectId("5a7040d664544e1bb877dec9")
},
]
},
],
"__v" : 0,
"companies" : {
"_id" : ObjectId("5a6eb43f437e6a0d9e00c92f"),
"first_name" : "Adrienne Runolfsson",
},
"users" : [
{
"_id" : ObjectId("5a6f2854ce7d6938de1dd52c"),
"first_name" : "Christ Hamill",
},
{
"_id" : ObjectId("5a6f2854ce7d6938de1dd52e"),
"first_name" : "Miss Dina Kovacek",
},
]
}
Excepted output. consultant data will come in booking_days.consultants array.
{
"_id" : ObjectId("5a7040d664544e1bb877deae"),
"company_id" : ObjectId("5a6eb43f437e6a0d9e00c92f"),
"booking_days" : [
{
"booking_date" : ISODate("2018-01-31T00:00:00.000Z"),
"_id" : ObjectId("5a7040d664544e1bb877deca"),
"consultants" : [
{
"consultant_id" : {
"_id" : ObjectId("5a6f2854ce7d6938de1dd52c"),
"first_name" : "Christ Hamill",
},
"_id" : ObjectId("5a7040d664544e1bb877decc")
},
{
"consultant_id" : {
"_id" : ObjectId("5a6f2854ce7d6938de1dd52e"),
"first_name" : "Miss Dina Kovacek",
},
"_id" : ObjectId("5a7040d664544e1bb877decb")
}
]
},
{
"booking_date" : ISODate("2018-02-01T00:00:00.000Z"),
"_id" : ObjectId("5a7040d664544e1bb877dec6"),
"consultants" : [
{
"consultant_id" : {
"_id" : ObjectId("5a6f2854ce7d6938de1dd52e"),
"first_name" : "Miss Dina Kovacek",
},
"_id" : ObjectId("5a7040d664544e1bb877dec9")
},
]
},
],
"__v" : 0,
"companies" : {
"_id" : ObjectId("5a6eb43f437e6a0d9e00c92f"),
"first_name" : "Adrienne Runolfsson",
},
}
As such you have to $unwind the localField when it is an embedded document array expect in some cases where localField is an array of scalar ids.
$unwind twice as consultant array is two levels deep followed by $lookup to get the name and $group to get back the expected output.
db.getCollection('booking_days').aggregate([
{"$match":{"company_id":ObjectId("5a6eb43f437e6a0d9e00c92f")}},
{"$lookup":{"localField":"company_id","from":"companies","foreignField":"_id","as":"companies"}},
{"$unwind":"$companies"},
{"$unwind":"$booking_days"},
{"$unwind":"$consultants"},
{"$lookup":{
"localField":"booking_days.consultants.consultant_id",
"from":"users",
"foreignField":"_id",
"as":"booking_days.consultants.consultant_id"
}},
{"$group":{
"_id":{"_id":"$_id","booking_days_id":"$booking_days._id"},
"company_id":{"$first":"$company_id"},
"booking_date":{"$first":"$booking_days.booking_date"},
"companies":{"$first":"$companies"},
"consultants":{"$push":"$booking_days.consultants"}
}},
{"$group":{
"_id":"$_id._id",
"company_id":{"$first":"$company_id"},
"companies":{"$first":"$companies"},
"booking_days":{
"$push":{
"_id":"$_id.booking_days_id",
"booking_date":"$booking_date",
"consultants":"$consultants"
}
}
}}
])
{"Id": "5b87a4c79a9c3feac943fc6c",
"comments" : [
{
"likes" : [],
"_id" : ObjectId("5b87a4c79a9c3feac943fc6c"),
"comment" : "string",
"accountId" : "a426d0da-ac72-4932-828e-3af99a998bc7",
"commentId" : "7d2a05d1-2026-4a13-a5c1-318ed80d1b38",
"reply" : [
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string",
"accountId" : "a426d0da-ac72-4932-828e-3af99a998bc7",
"replyId" : "ec220fd7-3440-44dc-9178-7a1183879463"
},
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string klllll",
"accountId" : "a426d0da-ac72-4932-828e-3af99a998bc7",
"replyId" : "ec220fd7-3440-44dc-9178-7a1183879463"
}
]
},
{
"likes" : [],
"_id" : ObjectId("5b87c301c8a07efa2599c29e"),
"comment" : "testing",
"accountId" : "cfd29f53-d73e-480c-9cfa-ea42b4119266",
"commentId" : "0676047b-1712-4f70-89d5-29c1abe03eaf",
"reply" : [
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string",
"accountId" : "a426d0da-ac72-4932-828e-3af99a998bc7",
"replyId" : "ec220fd7-3440-44dc-9178-7a1183879463"
},
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string klllll",
"accountId" : "a426d0da-ac72-4932-828e-3af99a998bc7",
"replyId" : "ec220fd7-3440-44dc-9178-7a1183879463"
}
]
}
]
}
accountId is in differnt connection
// Expected Out Put
{"Id": "5b87a4c79a9c3feac943fc6c",
"comments" : [
{
"likes" : [],
"_id" : ObjectId("5b87a4c79a9c3feac943fc6c"),
"comment" : "string",
"name" : "apple",
"reply" : [
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string",
"name" : "apple",
},
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string klllll",
"name" : "apple",
}
]
},
{
"likes" : [],
"_id" : ObjectId("5b87c301c8a07efa2599c29e"),
"comment" : "testing",
"name" : "ball",
"reply" : [
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string",
"name" : "apple",
},
{
"_id" : ObjectId("5b87b61e97585ef1d0d22108"),
"comment" : "string klllll",
"name" : "apple", }
]
}
]
}

Fetch Unique Document in Mongodb?

Sample Data:
{"_id" : ObjectId("58bd10e4ff1743c527754160"),
"data" : [
{
"No" : "70",
"Type" : "82",
"Device" : "01",
"timestamp" : "2017-03-06 13:00:32"
}]
},
{"_id" : ObjectId("58bd10sdfe4ff1743csdf0754"),
"data" : [
{
"No" : "75",
"Type" : "22",
"Device" : "02",
"timestamp" : "2017-03-06 13:00:32"
}]
}
I have some document which having same timestamp,so I want to find only unique document on the basis of timestamp.
I have done distinct of timestamp but I want full document.
desired Output:
If same timestamp is there I want only One document.
You will only get one output if you run this query.
db.getCollection('tests').aggregate([{$match:{"data.timestamp":"2017-03-06 13:00:32"}},{$limit:1}])
Solution 1:
db.your_collection.aggregate([
{
$group:{
_id:"$data.timestamp",
data:{
$first:"$data"
}
}
}
])
This will give you following :
{ "_id" : [ "2017-03-06 13:00:32" ], "data" : [ { "No" : "70", "Type" : "82", "Device" : "01", "timestamp" : "2017-03-06 13:00:32" }, { "No" : "10", "Type" : "20", "Device" : "01", "timestamp" : "2018-02-04 10:00:00" } ] }
Solution 2 :
db.your_collection.aggregate([
{ $unwind : '$data'},
{ $group : {
_id : '$data.timestamp',
'No': { $first : '$data.No'},
'Type': { $first : '$data.Type'},
'Device': { $first : '$data.Device'},
'timestamp': { $first : '$data.timestamp'},
}
}
]);
This will give you following :
[
{ "_id" : "2017-03-06 13:00:32", "No" : "70", "Type" : "82", "Device" : "01", "timestamp" : "2017-03-06 13:00:32" },
{ "_id" : "2018-02-04 10:00:00", "No" : "10", "Type" : "20", "Device" : "01", "timestamp" : "2018-02-04 10:00:00" },
]

Nested array count without unwind?

Is it possible to count a nested array without using $unwind in MongoDB? If possible then help me out. My json file is like this:
{
"_id" : ObjectId("57307906f051147d5317984e"),
"user" : [
{
"firstName" : "chetan",
"lastName" : "kumar",
"age" : 23,
"like" : [
{
"bookname" : "mongo"
},
{
"bookname" : "php"
},
{
"bookname" : "java"
}
]
},
{
"firstName" : "nepolean",
"lastName" : "dang",
"age" : 26,
"like" : [
{
"bookname" : "mongo"
},
{
"bookname" : "php"
}
]
},
{
"firstName" : "Raj",
"lastname" : "kumar",
"age" : 26,
"like" : [
{
"bookname" : "mongo"
}
]
}
],
"sales" : [
{
"firstName" : "ashu",
"lastName" : "jha",
"age" : 27
}
]
}
If I use $unwind then I can easily find out the result like this:
db.userdetail.aggregate([
{"$unwind": "$user"},
{"$project": {
"likecount": { "$size": "$user.like" }
}}
]).pretty()
{ "_id" : ObjectId("57307906f051147d5317984e"), "likecount" : 3 }
{ "_id" : ObjectId("57307906f051147d5317984e"), "likecount" : 2 }
{ "_id" : ObjectId("57307906f051147d5317984e"), "likecount" : 1 }