简体   繁体   中英

MongoDb return both matched results and matched results on subdocument

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM