Home > database >  Retrieve only queried element from a single document in mongoDB
Retrieve only queried element from a single document in mongoDB

Time:12-24

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

CodePudding user response:

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

CodePudding user response:

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"}
            }}
])
  • Related