skip to Main Content

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"]
        }
    ]
}

2

Answers


  1. 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

    Login or Signup to reply.
  2. db.getCollection('topics').aggregate([
    {"$unwind":"$topics"},
    {"$addFields":{
        "rest":{"$or":[{"$in":["12z3","$topics.owner"]},{"$in":["456","$topics.owner"]}]}
        }},
        {"$match":{
            "rest":true
            }},
            {"$group":{
                "_id":"$_id",
                "topics":{"$push":"$topics"}
                }}
    ])
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search