Hello i am trying to get my database to return both matched and empty results on a sub-document.
I am joining two tables using aggregate and lookup, below is the code
db.collection.aggregate([
{
$addFields: {
cut_off_date: { $toDate: "$shipment_cutoff_date" },
},
},
{
$lookup: {
from: "updates",
localField: "_id",
foreignField: "shipment_id",
as: "updates",
},
},
{
$match: {
"updates.description": { $ne: "All updates completed" },
},
},
]);
Challenge is i am trying to get All rows where all updates have been completed as well as all empty updates. If i remove the match parameters i get all the results including where the updates have been completed and i am trying to avoid doing a foreach after getting all my results.
Here is a snippet of the result without the match
{
"_id": "609927e31233700004370cfb",
"title": "Hello World",
"createdAt": "2021-05-10T12:32:35.799Z",
"updatedAt": "2021-05-10T15:58:59.149Z",
"updates": []
},
{
"_id": "60940ad73ced476b2d0b3626",
"createdAt": "2021-05-06T15:27:19.814Z",
"updatedAt": "2021-05-10T12:49:08.167Z",
"updates": [
{
"_id": "60952c0ed31c6283f302eb23",
"post_id": "60940ad73ced476b2d0b3626",
"description": "This is an update description",
"createdAt": "2021-05-07T12:01:18.815Z",
"updatedAt": "2021-05-07T12:01:18.815Z",
},
]
},
{
"_id": "60940ad73ced476b2d0b3626",
"createdAt": "2021-05-06T15:27:19.814Z",
"updatedAt": "2021-05-10T12:49:08.167Z",
"updates": [
{
"_id": "60952c0ed31c6283f302eb23",
"post_id": "60940ad73ced476b2d0b3626",
"description": "All updates completed",
"createdAt": "2021-05-07T12:01:18.815Z",
"updatedAt": "2021-05-07T12:01:18.815Z",
},
]
}
Here is a snippet of what i will like to achieve after the match
{
"_id": "609927e31233700004370cfb",
"title": "Hello World",
"createdAt": "2021-05-10T12:32:35.799Z",
"updatedAt": "2021-05-10T15:58:59.149Z",
"updates": []
},
{
"_id": "60940ad73ced476b2d0b3626",
"createdAt": "2021-05-06T15:27:19.814Z",
"updatedAt": "2021-05-10T12:49:08.167Z",
"updates": [
{
"_id": "60952c0ed31c6283f302eb23",
"post_id": "60940ad73ced476b2d0b3626",
"description": "This is an update description",
"createdAt": "2021-05-07T12:01:18.815Z",
"updatedAt": "2021-05-07T12:01:18.815Z",
},
]
},
I am trying to get the results without the section where update description is not "All updates completed
Any help here please, MondoDb version is 4+
You can use $filter
$facet
to categorize incoming doucment into two. 1. updates == empty array and 2. update != empty array $redact
use to keep or eliminate the document based on the condition we give $concatArray
to combined to both arrays which were produced after $facet
$unwind
to deconstruct the array $replaceRoot
to make to root He is the script
db.collection.aggregate([
{
"$facet": {
"emptyUpdates": [
{
"$match": {
$expr: { $eq: [ "$updates", [] ] }
}
}
],
"withoutUpdate": [
{
"$match": {
$expr: { $ne: [ "$updates", [] ] }
}
},
{
"$redact": {
"$cond": [
{
"$anyElementTrue": {
"$filter": {
"input": "$updates",
"cond": {
$eq: [ "$$this.description","All updates completed" ]
}
}
}
},
"$$PRUNE",
"$$KEEP",
]
}
}
]
}
},
{
"$project": {
combined: {
"$concatArrays": ["$emptyUpdates", "$withoutUpdate" ]
}
}
},
{ "$unwind": "$combined" },
{
"$replaceRoot": {"newRoot": "$combined" }
}
])
Working Mongo playground
Let me know anything goes wrong
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.