Reputation: 113
I am having issues with referencing a nested array item in a $cond
statement.
db.getCollection('bookings').aggregate([
{
$lookup: {
from: "listings",
localField: "listingId",
foreignField: "_id",
as: "listing"
}
},
{
$match: {
$and: [
{
locationId: ObjectId("5c0f0c882fcf07fb08890c27")
},
{
$or: [
{
$and: [
{
state: "booked"
},
{
startDate: {
$lte: new Date()
}
},
{
startDate: {
$gte: ISODate("2019-12-18T07:00:00.000Z")
}
}
]
},
{
$and: [
{
listing: {
$elemMatch: {
inspectionStatus: "none"
}
}
},
{
endDate: {
$lte: new Date()
}
},
{
endDate: {
$gte: ISODate("2019-12-18T07:00:00.000Z")
}
},
{
state: {
$in: [
"active",
"returned"
]
}
}
]
},
{
$and: [
{
state: {
$ne: "cancelled"
}
},
{
$or: [
{
$and: [
{
startDate: {
$gte: ISODate("2019-12-20T07:00:00.993Z")
}
},
{
startDate: {
$lte: ISODate("2019-12-21T06:59:59.999Z")
}
}
]
},
{
$and: [
{
endDate: {
$gte: ISODate("2019-12-20T07:00:00.993Z")
}
},
{
endDate: {
$lte: ISODate("2019-12-21T06:59:59.999Z")
}
}
]
}
]
}
]
}
]
}
]
}
},
{
$addFields: {
isLate: {
$cond: [
{
$or: [
{
$and: [
{
$eq: [
"$listing.0.inspectionStatus",
"none"
]
},
{
$lte: [
"$endDate",
new Date()
]
},
{
$gte: [
"$endDate",
ISODate("2019-12-18T07:00:00.000Z")
]
},
{
$in: [
"$state",
[
"active",
"returned"
]
]
},
]
},
{
$and: [
{
$eq: [
"$state",
"booked"
]
},
{
$lte: [
"$startDate",
new Date()
]
},
{
$gte: [
"$startDate",
ISODate("2019-12-18T07:00:00.000Z")
]
}
]
}
]
},
true,
false
]
}
}
}
])
In the above, the following lines in the $cond
statement does not work at all:
$eq: [
"$listing.0.inspectionStatus",
"none"
]
My question is - how do I make the above work? Note that there is always only one array item in the listing
field after the lookup (never more than one array item in there). I've tried different variations like $listing.$0.$inspectionStatus
- but nothing seems to work. I could go down the trajectory of researching group
and filter
- but I feel like this is overkill when I simply always want to access the first and only item in the listing
array.
Upvotes: 0
Views: 1431
Reputation: 1080
Please use $in keyword instead of $eq keyword in $cond keyword
db.demo1.aggregate([
{
$lookup: {
from: "demo2",
localField: "listingId",
foreignField: "_id",
as: "listing"
}
},
{
$match: {
$and: [
{
locationId: ObjectId("5c0f0c882fcf07fb08890c27")
},
{
$or: [
{
$and: [
{
state: "booked"
},
{
startDate: {
$lte: new Date()
}
},
{
startDate: {
$gte: ISODate("2019-12-18T07:00:00.000Z")
}
}
]
},
{
$and: [
{
listing: {
$elemMatch: {
inspectionStatus: "none"
}
}
},
{
endDate: {
$lte: new Date()
}
},
{
endDate: {
$gte: ISODate("2019-12-18T07:00:00.000Z")
}
},
{
state: {
$in: [
"active",
"returned"
]
}
}
]
},
{
$and: [
{
state: {
$ne: "cancelled"
}
},
{
$or: [
{
$and: [
{
startDate: {
$gte: ISODate("2019-12-20T07:00:00.993Z")
}
},
{
startDate: {
$lte: ISODate("2019-12-21T06:59:59.999Z")
}
}
]
},
{
$and: [
{
endDate: {
$gte: ISODate("2019-12-20T07:00:00.993Z")
}
},
{
endDate: {
$lte: ISODate("2019-12-21T06:59:59.999Z")
}
}
]
}
]
}
]
}
]
}
]
}
},
{
$addFields: {
isLate: {
$cond: [
{
$or: [
{
$and: [
{
$in: [
"none",
"$listing.inspectionStatus",
]
},
{
$lte: [
"$endDate",
new Date()
]
},
{
$gte: [
"$endDate",
ISODate("2019-12-18T07:00:00.000Z")
]
},
{
$in: [
"$state",
[
"active",
"returned"
]
]
},
]
},
{
$and: [
{
$eq: [
"$state",
"booked"
]
},
{
$lte: [
"$startDate",
new Date()
]
},
{
$gte: [
"$startDate",
ISODate("2019-12-18T07:00:00.000Z")
]
}
]
}
]
},
true,
false
]
}
}
}
])
Upvotes: 1