Home > Back-end >  How to use projection for nested value in mongod
How to use projection for nested value in mongod

Time:11-03

How to use projection to view only the below part from all docs of the collection?

Conditions: I need to fetch only for "type": "DEBIT" and below 2 lines, NOT all other keys in the same type. I dont want to view other types like Account, Deposit.

{
     "key": "Call",
     "enabled": true,
 }

Sample Docs which i have in the below structure.

{
    "_id": "1",
    "menu": [
        {
            "type": "ACCOUNT",
            "scope": "ACCOUNT",
            "items": [
                {
                    "key": "Call",
                    "enabled": true,
                },
                {
                    "key": "Work",
                    "enabled": true,
                }
            ]
        },
        {
            "type": "DEPOSIT",
            "scope": "DEPOSIT",
            "items": [
               {
                    "key": "Call",
                    "enabled": true,
                },
                {
                    "key": "Work",
                    "enabled": true,
                }
            ]
        },
        {
            "type": "DEBIT",
            "scope": "DEBIT",
            "items": [
               {
                    "key": "Call",
                    "enabled": true,
                },
                {
                    "key": "Work",
                    "enabled": true,
                }
            ]
        },
    ]
}

CodePudding user response:

first, you need to $unwind the menu then $match type debit and filter array items and then group to create the final result

db.collection.aggregate([
  {
    "$unwind": "$menu"
  },
  {
    $match: {
      "menu.type": "DEBIT"
    }
  },
  {
    "$project": {
      _id: 1,
      "menu.items": {
        "$filter": {
          "input": "$menu.items",
          "as": "s",
          "cond": {
            $and: [
              {
                $eq: [
                  "$$s.enabled",
                  true
                ]
              },
              {
                $eq: [
                  "$$s.key",
                  "Call"
                ]
              }
            ]
          }
        }
      }
    }
  },
  {
    "$group": {
      "_id": "$_id",
      "menu": {
        "$push": "$menu"
      }
    }
  }
])

https://mongoplayground.net/p/kRChgF9rLsI

CodePudding user response:

use $filter

db.collection.aggregate([
  {
    "$match": {
      "menu.type": "DEBIT"
    }
  },
  {
    "$set": {
      "menu": {
        "$filter": {
          "input": "$menu",
          "as": "m",
          "cond": {
            $eq: [
              "$$m.type",
              "DEBIT"
            ]
          }
        }
      }
    }
  }
])

mongoplayground

  • Related