Search code examples
mongodbaggregation

Retrieve only queried element from a single document in mongoDB


I have a collection like below :

`{
    "topics" : [ 
        {
            "id" : "2",
            "name" : "Test1",
            "owner" : [ 
                "123"
            ]
        }, 
        {
            "id" : "3",
            "name" : "Test2",
            "owner" : [ 
                "123", 
                "456"
            ]
        }
]
}`

As, this data is in single document, and I want only matching elements based on their owner, I am using below query ( using filter in aggregation ), but I am getting 0 matching elements. Query :

Thanks in advance...!!

db.getCollection('topics').aggregate([
  {"$match":{"topics.owner":{"$in":["123","456"]}}},
  {"$project":{
    "topics":{
      "$filter":{
        "input":"$topics",
        "as":"topic",
        "cond": {"$in": ["$$topic.owner",["123","456"]]}
      }},
    "_id":0
  }}
])

This query should produce below output :

{
    "topics" : [ 
        {
            "id" : "1",
            "name" : "Test1",
            "owner" : ["123"]
        }, 
        {
            "id" : "2",
            "name" : "Test2",
            "owner" : ["123","456"]
        }
    ]
}

Solution

  • As the topic.owner is an array, you can't use $in directly as this compares whether the array is within in an array.

    Instead, you should do as below:

    1. $filter - Filter the document in the topics array.

      1.1. $gt - Compare the result from 1.1.1 is greater than 0.

      1.1.1. $size - Get the size of the array from the result 1.1.1.1.

      1.1.1.1. $setIntersection - Intersect the topic.owner array with the input array.

    {
      "$project": {
        "topics": {
          "$filter": {
            "input": "$topics",
            "as": "topic",
            "cond": {
              $gt: [
                {
                  $size: {
                    $setIntersection: [
                      "$$topic.owner",
                      [
                        "123",
                        "456"
                      ]
                    ]
                  }
                },
                0
              ]
            }
          }
        },
        "_id": 0
      }
    }
    

    Demo @ Mongo Playground