Home > front end >  How to query MongoDB to return Document but not all subdocuments?
How to query MongoDB to return Document but not all subdocuments?

Time:10-28

Let's say I have a document like this:


      {
         _id: ObjectId("1234567890"),
         author: "ABC1",
         text:"this is a Post",
         details: {
            time: "14/05/2015",
            Edit: "none"
         },
         comments: [
             { 
                   comment_text: "Hello",
                    user: "alan",
                      time:"20/05/2014 20:44" 
               }, 
             { 
                    comment_text: "Hi Every One",
                     user: "bob",
                      time:"20/05/2014 20:44"
              },
             { 
                     comment_text: "Good morning , Alan", 
                     user: "Alan",
                     time:"20/05/2014 20:44"
               },
             { 
                        comment_text: "I'm bob",
                        user: "bob", 
                        time:"20/05/2014 20:44"
                },
                  ],
         category: "IT"
       }

I want to build a query that returns this object but with only Bob's comments in the comments array.


      {
         author: "ABC1",
         text:"this is a Post",
         details: {
            time: "14/05/2015",
            Edit: "none"
         },
         comments: [
             { 
                    comment_text: "Hi Every One",
                     user: "bob",
                      time:"20/05/2014 20:44"
              },
             { 
                        comment_text: "I'm bob",
                        user: "bob", 
                        time:"20/05/2014 20:44"
                },
                  ],
         category: "IT"
       }

How can this be done?

  • Using $unwind (and $match) in an aggregation pipeline will get me the correct subdocuments, but not as an array of objects within the original document.
  • Using $elemMatch within a projection (with find() or findOne()) only returns the first matching comment (subdocument).

CodePudding user response:

You can use the $filter operator in the $project stage of an aggregation pipeline:

db.collection.aggregate([
  {
    $project: {
      _id: 0,
      author: 1,
      text: 1,
      details: 1,
      category: 1,
      comments: {
        $filter: {
          input: "$comments",
          as: "comment",
          cond: {
            $eq: [
              "$$comment.user",
              "bob"
            ]
          }
        }
      }
    }
  }
])

Example mongoplayground

  • Related