$project $lookup value not shown after $group - mongodb

I have 2 related collection which i want to do a $lookup.
switches
{
"_id" : ObjectId("5e8453c095c85ca0c33a9461"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"relay" : NumberInt(1),
"name" : "Lampu Tengah",
"voltage" : 80.0,
"duration" : null,
"status" : true,
"triggered_by" : ObjectId("5e5fd642fce106005319e884"),
"created_at" : ISODate("2020-04-01T15:41:36.588+0000"),
"updated_at" : ISODate("2020-04-01T22:59:39.261+0000")
}
{
"_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"relay" : NumberInt(2),
"name" : "Kipas Angin",
"voltage" : 100.0,
"duration" : null,
"status" : true,
"triggered_by" : ObjectId("5e5fd642fce106005319e884"),
"created_at" : ISODate("2020-04-01T15:45:48.099+0000"),
"updated_at" : ISODate("2020-04-01T15:45:48.099+0000")
}
power_usage_month
{
"_id" : ObjectId("5e87edffffba850e8d72ce27"),
"switch_id" : ObjectId("5e8453c095c85ca0c33a9461"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"current" : 19.345,
"time_minutes" : NumberInt(123),
"created_at" : ISODate("2020-04-02T15:01:37.521+0000"),
"updated_at" : ISODate("2020-04-02T15:01:37.521+0000")
}
{
"_id" : ObjectId("5e87ee06ffba850e8d72ce28"),
"switch_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"current" : 17.5,
"time_minutes" : NumberInt(123),
"created_at" : ISODate("2020-04-03T20:35:09.870+0000"),
"updated_at" : ISODate("2020-04-03T20:35:09.871+0000")
}
{
"_id" : ObjectId("5e87ee0cffba850e8d72ce29"),
"switch_id" : ObjectId("5e8453c095c85ca0c33a9461"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"current" : 19.345,
"time_minutes" : NumberInt(124),
"created_at" : ISODate("2020-04-04T01:45:00.000+0000"),
"updated_at" : ISODate("2020-04-04T01:45:00.000+0000")
}
{
"_id" : ObjectId("5e87ee13ffba850e8d72ce2a"),
"switch_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"current" : 17.5,
"time_minutes" : NumberInt(124),
"created_at" : ISODate("2020-04-04T01:45:00.000+0000"),
"updated_at" : ISODate("2020-04-04T01:45:00.000+0000")
}
{
"_id" : ObjectId("5e87ee18ffba850e8d72ce2b"),
"switch_id" : ObjectId("5e8453c095c85ca0c33a9461"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"current" : 19.345,
"time_minutes" : NumberInt(125),
"created_at" : ISODate("2020-04-04T01:45:00.000+0000"),
"updated_at" : ISODate("2020-04-04T01:45:00.000+0000")
}
{
"_id" : ObjectId("5e87ee20ffba850e8d72ce2c"),
"switch_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"current" : 17.5,
"time_minutes" : NumberInt(125),
"created_at" : ISODate("2020-04-04T01:45:00.000+0000"),
"updated_at" : ISODate("2020-04-04T01:45:00.000+0000")
}
{
"_id" : ObjectId("5e87ee26ffba850e8d72ce2d"),
"switch_id" : ObjectId("5e8453c095c85ca0c33a9461"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"current" : 19.345,
"time_minutes" : NumberInt(126),
"created_at" : ISODate("2020-04-04T01:45:00.000+0000"),
"updated_at" : ISODate("2020-04-04T01:45:00.000+0000")
}
{
"_id" : ObjectId("5e87ee2dffba850e8d72ce2e"),
"switch_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"current" : 17.5,
"time_minutes" : NumberInt(126),
"created_at" : ISODate("2020-04-04T01:45:00.000+0000"),
"updated_at" : ISODate("2020-04-04T01:45:00.000+0000")
}
Now i want to "join" these collections using $lookup and $project the field i want to show, but apparently the $project value won't show after i do a $group. Here's my query
db.getCollection("power_usages_month").aggregate(
[
{
"$project" : {
"_id" : NumberInt(0),
"power_usages_month" : "$$ROOT"
}
},
{
"$lookup" : {
"localField" : "power_usages_month.switch_id",
"from" : "switches",
"foreignField" : "_id",
"as" : "switches"
}
},
{
"$unwind" : {
"path" : "$switches",
"preserveNullAndEmptyArrays" : false
}
},
{
"$group" : {
"_id" : "$power_usages_month.switch_id",
"sum_current" : {
"$sum" : "$power_usages_month.current"
}
}
},
{
"$project" : {
"switch_id" : "$_id",
"device_id" : "$switches.device_id",
"sum_current" : "$sum_current",
"voltage" : "$switches.voltage",
}
}
],
{
"allowDiskUse" : true
}
);
The "device_id" : "$switches.device_id", and "voltage" : "$switches.voltage" cannot appear as expected according to the result:
{
"_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
"switch_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
"sum_current" : 70.0
}
{
"_id" : ObjectId("5e8453c095c85ca0c33a9461"),
"switch_id" : ObjectId("5e8453c095c85ca0c33a9461"),
"sum_current" : 77.38
}
How could it be? Please tell me the fault of the query..
Edit: Here's my desired result
{
"_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
"switch_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"sum_current" : 70.0,
"voltage" : 80.0
}
{
"_id" : ObjectId("5e8453c095c85ca0c33a9461"),
"switch_id" : ObjectId("5e8453c095c85ca0c33a9461"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"sum_current" : 77.38,
"voltage" : 100.0
}

you can do the project as the last step after grouping and $lookup
also you can handle all of that in the group,
what you will include in the $group will be only available with you in the query,
but lets say you need to gather the power_usages_month docs used by each switch in one array in that switch,
but you don't need all the info from that power_usages_month, you just need the current and the time_minutes for example
you can do something like that
db.powerUsageMonth.aggregate(
[
{
$match: {}
},
{
$lookup: {
from: 'switches',
localField: 'switch_id',
foreignField: '_id',
as: 'switch'
}
},
{
$unwind: '$switch'
},
{
$group: {
_id: '$switch._id',
sum_current: {
$sum: '$current'
},
switchInfo: {
$first: '$switch'
},
powerUsageDocs: {
$addToSet: '$$ROOT'
}
}
},
{
$project: {
_id: 1,
sum_current: 1,
switchInfo: 1,
'powerUsageDocs.current': 1,
'powerUsageDocs.time_minutes': 1,
}
}
]
)
this will return an array of switches with their total current and the switch info (you can do some projection here too if you don't need all the switch info), and the power usages docs related to this switch (after projection)
the result will be something like that
{
"_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
"sum_current" : 70,
"switchInfo" : {
"_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"relay" : 2,
"name" : "Kipas Angin",
"voltage" : 100,
"duration" : null,
"status" : true,
"triggered_by" : ObjectId("5e5fd642fce106005319e884"),
"created_at" : ISODate("2020-04-01T15:45:48.099Z"),
"updated_at" : ISODate("2020-04-01T15:45:48.099Z")
},
"powerUsageDocs" : [
{
"current" : 17.5,
"time_minutes" : 125
},
{
"current" : 17.5,
"time_minutes" : 123
},
{
"current" : 17.5,
"time_minutes" : 126
},
{
"current" : 17.5,
"time_minutes" : 124
}
]
}
{
"_id" : ObjectId("5e8453c095c85ca0c33a9461"),
"sum_current" : 77.38,
"switchInfo" : {
"_id" : ObjectId("5e8453c095c85ca0c33a9461"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"relay" : 1,
"name" : "Lampu Tengah",
"voltage" : 80,
"duration" : null,
"status" : true,
"triggered_by" : ObjectId("5e5fd642fce106005319e884"),
"created_at" : ISODate("2020-04-01T15:41:36.588Z"),
"updated_at" : ISODate("2020-04-01T22:59:39.261Z")
},
"powerUsageDocs" : [
{
"current" : 19.345,
"time_minutes" : 124
},
{
"current" : 19.345,
"time_minutes" : 126
},
{
"current" : 19.345,
"time_minutes" : 123
},
{
"current" : 19.345,
"time_minutes" : 125
}
]
}
Update
If you just need info about your switch,
also you need to get the watt which is = total current * voltage of each switch,
we can do that in the $project, we can add the $multiply operator to the $project pipeline, which multiplies the voltage of the switch by the total current we just calculated in the $group pipeline
db.powerUsageMonth.aggregate(
[
{
$match: {}
},
{
$lookup: {
from: 'switches',
localField: 'switch_id',
foreignField: '_id',
as: 'switch'
}
},
{
$unwind: '$switch'
},
{
$group: {
_id: '$switch._id',
switch_id: { $first: '$switch._id' },
device_id: { $first: '$switch.device_id' },
voltage: { $first: '$switch.voltage' },
sum_current: {
$sum: '$current'
}
}
},
{
$project: {
_id: 1,
switch_id: 1,
device_id: 1,
voltage: 1,
sum_current: 1,
watt: { $multiply: [ "$voltage", "$sum_current" ] }
}
}
]
)
this will result an array of the form
{
"_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
"switch_id" : ObjectId("5e8454bc95c85ca0c33a9463"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"voltage" : 100,
"sum_current" : 70,
"watt" : 7000
}
{
"_id" : ObjectId("5e8453c095c85ca0c33a9461"),
"switch_id" : ObjectId("5e8453c095c85ca0c33a9461"),
"device_id" : ObjectId("5e7d83efd62c242a11e3ca5e"),
"voltage" : 80,
"sum_current" : 77.38,
"watt" : 6190.4
}

Related

Find and sort array of array in nested documents

My collection schema is like this:
{
"_id" : ObjectId("5f0c64e4dd0a36b93c7deafa"),
"name" : "Asd",
"email" : "asd#asd.com",
"password" : "$2b$12$66OTK8mSWELMF5YiF9HMUuHEeOVLI61aINjWs1Cmn1699lLJfz/7y",
"auto_ml" : true,
"notification" : true,
"photo" : null,
"tariff_id" : NumberInt(1),
"city" : null,
"sub_district" : null,
"village" : null,
"latitude" : null,
"longitude" : null,
"created_at" : ISODate("2020-07-13T20:43:00.871+0000"),
"updated_at" : ISODate("2020-07-13T23:08:26.149+0000"),
"family_members" : [
],
"rooms" : [
{
"_id" : ObjectId("5f0c98826f0321f6986755da"),
"name" : "Ruang Makan",
"created_at" : ISODate("2020-07-14T00:23:14.839+0000"),
"updated_at" : ISODate("2020-07-14T00:23:14.840+0000"),
"devices" : [
]
},
{
"_id" : ObjectId("5f0c98876f0321f6986755dd"),
"name" : "Ruang Tamu",
"created_at" : ISODate("2020-07-14T00:23:19.693+0000"),
"updated_at" : ISODate("2020-07-14T19:00:08.281+0000"),
"devices" : [
{
"serial_number" : "ST9L0CY4A2AVY7HFWWUE",
"used_relay" : NumberInt(0),
"created_at" : ISODate("2020-07-14T16:56:22.156+0000"),
"updated_at" : ISODate("2020-07-14T16:56:22.156+0000"),
"sensors" : [
{
"_id" : ObjectId("5f0db478ca203bde99d2438e"),
"name" : "Temperature",
"value" : null,
"created_at" : ISODate("2020-07-14T20:34:48.134+0000"),
"updated_at" : ISODate("2020-07-14T20:34:48.134+0000")
},
{
"_id" : ObjectId("5f0dbe0563ccbcb2a2aecc04"),
"name" : "Motion",
"value" : null,
"created_at" : ISODate("2020-07-14T21:15:33.135+0000"),
"updated_at" : ISODate("2020-07-14T21:15:33.135+0000")
},
{
"_id" : ObjectId("5f0dc0412022e93af338316f"),
"name" : "Humidity",
"value" : null,
"created_at" : ISODate("2020-07-14T21:25:05.126+0000"),
"updated_at" : ISODate("2020-07-14T21:25:05.126+0000")
},
{
"_id" : ObjectId("5f0dc0442022e93af3383170"),
"name" : "Light",
"value" : null,
"created_at" : ISODate("2020-07-14T21:25:08.451+0000"),
"updated_at" : ISODate("2020-07-14T21:25:08.451+0000")
}
],
"switches" : [
]
}
]
}
]
}
The question is, how could i access the array sensors inside device with "serial_number": "ST9L0CY4A2AVY7HFWWUE" and inside room with id ObjectId("5f0c98876f0321f6986755dd"), and the sort the sensors by id? I've tried the projection way and aggregate way but the result is not as i expected. My expected result is only showing the array of sensors like:
"sensors" : [
{
"_id" : ObjectId("5f0db478ca203bde99d2438e"),
"name" : "Temperature",
"value" : null,
"created_at" : ISODate("2020-07-14T20:34:48.134+0000"),
"updated_at" : ISODate("2020-07-14T20:34:48.134+0000")
},
{
"_id" : ObjectId("5f0dbe0563ccbcb2a2aecc04"),
"name" : "Motion",
"value" : null,
"created_at" : ISODate("2020-07-14T21:15:33.135+0000"),
"updated_at" : ISODate("2020-07-14T21:15:33.135+0000")
},
{
"_id" : ObjectId("5f0dc0412022e93af338316f"),
"name" : "Humidity",
"value" : null,
"created_at" : ISODate("2020-07-14T21:25:05.126+0000"),
"updated_at" : ISODate("2020-07-14T21:25:05.126+0000")
},
{
"_id" : ObjectId("5f0dc0442022e93af3383170"),
"name" : "Light",
"value" : null,
"created_at" : ISODate("2020-07-14T21:25:08.451+0000"),
"updated_at" : ISODate("2020-07-14T21:25:08.451+0000")
}
],
Query that i have tried:
db.users.aggregate([
{
$match: { "_id": ObjectId("5f0c64e4dd0a36b93c7deafa") }
},
{ $unwind: "$rooms" },
{
$match: {
"rooms._id": ObjectId("5f0c98876f0321f6986755dd")
}
},
{ $unwind: "$rooms.devices" },
{
$match: {
"rooms.devices.serial_number": "ST9L0CY4A2AVY7HFWWUE"
}
},
{
$project: { "rooms.devices.sensors": 1 }
},
{
$group: {
_id: "$_id",
sensors: { $first: "$rooms.devices.sensors" }
}
},
{
$sort: { "rooms.devices.sensors._id": -1}
},
])
But the sensors doesn't seem to be sorted.
Thanks in advance for your help~

$map upto three nested array mongodb aggregation

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

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", }
]
}
]
}

Mongodb If then else, unwinding

I have documnet structure like below.
{
"_id" : ObjectId("5852c49ba35fe"),
"date" : "20100101",
"p9" : "PWR_FSA",
"p10" : "00278",
"p11" : "002",
"gs" : [
{
"tis" : [
{
"rr" : "00",
"ul" : [
{
"amnt" : 1.0,
"su" : "N"
}
]
}
],
"type" : "PQR"
}
],
"trig_id" : "255"
}
{
"_id" : ObjectId("59fdc49ba35fe"),
"date" : "20100101",
"p9" : "PWR_FSA",
"p10" : "00278",
"p11" : "002",
"gs" : [
{
"mis" : [
{
"rr" : "00",
"tl" : [
{
"amnt" : -1.5,
"su" : "N"
}
]
}
],
"type" : "ABC"
}
],
"trig_id" : "255"
}
Now i want to aggregare the amount on the basis of p9 so i have written below query.
I am gettiing an error at then : {{$unwind : "$gs.tis"},{$unwind : "$gs.tis.ul"}},
Where i am going wrong? Also Can i do unwinding in Then clause ?
db.TB.aggregate({$match :{$and :[{"trig_id" : "255"}]}},
{ $unwind : "$gs" },
{$project: {_id :1,
"amnt" :{
$concat : [ {
$cond : { if : {"gs.type" : {$eq : "PQR"}} ,
then : {{$unwind : "$gs.tis"},{$unwind : "$gs.tis.ul"}},
$cond : { if : {$match : {"gs.tis.ul.su": "N"}} , then : {$gs.tis.ul.amnt} , else: {""}}
else : "" }
}]}},
"total" : { $sum : 1 }
}},
{$group :{"_id": "$p9",
"amnt": {"$sum": "$amnt"}
}
})

How to optimise MongoDB search with indexing?

These documents are in my MongoDB collection:
{
"_id" : ObjectId("57f5e1b5c7739d9805edfe85"),
"date" : ISODate("2016-10-01T00:00:00.000Z"),
"query" : "test1",
"page" : "page1/runway/ready-to-wear/ss17/2016/10/christian-dior/",
"clicks" : 17.0,
"impressions" : 161.0,
"ctr" : 0.10559006211180125,
"position" : 8.503105590062113
}
{
"_id" : ObjectId("57f5e1b5c7739d9805edfe86"),
"date" : ISODate("2016-10-01T00:00:00.000Z"),
"query" : "test1",
"page" : "page2/runway/ready-to-wear/ss17/2016/10/christian-dior/",
"clicks" : 17.0,
"impressions" : 161.0,
"ctr" : 0.10559006211180125,
"position" : 8.503105590062113
}
{
"_id" : ObjectId("57f5e1b5c7739d9805edfe87"),
"date" : ISODate("2016-10-01T00:00:00.000Z"),
"query" : "test2",
"page" : "page3/runway/ready-to-wear/ss17/2016/10/christian-dior/",
"clicks" : 17.0,
"impressions" : 161.0,
"ctr" : 0.10559006211180125,
"position" : 8.503105590062113
}
I need to filter and get some documents like these:
{
"_id" : ObjectId("57f5e1b5c7739d9805edfe85"),
"date" : ISODate("2016-10-01T00:00:00.000Z"),
"query" : "test1",
"page" : "page1/runway/ready-to-wear/ss17/2016/10/christian-dior/",
"clicks" : 17.0,
"impressions" : 161.0,
"ctr" : 0.10559006211180125,
"position" : 8.503105590062113
}
{
"_id" : ObjectId("57f5e1b5c7739d9805edfe86"),
"date" : ISODate("2016-10-01T00:00:00.000Z"),
"query" : "test1",
"page" : "page2/runway/ready-to-wear/ss17/2016/10/christian-dior/",
"clicks" : 17.0,
"impressions" : 161.0,
"ctr" : 0.10559006211180125,
"position" : 8.503105590062113
}
I created an index using query field and ran db.query using aggregate() method like this:
{
"aggregate" : "Mycollection Name" ,
"pipeline" : [
{ "$match" : { "$text" : { "$search" : "\"test1\""}}},
{ "$match" : { "date" : { "$gte" : { "$date" : "2016-10- 01T00:00:00.000Z"} ,"$lte" : { "$date" : "2016-10-01T00:00:00.000Z"}}}},
{ "$group" : { "_id" : "$page" , "clicks" : { "$sum" : "$clicks"} , "impressions" : { "$sum" : "$impressions"} , "ctr" : { "$avg" : "$ctr"} , "position" : { "$avg" : "$position"}}} ,
{ "$sort" : { "clicks" : -1}}
]
}
This query is working but it is not return exactly search.
How can I optimize this query?