skip to Main Content

I have a document like below

{
  "name" :{
  "English": "AA",
  "Bengali": "BB",
  "Gujarati": "CC",
  "Hindi": "DD"} 
}

can I filter it based on the keys e.g. need to filter only on ‘English’ and ‘Hindi’ so the output should be

{
  "name" :{
  "English": "AA",
  "Hindi": "DD"} 
}

2

Answers


  1. One way to do this is to first turn the object into an array of key-value pairs [{ "k": "Bengali", "v": "BB" }, { "k": "English", "v": "AA" }...] using $objectToArray

    Then call $filter on the array and take only the ones you need

    Finally, convert that array back to an object using $arrayToObject

    db.collection.aggregate([
      {
        $project: {
          name: {
            $arrayToObject: {
              $filter: {
                input: { $objectToArray: "$name" },
                cond: { $in: [ "$$this.k", [ "English", "Hindi" ] ] }
              }
            }
          }
        }
      }
    ])
    

    playground

    Login or Signup to reply.
  2. The simple option is to check for key existence and project only the necessary keys :

    db.collection.find({
    "$and": [
     {
       "name.Hindi": {
         "$exists": true
       }
      },
      {
       "name.English": {
         "$exists": true
       }
     }
    ]
    },
    {
    name: {
     "English": 1,
     "Hindi": 1
     }
    })
    

    Playground

    But the better option if you are going to use this filter often is to modify the keys to values as follow:

    [
      {
      "_id": ObjectId("5a934e000102030405000000"),
       "name": [
        {key:"Bengali" , value:"BB"},
        {key:"English" , value:"AA"},
        {key:"Gujarati", value:"CC"},
        {key:"Hindi",  value:"DD" }
      ]
     }
    ]
    

    where you can do something faster like:

       db.collection.find({
      "name.key": {
      $in: [
      "English",
      "Hindi"
      ]
      }
     },
     {
     name: {
      $filter: {
      input: "$name",
      as: "item",
      cond: {
        $in: [
          "$$item.key",
          [
            "English",
            "Hindi"
           ]
          ]
         }
       }
      }
     })
    

    Assuming you create in advance an index on the "name.key" field.

    playground

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search