Related
I´m facing a challenge here. I have this collection here
{
"_id" : ObjectId("5e0ff6d424f9fc12bc3d9464"),
"name" : "Pizzaria Don Juan",
"active" : true,
"branches" : [
{
"location" : {
"type" : "Point",
"coordinates" : [ ]
},
"_id" : ObjectId("5e19cafc31d60216b8dbd649"),
"name" : "Parque da Mooca",
"address" : "Rua Dianópolis",
"addressNumber" : 1283,
"federalId" : "10.445.089/0001-44",
"complement" : "Ap 55",
"postalCode" : "03126-007",
"coveredArea" : 0,
"neighborhood" : "Parque da Mooca",
"deliveryTime" : 0,
"deliveryRate" : 0,
"standard" : false,
"city" : "Mococa",
"state" : "RJ",
"emails" : [ ],
"phones" : [ ],
"daysWeek" : [ ],
"socialMedias" : [ ],
"paymentTerms" : [ ],
"sections" : [ ]
},
{
"location" : {
"type" : "Point",
"coordinates" : [ ]
},
"_id" : ObjectId("5e19c9a531d60216b8dbd639"),
"name" : "Principal",
"address" : "Rua Nicolau Filizola",
"addressNumber" : null,
"federalId" : "10.445.089/0001-53",
"complement" : "",
"postalCode" : "05547-010",
"coveredArea" : 0,
"neighborhood" : "Jardim Rosa Maria",
"deliveryTime" : 0,
"deliveryRate" : 0,
"standard" : true,
"city" : "São Paulo",
"state" : "SP",
"emails" : [
{
"_id" : ObjectId("5e19ca9531d60216b8dbd643"),
"name" : "Contato",
"address" : "contato#pizzariadonjuan.com.br"
},
{
"_id" : ObjectId("5e19ca9531d60216b8dbd642"),
"name" : "Contato2",
"address" : "contato2#pizzariadonjuan.com.br"
}
],
"phones" : [
{
"_id" : ObjectId("5e19ca9531d60216b8dbd645"),
"name" : "Principal",
"number" : "(11) 99740-2216"
},
{
"_id" : ObjectId("5e19ca9531d60216b8dbd644"),
"name" : "Secundario",
"number" : "(11) 2562-2759"
}
],
"daysWeek" : [
{
"_id" : ObjectId("5e1cf99741c52d4a587a9162"),
"startsAt" : 64800000,
"endsAt" : 82800000,
"opens" : true,
"dayWeekId" : ObjectId("5e1a124a17fd054900a1afb2")
},
{
"_id" : ObjectId("5e1cf99741c52d4a587a9161"),
"startsAt" : 0,
"endsAt" : 0,
"opens" : false,
"dayWeekId" : ObjectId("5e1a126817fd054900a1afb3")
},
{
"_id" : ObjectId("5e1cfbed41c52d4a587a9170"),
"startsAt" : 64980000,
"endsAt" : 82800000,
"opens" : true,
"dayWeekId" : ObjectId("5e1a126e17fd054900a1afb4")
},
{
"_id" : ObjectId("5e1b8fac96516432845e364c"),
"startsAt" : 64980000,
"endsAt" : 82800000,
"opens" : true,
"dayWeekId" : ObjectId("5e1a127517fd054900a1afb5")
},
{
"_id" : ObjectId("5e1cfbed41c52d4a587a916f"),
"startsAt" : 64980000,
"endsAt" : 82800000,
"opens" : true,
"dayWeekId" : ObjectId("5e1a127a17fd054900a1afb6")
},
{
"_id" : ObjectId("5e1cfbed41c52d4a587a916e"),
"startsAt" : 64800000,
"endsAt" : 82800000,
"opens" : true,
"dayWeekId" : ObjectId("5e1a23f8bf353f493c74e8ae")
},
{
"_id" : ObjectId("5e1cfbed41c52d4a587a916d"),
"startsAt" : 61380000,
"endsAt" : 83154000,
"opens" : true,
"dayWeekId" : ObjectId("5e1a2407bf353f493c74e8af")
}
],
"socialMedias" : [
{
"_id" : ObjectId("5e1d082641c52d4a587a9191"),
"socialMediaId" : ObjectId("5e10089a3330ad05d4e1867d"),
"url" : "rewrwerwerwerwerwerwerwer"
}
],
"paymentTerms" : [
{
"_id" : ObjectId("5e1d143041c52d4a587a91b7"),
"paymentTermId" : ObjectId("5e1a2277bf353f493c74e8a7")
},
{
"_id" : ObjectId("5e1d143041c52d4a587a91b6"),
"paymentTermId" : ObjectId("5e1a228cbf353f493c74e8a8")
},
{
"_id" : ObjectId("5e1d143041c52d4a587a91b5"),
"paymentTermId" : ObjectId("5e1a229ebf353f493c74e8a9")
}
],
"sections" : [
{
"_id" : ObjectId("5e1e535441c52d4a587a9208"),
"name" : "Camisetas",
"products" : [
{
"_id" : ObjectId("5e1e662f044582129844ffd5"),
"name" : "DonJuan M",
"description" : "",
"quantityAvailable" : 0,
"image" : "",
"price" : 0,
"validFrom" : ISODate("2020-01-15T01:08:49.552Z"),
"validTo" : ISODate("2020-01-15T01:08:49.552Z"),
"enabled" : true
}
]
},
{
"_id" : ObjectId("5e20ec889c05f229a484ea3d"),
"name" : "Imãs",
"products" : [
{
"_id" : ObjectId("5e20ec889c05f229a484ea3e"),
"name" : "Imã",
"description" : "Imã",
"quantityAvailable" : 0,
"image" : "",
"price" : 0,
"validFrom" : ISODate("0001-01-01T00:00:00Z"),
"validTo" : ISODate("9999-12-31T00:00:00Z"),
"enabled" : true
}
]
}
]
}
],
"users" : [
{
"_id" : ObjectId("5e10fc2adc147a373c312144")
},
{
"_id" : ObjectId("5e11ff8003eb832ef84342a6")
}
],
"socialMedias" : [
{
"_id" : ObjectId("5e165672a2204b49c892db74"),
"socialMediaId" : ObjectId("5e10089a3330ad05d4e1867d"),
"url" : "uuuutt"
},
{
"_id" : ObjectId("5e15385fb3a0aa1004ac3598"),
"socialMediaId" : ObjectId("5e1009043330ad05d4e1867f"),
"url" : "jkkjkjkjkjk"
}
],
"sections" : [
{
"_id" : ObjectId("5e15313b2e985e16ec4e7413"),
"name" : "Bebidas",
"products" : [
{
"_id" : ObjectId("5e1e6381044582129844ffc2"),
"name" : "Coca Cola Zero 2 Litros",
"description" : "",
"quantityAvailable" : 0,
"image" : "",
"price" : 18.39,
"validFrom" : ISODate("1970-01-01T00:00:00Z"),
"validTo" : ISODate("1970-01-01T00:00:00Z"),
"enabled" : true
},
{
"_id" : ObjectId("5e1e6381044582129844ffc3"),
"name" : "Coca Cola 2 Litros",
"description" : "",
"quantityAvailable" : 0,
"image" : "",
"price" : 21.42,
"validFrom" : ISODate("1970-01-01T00:00:00Z"),
"validTo" : ISODate("1970-01-01T00:00:00Z"),
"enabled" : true
},
{
"_id" : ObjectId("5e1e662f044582129844ffda"),
"name" : "Cerveja Heineken Lata 350ml",
"description" : "Cerveja Heineken Lata 350ml",
"quantityAvailable" : 0,
"image" : "volkswagen-polo.jpg",
"price" : 1.55,
"validFrom" : ISODate("2020-01-01T00:00:00Z"),
"validTo" : ISODate("1970-01-01T00:00:00Z"),
"enabled" : true
}
]
},
{
"_id" : ObjectId("5e20e8de9c05f229a484ea27"),
"name" : "Esfihas",
"products" : [
{
"_id" : ObjectId("5e20e8de9c05f229a484ea28"),
"name" : "Esfiha de carne",
"description" : "Esfiha de carne",
"quantityAvailable" : 0,
"image" : "",
"price" : 5,
"validFrom" : ISODate("2020-01-01T00:00:00Z"),
"validTo" : null,
"enabled" : true
}
]
}
],
"__v" : 0
}
{
"_id" : ObjectId("5e0ffd23991918424c8d7c3b"),
"name" : "Pizza Ruth",
"active" : true,
"users" : [ ],
"socialMedias" : [ ],
"branches" : [ ],
"sections" : [ ],
"__v" : 0
}
{
"_id" : ObjectId("5e0ffd3d991918424c8d7c3c"),
"name" : "Feijão de Corda",
"active" : true,
"users" : [ ],
"socialMedias" : [ ],
"branches" : [ ],
"sections" : [ ],
"__v" : 0
}
The fields validFrom and validTo (Date fields) from the collection products nested in branches.sections need to be converted to the format yyyy-mm-dd. I can do that with this aggregation pipeline:
{ $unwind: { path: "$branches.sections", preserveNullAndEmptyArrays: true } },
{
"$addFields": {
"branches.sections.products": {
$map: {
input: "$branches.sections.products",
as: "product",
in: {
'_id': "$$product._id",
'name': "$$product.name",
'description': "$$product.description",
'quantityAvailable': "$$product.quantityAvailable",
'image': "$$product.image",
'imageUrl': "$$product.imageUrl",
'price': "$$product.price",
'validFrom' : {"$dateToString": { "date": "$$product.validFrom", "format": "%Y-%d-%m" }},
'validTo' : {"$dateToString": { "date": "$$product.validTo", "format": "%Y-%d-%m" }},
'enabled': "$$product.enabled",
}
}
}
}
}
I can successfully convert those date fields, but I need now to "re-unwind" the array products, in order to be just like before the unwind.
Any clue in how to proceed? Or even a different way to format those dates without having to unwind? Tried dozens of ways of $group, but without any success.
You just need to $map over each nested array to drill upload the validTo and validFrom field
.aggregate([
{ "$addFields": {
"branches": {
"$map": {
"input": "$branches",
"as": "branch",
"in": {
"$mergeObjects": [
"$$branch",
{ "section": {
"$map": {
"input": "$$branch.sections",
"as": "section",
"in": {
"$mergeObjects": [
"$$section",
{ "product": {
"$map": {
"input": "$$section.products",
"as": "product",
"in": {
"$mergeObjects": [
"$$product",
{
"validFrom": { "$dateToString": { "date": "$$product.validFrom", "format": "%Y-%d-%m" }},
"validTo": { "$dateToString": { "date": "$$product.validTo", "format": "%Y-%d-%m" }}
}
]
}
}
}}
]
}
}
}}
]
}
}
}
}}
])
MongoPlayground
In my mongodb collection I have next records
{ "_id" : ObjectId("5d0dfb68264b2d01a3237a3e"), "name" : "lexa", "cat" : 2, "gender" : "male", "date" : ISODate("2019-06-22T09:56:56.070Z") }
{ "_id" : ObjectId("5d0dfb6c264b2d01a3237a3f"), "name" : "dima", "cat" : 2, "gender" : "male", "date" : ISODate("2019-06-22T09:57:00.925Z") }
{ "_id" : ObjectId("5d0dfb75264b2d01a3237a40"), "name" : "lena", "cat" : 2, "gender" : "female", "date" : ISODate("2019-06-22T09:57:10.003Z") }
{ "_id" : ObjectId("5d0dfb7a264b2d01a3237a41"), "name" : "nina", "cat" : 2, "gender" : "female", "date" : ISODate("2019-06-22T09:57:14.941Z") }
{ "_id" : ObjectId("5d0dfb8f264b2d01a3237a42"), "name" : "nina", "cat" : 1, "gender" : "female", "date" : ISODate("2019-06-22T09:57:35.128Z") }
{ "_id" : ObjectId("5d0dfb93264b2d01a3237a43"), "name" : "lena", "cat" : 1, "gender" : "female", "date" : ISODate("2019-06-22T09:57:39.789Z") }
{ "_id" : ObjectId("5d0dfb9b264b2d01a3237a44"), "name" : "dima", "cat" : 1, "gender" : "male", "date" : ISODate("2019-06-22T09:57:47.150Z")
Then I use aggregation mongo framework to group that records by cat.
db.foo.aggregate([{'$group':
{
'_id': '$cat',
'users':
{'$push':
{
'name':'$name',
'gender': '$gender'
}
}
}
}])
That query returns me next result
{
"_id" : 1,
"users" : [
{
"name" : "nina",
"gender" : "female"
},
{
"name" : "lena",
"gender" : "female"
},
{
"name" : "dima",
"gender" : "male"
}
]
}
{
"_id" : 2,
"users" : [
{
"name" : "lexa",
"gender" : "male"
},
{
"name" : "dima",
"gender" : "male"
},
{
"name" : "lena",
"gender" : "female"
},
{
"name" : "nina",
"gender" : "female"
}
]
}
And the question is what I need to add to my query to group by my users array. I want to get something like this
{
"_id" : 1,
"users" : [
{
"gender": "male",
"names": ["dima"]
},
{
"gender": "female",
"names": ["lena", "nina"]
}
]
}
{
"_id" : 2,
"users" : [
{
"gender": "male",
"names": ["lexa", "dima"]
},
{
"gender": "female",
"names": ["lena", "nina"]
}
]
}
I need to have my nested array been grouped too without loosing first group result
Would be easier to first group by cat X gender and then restructure the data like so :
db.foo.aggregate([
{'$group':
{
'_id': {cat: '$cat', gender: "$gender"},
'names':
{'$push':
{
'name':'$name',
}
}
}
},
{
$group: {
'_id': "$_id.cat",
users: { $push: { gender: "$_id.gender", names: "$names" }
}
}
])
I have the following query, what I want is to have a combined group of custom group field names, with field value.
db.getCollection('mycollection').aggregate([
{"$match":{
"expireDate":{"$gte":"2018-02-06T00:00:00.000Z"},
"publishDate":{"$lte":"2018-02-06T00:00:00.000Z"},
"isPublished":true,"isDrafted":false,
"deletedAt":{"$eq":null},"deleted":false
}},
{"$group":{
"twentyFourHourAgo":{
"$sum":{
"$cond":[
{"$gt":["$publishDate","2018-02-04T08:48:16.892Z"]},1,0
]
}
},
"fortyEightHourAgo":{
"$sum":{
"$cond":[
{"$gt":["$publishDate","2018-02-01T08:48:16.892Z"]},1,0
]
}
},
"thirtyDaysAgo":{
"$sum":{
"$cond":[
{"$gt":["$publishDate","2017-12-31T08:48:16.892Z"]},1,0
]
}
},
"_id":{
"position":{"$ifNull":["$position","Unknown"]},
"workType":{"$ifNull":["$workType","Unknown"]},
"functionalArea":{"$ifNull":["$functionalArea","Unknown"]},
"minimumEducation":{"$ifNull":["$minimumEducation","Unknown"]},
"gender":{"$ifNull":["$gender","Unknown"]},
"contractType":{"$ifNull":["$contractType","Unknown"]},
"locations":{"$ifNull":["$locations","Unknown"]},
"requiredLanguages":{"$ifNull":["$requiredLanguages","Unknown"]},
"company":{"$ifNull":["$company.name","Unknown"]}},"count":{"$sum":1}
}
},
{"$group":{
"_id":null,
"twentyFourHourAgo":{
"$sum":"twentyFourHourAgo"
},
"fortyEightHourAgo":{
"$sum":"$fortyEightHourAgo"
},
"thirtyDaysAgo":{
"$sum":"$thirtyDaysAgo"
},
"position":{"$addToSet":{"Name":"$_id.position","Count":"$count"}},
"workType":{"$addToSet":{"Name":"$_id.workType","Count":"$count"}},
"functionalArea":{
"$addToSet":{"Name":"$_id.functionalArea","Count":"$count"}
},
"minimumEducation":{
"$addToSet":{"Name":"$_id.minimumEducation","Count":"$count"}
},
"gender":{"$addToSet":{"Name":"$_id.gender","Count":"$count"}},"contractType":{"$addToSet":{"Name":"$_id.contractType","Count":"$count"}},"locations":{"$addToSet":{"Name":"$_id.locations","Count":"$count"}},"requiredLanguages":{"$addToSet":{"Name":"$_id.requiredLanguages","Count":"$count"}},"company":{"$addToSet":{"Name":"$_id.company","Count":"$count"}}}}]
)
my document inside collection schema is like:
/* 1 */
{
"_id" : ObjectId("59e4540bf14f1607b90ffb81"),
"vacancyNumber" : "1",
"position" : "Software Tester",
"publishDate" : ISODate("2018-01-02T00:00:00.000Z"),
"expireDate" : ISODate("2018-05-29T00:00:00.000Z"),
"yearsOfExperience" : 40,
"minimumEducation" : "Doctorate",
"functionalArea" : "Education",
"company" : {
"id" : ObjectId("59e453fbf14f1607b90ffb80"),
"name" : "First Company",
"profile" : "profile",
"logo" : {
"container" : "companyFiles",
"name" : "abbbff58cd3fda2c59ab2ee620ea5aa0",
"mime" : ".png",
"size" : 5806
}
},
"durations" : {
"years" : 3,
"months" : 4
},
"probationPeriod" : {
"duration" : 34,
"unit" : "month"
},
"salary" : {
"minSalary" : 1000,
"maxSalary" : 2000,
"currency" : "USD",
"period" : "monthly",
"isNegotiable" : true
},
"locations" : [
"Germany",
"Itly",
"Iran"
],
"canApplyOnline" : true,
"skills" : [
"Skill1",
"Skill2",
"Skill3",
"Skill4"
],
"requiredLanguages" : [
"Arabic",
"English",
"Russian",
"Dari",
"French"
],
"keywords" : [
"Key1",
"Key2"
],
"deleted" : false,
"deletedAt" : null,
"isDrafted" : false,
"isPublished" : true,
"requiresTravel" : true,
"gender" : "male",
"nationalities" : [
"afghan"
],
"workType" : "Full Time",
"contractType" : "Permanent",
}
/* 2 */
{
"_id" : ObjectId("59f9402e05d04ebe5653d98f"),
"vacancyNumber" : "1",
"position" : "Software Engineer",
"publishDate" : ISODate("2018-01-03T00:00:00.000Z"),
"expireDate" : ISODate("2018-11-10T00:00:00.000Z"),
"yearsOfExperience" : 40,
"minimumEducation" : "Doctorate",
"functionalArea" : "Education",
"company" : {
"id" : ObjectId("59e453fbf14f1607b90ffb80"),
"name" : "First Company",
"profile" : "profile",
"logo" : {
"container" : "logo container",
"name" : "logo name",
"mime" : "logo mime type",
"size" : 1
}
},
"durations" : {
"years" : 3,
"months" : 4
},
"probationPeriod" : {
"duration" : 34,
"unit" : "month"
},
"salary" : {
"minSalary" : 1000,
"maxSalary" : 2000,
"currency" : "USD",
"period" : "monthly",
"isNegotiable" : true
},
"locations" : [
"Afghanistan",
"Itly",
"Iran"
],
"skills" : [
"Skill1",
"Another Skill"
],
"requiredLanguages" : [
"Arabic",
"English",
"Russian",
"Dari",
"French"
],
"keywords" : [
"Keyword",
"Key1"
],
"deleted" : false,
"deletedAt" : null,
"isDrafted" : false,
"isPublished" : true,
"gender" : "male",
"nationalities" : [
"afghan",
"iranian"
],
"workType" : "Full Time",
"contractType" : "Short-Term",
}
/* 3 */
{
"_id" : ObjectId("5a03235234f7504f13970abd"),
"vacancyNumber" : "1",
"position" : "Software Tester",
"publishDate" : ISODate("2017-10-10T00:00:00.000Z"),
"expireDate" : ISODate("2018-11-25T00:00:00.000Z"),
"yearsOfExperience" : 40,
"minimumEducation" : "Doctorate",
"functionalArea" : "IT Software",
"company" : {
"id" : ObjectId("59e453fbf14f1607b90ffb80"),
"name" : "My First Company",
"profile" : "profile",
"logo" : {
"container" : "logo container",
"name" : "logo name",
"mime" : "logo mime type",
"size" : 1
}
},
"durations" : {
"years" : 3,
"months" : 4
},
"probationPeriod" : {
"duration" : 34,
"unit" : "month"
},
"salary" : {
"minSalary" : 1000,
"maxSalary" : 2000,
"currency" : "USD",
"period" : "monthly",
"isNegotiable" : true
},
"locations" : [
"Germany",
"Itly",
"Iran"
],
"skills" : [
"Skill1",
"Test Skill"
],
"requiredLanguages" : [
"Arabic",
"English",
"Russian",
"Dari",
"French"
],
"keywords" : [
"Test Key",
"Keyword"
],
"deleted" : false,
"deletedAt" : null,
"isDrafted" : false,
"isPublished" : true,
"gender" : "female",
"nationalities" : [
"afghan"
],
"workType" : "Part Time",
"contractType" : "Permanent",
}
Now I want to count the group of data by my custom expression check 'twentyFourHourAgo, fortyEightHourAgo, thirtyDaysAgo', and also by the value of a field (functionalArea, position, locations, keywords, workType).
My current query result is
{
"_id" : null,
"twentyFourHourAgo" : 0,
"fortyEightHourAgo" : 0.0,
"thirtyDaysAgo" : 2.0,
"position" : [
{
"Name" : "Software Engineer",
"Count" : 1.0
},
{
"Name" : "Software Tester",
"Count" : 1.0
}
],
"workType" : [
{
"Name" : "Full Time",
"Count" : 1.0
},
{
"Name" : "Part Time",
"Count" : 1.0
}
],
"functionalArea" : [
{
"Name" : "Education",
"Count" : 1.0
},
{
"Name" : "IT Software",
"Count" : 1.0
}
],
"minimumEducation" : [
{
"Name" : "Doctorate",
"Count" : 1.0
}
],
"gender" : [
{
"Name" : "male",
"Count" : 1.0
},
{
"Name" : "female",
"Count" : 1.0
}
],
"contractType" : [
{
"Name" : "Short-Term",
"Count" : 1.0
},
{
"Name" : "Permanent",
"Count" : 1.0
}
],
"locations" : [
{
"Name" : [
"Afghanistan",
"Itly",
"Iran"
],
"Count" : 1.0
},
{
"Name" : [
"Germany",
"Itly",
"Iran"
],
"Count" : 1.0
}
],
"requiredLanguages" : [
{
"Name" : [
"Arabic",
"English",
"Russian",
"Dari",
"French"
],
"Count" : 1.0
}
],
"company" : [
{
"Name" : "First Company",
"Count" : 1.0
},
{
"Name" : "My First Company",
"Count" : 1.0
}
]
}
As you see, I have three document that has following properties:
Two document that has the same position Software Tester, but query return 1 Software Tester (It means if I have multiple documents that have some common values in specific columns, their count result is wrong). The same problem exists for other fields 'contractType, workType, etc...'.
In array-type fields such as locations, my first document has Germany, Italy, Iran values in locations array, my second document has Afghanistan, Italy, Iran, and my third document has Germany, Italy, Iran. But query result is like this:
"locations" : [
{
"Name" : [
"Afghanistan",
"Itly",
"Iran"
],
"Count" : 1.0
},
{
"Name" : [
"Germany",
"Itly",
"Iran"
],
"Count" : 1.0
}
],
This should be like: Germany => 2, Italy,Iran => 3, and Afghanistan => 1
The same problem exists for other array type fields.
Apologies I misunderstood your question earlier. To be able to $unwind the location array, but NOT effect your twentyFourHourAgo etc you could look at using $first.
You'll need to $unwind any array if you wish count/sum the individual elements.
Example of how using $first.
db.getCollection('foo').aggregate([
{ $unwind : "$locations" },
{ "$group" : { "_id" : "$_id",
"twentyFourHourAgo":{ $first : {
"$sum" : { "$cond":[
{"$gt":["$publishDate", ISODate("2016-10-10T00:00:00.000Z")]},1,0 ] } } },
"fortyEightHourAgo" : { $first : {
"$sum" : { "$cond" : [
{ "$gt" : [ "$publishDate","2018-01-02T00:00:00.000Z"]},1,0 ] } } },
"thirtyDaysAgo" : { $first : {
"$sum" : { "$cond" : [
{ "$gt" : [ "$publishDate","2017-12-31T08:48:16.892Z"]},1,0 ] } } },
} },
{ "$group" : { "_id" : null,
"twentyFourHourAgo" : { "$sum" : "$twentyFourHourAgo" },
"fortyEightHourAgo" : { "$sum" : "$fortyEightHourAgo" },
"thirtyDaysAgo" : { "$sum" : "$thirtyDaysAgo" },
}}
])
Output:
"_id" : null,
"twentyFourHourAgo" : 0,
"fortyEightHourAgo" : 3.0,
"thirtyDaysAgo" : 3.0,
Please see here $first for further information on why I think it might be of use. I've stuck an $unwind at the beginning to help prove that it will solve the problem in your OP.
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", }
]
}
]
}
I have datas of following format collection(projects) inside my database:
{ "_id" : ObjectId("5981a80f223e491a58230e5d"), "id" : 2, "name" : "gbqplhlqxzwl", "managerId" : 65151, "startDate" : "03.11.1999", "finishDate" : "02.01.2003", "projectStatus" : "POSTPONED", "participants" : [ ], "estimatedBudget" : 6017891.811079914 }
{ "_id" : ObjectId("5981a80f223e491a58230e5e"), "id" : 3, "name" : "erfekfsdgryu", "managerId" : 83749, "startDate" : "07.07.2007", "finishDate" : "26.12.2027", "projectStatus" : "POSTPONED", "participants" : [ 19229, 81856, 79270, 5509, 70344, 39424 ], "estimatedBudget" : 3086213.8981674756 }
{ "_id" : ObjectId("5981a80f223e491a58230e5f"), "id" : 1, "name" : "jvbzobhppntd", "managerId" : 18925, "startDate" : "29.04.1999", "finishDate" : "13.10.2008", "projectStatus" : "OPEN", "participants" : [ 46100, 96968, 6676, 56121, 4716, 68901, 43990, 48587, 62547, 30292, 65153, 17551, 27083, 20261, 27097, 50036, 86585, 69890, 18790, 22592, 60774, 93709, 78471, 27157, 4328, 36501, 47296, 16831 ], "estimatedBudget" : 3581496.7068344904 }
{ "_id" : ObjectId("5981a80f223e491a58230e60"), "id" : 4, "name" : "cdspkkqwvwld", "managerId" : 62042, "startDate" : "13.03.1998", "finishDate" : "20.06.2007", "projectStatus" : "OPEN", "participants" : [ 53480, 60897, 23677, 22064, 60807, 66637, 84609, 28378, 87143, 27675, 79283, 94992, 20429, 48769, 91671, 41747, 21651, 91134, 41684, 57228, 51949, 18756, 45679, 87781, 67287, 6902, 27526 ], "estimatedBudget" : 2126283.953787842 }
....
I need to find the busiest employee and list all his projects.
participants array contains employee ids who participate in the project.
I use the following query to find the busiest employee:
db.projects.aggregate(
{
$unwind: '$participants'
},
{
$addFields: {
count: 1
}
},
{
$group: {
_id : '$participants',
participation_count : {
'$sum':'$count'
}
}
},
{
$sort:{participation_count:-1}
},
{
$limit:1
}
)
and this work correctly. But I have no ideas how to list all his projects.
any ideas?
db.projects.aggregate(
[
{
$unwind: '$participants'
},
{
$addFields: {
count: 1
}
},
{
$group: {
_id : '$participants',
participation_count : {'$sum':'$count'},
projectId : {$push: '$id'}
}
},
{
$sort:{participation_count:-1}
},
{
$limit:1
}
],
{
allowDiskUse:true
}
)