Search code examples
mongodbmongodb-queryaggregation-frameworkjenssegers-mongodb

How do I get all matching sub array Objects in mongoDB


I have following JSON

[
  {
    "_id": "5c87e621257db42508007f3b",
    "uuid": "8b03dba7-db96-40d0-8dd9-6a65efd6719a",
    "user_answers": [
      {
        "profile_section_code": "MY_PROFILE",
        "profile_question_code": "STANDARD_EDUCATION",
        "selected_answer": [
          "2"
        ]
      },
      {
        "profile_section_code": "MY_PROFILE",
        "profile_question_code": "ETHNICITY",
        "selected_answer": [
          "2"
        ]
      },
      {
        "profile_section_code": "FAMILY",
        "profile_question_code": "STANDARD_HHI_US",
        "selected_answer": [
          "11"
        ]
      },
      {
        "profile_section_code": "FAMILY",
        "profile_question_code": "STANDARD_HH_ASSETS",
        "selected_answer": [
          "5"
        ]
      },
      {
        "profile_section_code": "AUTOMOTIVE",
        "profile_question_code": "STANDARD_AUTO_DECISION_MAKER",
        "selected_answer": [
          "1"
        ]
      }
    ],
    "created_at": "2019-03-12T17:02:25.000Z"
  }
]

Complete JSON can be seen here: Link

I want to fetch all user_answers with "profile_section_code": "MY_PROFILE" Expected Result should be like this

{ "_id": "5c87e621257db42508007f3b", "uuid": "8b03dba7-db96-40d0-8dd9-6a65efd6719a", "user_answers": [ { "profile_section_code": "MY_PROFILE", "profile_question_code": "STANDARD_EDUCATION", "selected_answer": [ "2" ] }, { "profile_section_code": "MY_PROFILE", "profile_question_code": "ETHNICITY", "selected_answer": [ "2" ] }],"created_at": "2019-03-12T17:02:25.000Z" }

I tried $elemMatch in Projection but it returns the only 1st Matching array, I need something just like $elemMatch but should return all matching array. here's Fiddle for the same

I also tried using this Answer But it didn't work as it was returning only 1st matching subArray

  • Is there any way to do this using Projection only (I want to avoid Aggregation, as I have to implement this in PHP)
  • If Above is not possible then how can I implement this using aggregate?

Please let me know what I can do to fix this


Solution

  • Use $filter to get your expected result. Also, it looks like aggregation pipeline is the only option to filter the records or it needs to be done at PHP code level.

    [
        {
            '$addFields': {
                'user_answers': {
                    '$filter': {
                        'input': '$user_answers', 
                        'as': 'user_answer', 
                        'cond': {
                            '$eq': [
                                '$$user_answer.profile_section_code', 'MY_PROFILE'
                            ]
                        }
                    }
                }
            }
        }
    ]