I have two collection bookings and invoices and I have prepared aggregate and lookup query for below condition
bookings collection condition
condition 1: Status not equal to delivered
condition 2: products should not be null or empty
condition 3: ProductID should exist in the products array and should not be null
condition 4: IsDeliveryFailed should not be "Yes"
bookings Collection Data
{
"_id" : ObjectId("609a382b589346973c84c6fe"),
"Name" : "abc",
"UserId":1
"Status" : "Pending",
"Invoices" : [
ObjectId("709a382b5c6fe89346973c84")
],
"BookingData" : {
"Date" : ISODate("2021-04-30T04:00:00.000Z"),
"info" : [],
"BookingDataMethod" : "avf",
"Message" : null,
"products" : [
{
"_id" : ObjectId("60a4e92775e5de3570578820"),
"ProductName" : "Test1",
"ProductID" : ObjectId("60a4e92475e5de357057880a"),
"IsDeliveryFailed" : "Yes"
},
{
"_id" : ObjectId("60a4e92775e5de357057881f"),
"ProductName" : "Test2",
"ProductID" : ObjectId("60a4e92475e5de357057880d")
}
],
}
}
invoices collection condition
condition 1: InvoiceData should not be null or empty
condition 2: InvoiceID should exist in the InvoiceData array and should not be null
condition 3: IsPaymentFailed should not be "Yes"
invoices Collection Data
{
"_id" : ObjectId("709a382b5c6fe89346973c84"),
"invoiceNumber":1
"InvoiceData" :[
{
"_id" : ObjectId("60a4e92775e5de3570578820"),
"ProductName" : "Test1",
"InvoiceID":1,
"IsPaymentFailed" : "Yes"
},
{
"_id" : ObjectId("60a4e92775e5de357057881f"),
"InvoiceID":2,
"ProductName" : "Test2",
}
]
}
Query
db.bookings.aggregate([
{
"$match": {
"Status": {
$ne: "Delivered"
}
}
},
{
"$lookup": {
"from": "invoices",
"localField": "Invoices",
"foreignField": "_id",
"as": "invoiceInfo"
}
},
{
"$match": {
"$or": [
{
"BookingData.products": {
"$exists": true
}
},
{
"invoiceInfo.InvoiceData": {
"$exists": true
}
}
]
}
},
{
$set: {
"BookingData.products": {
"$filter": {
"input": "$BookingData.products",
"cond": {
$and: [
{ $ne: [ "$$this.ProductID", undefined ] },
{ $ne: [ "$$this._id", null ] },
{ $ne: [ "$$this.IsDeliveryFailed", "Yes" ] }
]
}
}
}
}
},
{
$set: {
"invoiceInfo.InvoiceData": {
"$filter": {
"input": "$invoiceInfo.InvoiceData",
"cond": {
$and: [
{ $ne: [ "$$this.InvoiceID", undefined ] },
{ $ne: [ "$$this._id", null ] },
{ $ne: [ "$$this.IsPaymentFailed", "Yes" ] }
]
}
}
}
}
},
{
$match: {
$expr: {
$or: [
{
$ne: [
"$BookingData.products",
[],
]
},
{
$ne: [
"$invoiceInfo.InvoiceData",
[],
]
}
]
}
}
}
])
this is not working as expected for example if
The query should return the above document
if ProductID exist and products exist and all products do not have IsDeliveryFailed: "Yes"
if ProductID exist and products exist and anyone products do not have IsDeliveryFailed: "Yes"
if InvoiceID exist and InvoiceData exist and all InvoiceData do not have IsPaymentFailed: "Yes"
if InvoiceID exist and InvoiceData exist and anyone InvoiceData does not has IsPaymentFailed: "Yes"
another set
if ProductID exists and products exist and all products are IsDeliveryFailed: "Yes" flag. but we have to check invoices collection if InvoiceID exist and InvoiceData exist and anyone InvoiceData does not have IsPaymentFailed: "Yes" then we have to return this document
if InvoiceID exist and InvoiceData exist and all InvoiceData are IsPaymentFailed: "Yes".but we have to check bookings collection if ProductID exist and products exist and anyone products does not have IsDeliveryFailed:"Yes" then we have to returndocument