'mongodb lookup on nested documents
I have documents like these :
Merchant:
{
"_id" : ObjectId("628728cf9f5c99d8dedbe759"),
"name" : "agriTales",
"information" : "Farmers social",
"categories" : [
ObjectId("6287220c52497922d6f4a121")
],
"website" : "www.agritales.com",
"active" : true
}
LuckyDraw:
{
"_id" : ObjectId("62873487e0e5eedc24748a55"),
"business" : ObjectId("628728cf9f5c99d8dedbe759"),
"title" : "May Lucky draw 2022",
"date_start" : ISODate("2022-04-26T00:00:00Z"),
"max_participants" : 5,
"active" : true,
"date_of_draw" : ISODate("2022-07-30T00:00:00Z"),
"prizes_winners" : [
{
"prize_name" : "1st Prize",
"coupon_voucher" : ObjectId("62872f809f5c99d8dedbe764")
},
{
"prize_name" : "2nd Prize",
"coupon_voucher" : ObjectId("62872f8d9f5c99d8dedbe765")
}
],
"result_declared" : true
}
CouponVoucher:
{
"_id" : ObjectId("62872f809f5c99d8dedbe764"),
"business" : ObjectId("628728cf9f5c99d8dedbe759"),
"type" : "voucher",
"title" : "8farmers Coupons 2001",
"minimum_order_value" : 0,
"voucher_face_value" : 2001,
"active" : true,
"status" : "NEW",
"date_expiry" : ISODate("2022-12-31T00:00:00Z"),
}
{
"_id" : ObjectId("62872f8d9f5c99d8dedbe765")
"type" : "voucher",
"title" : "8farmers Coupons 1501",
"minimum_order_value" : 0,
"voucher_face_value" : 1501,
"active" : true,
"status" : "NEW",
"date_expiry" : ISODate("2022-12-31T00:00:00Z")
}
class LuckyDraws(Document):
business = ReferenceField(Merchants, required=True)
branches = ListField(ReferenceField(MerchantBranches))
title = StringField(required=True)
date_start = DateTimeField(required=True) # the date when luck draw will be available to participate
max_participants = IntField() # max number of participants
active = BooleanField(default=True)
date_of_draw = DateTimeField(required=True) # the date when luck draw will be declared
filter_conditions = EmbeddedDocumentField(LuckyDrawFilterConditions)
participants = ListField(ReferenceField(Users), required=False)
prizes_winners = ListField(EmbeddedDocumentField(LuckyDrawPrizesWinners), required=True)
class LuckyDrawPrizesWinners(EmbeddedDocument):
prize_name = StringField(required=True)
coupon_voucher = ReferenceField(CouponVoucher, required=True)
winner = ReferenceField(Users, blank=True, null=True, default=None)
class CouponVoucher(Document):
business = ReferenceField(Merchants, required=True)
title = StringField(required=True, unique=True)
discount_type = StringField(required=False) # amount / percentage
coupon_discount = DecimalField(required=False)
max_count = IntField(required=False)
minimum_order_value = DecimalField(required=False)
I am looking for a result where I get details of the lucky draw and its corresponding prizes and couponvoucher details used below pipeline
LuckyDraws.objects.aggregate([{
'$lookup':
{
"from": "merchants",
"localField": "business",
"foreignField": "_id",
"as": "business",
"pipeline": [
{"$project": {"name": 1, "information": 1, "categories": 1}}
]
}
},
{"$project":
{
"business": 1, "title": 1, "date_start": 1, "active": 1, "date_of_draw": 1,
"prizes_winners.prize_name": 1, "prizes_winners.coupon_voucher": 1,
"result_declared": 1, "vouchers": 1
}
},
{
'$lookup':
{
"from": "coupon_voucher",
"localField": "prizes_winners.coupon_voucher",
"foreignField": "_id",
"pipeline": [
{"$project": {"title": 1, "minimum_order_value": 1, "voucher_face_value": 1,
"active": 1, "date_expiry": 1}}
],
"as": "prizes_winners"
}
},
{
"$sort": {
"date_of_draw": -1
}
}
]
and getting below results but its missing prize_name under prizes_winners, please let me know what I am missing and how t oadd prize_name under prizes_winners. the result i am getting :
[
{
"_id": {
"$oid": "62873487e0e5eedc24748a55"
},
"business": [
{
"_id": {
"$oid": "628728cf9f5c99d8dedbe759"
},
"name": "agriTales",
"information": "Farmers social",
"categories": [
{
"$oid": "6287220c52497922d6f4a121"
}
]
}
],
"title": "May Lucky draw 2022",
"date_start": {
"$date": "2022-04-26T00:00:00Z"
},
"active": true,
"date_of_draw": {
"$date": "2022-07-30T00:00:00Z"
},
"prizes_winners": [
{
"_id": {
"$oid": "62872f809f5c99d8dedbe764"
},
"title": "8farmers Coupons 2001",
"minimum_order_value": 0.0,
"voucher_face_value": 2001.0,
"active": true,
"date_expiry": {
"$date": "2022-12-31T00:00:00Z"
}
},
{
"_id": {
"$oid": "62872f8d9f5c99d8dedbe765"
},
"title": "8farmers Coupons 1501",
"minimum_order_value": 0.0,
"voucher_face_value": 1501.0,
"active": true,
"date_expiry": {
"$date": "2022-12-31T00:00:00Z"
}
}
],
"result_declared": true
}
]
I want the result should be :
[
{
"_id": {
"$oid": "62873487e0e5eedc24748a55"
},
"business": [
{
"_id": {
"$oid": "628728cf9f5c99d8dedbe759"
},
"name": "agriTales",
"information": "Farmers social",
"categories": [
{
"$oid": "6287220c52497922d6f4a121"
}
]
}
],
"title": "May Lucky draw 2022",
"date_start": {
"$date": "2022-04-26T00:00:00Z"
},
"active": true,
"date_of_draw": {
"$date": "2022-07-30T00:00:00Z"
},
"prizes_winners": [
{
**"prize_name":"1st prize",**
"_id": {
"$oid": "62872f809f5c99d8dedbe764"
},
"title": "8farmers Coupons 2001",
"minimum_order_value": 0.0,
"voucher_face_value": 2001.0,
"active": true,
"date_expiry": {
"$date": "2022-12-31T00:00:00Z"
}
},
{
**"prize_name":"2nd prize",**
"_id": {
"$oid": "62872f8d9f5c99d8dedbe765"
},
"title": "8farmers Coupons 1501",
"minimum_order_value": 0.0,
"voucher_face_value": 1501.0,
"active": true,
"date_expiry": {
"$date": "2022-12-31T00:00:00Z"
}
}
],
"result_declared": true
}
]
Solution 1:[1]
There are lots of ways, and possibly more efficient ways, to do this. Here's one way.
db.LuckyDraw.aggregate([
{
"$lookup": {
"from": "Merchant",
"localField": "business",
"foreignField": "_id",
"pipeline": [ { "$unset": [ "active", "website" ] } ],
"as": "business"
}
},
{
"$lookup": {
"from": "CouponVoucher",
"localField": "prizes_winners.coupon_voucher",
"foreignField": "_id",
"let": { "prizes_winners": "$prizes_winners" },
"pipeline": [
{
"$set": {
"prize_name": {
"$reduce": {
"input": "$$prizes_winners",
"initialValue": "",
"in": {
"$cond": [
{ "$eq": [ "$$this.coupon_voucher", "$_id" ] },
"$$this.prize_name",
"$$value"
]
}
}
}
}
}
],
"as": "prizes_winners"
}
}
])
Try it on mongoplayground.net.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | rickhg12hs |
