Search code examples
node.jsmongodbperformancemongoosenodes

Remove document where populated data is empty after match


I'm trying to add filter on populated data.

   "populate": [
            {
                "path": "attachments",
                "select": "_id type",
                "match": {
                    "type": {
                        "$in": [
                            2
                        ]
                    }
                }
            }
        ]

Data without filter

[
  {
   _id : "6e43454gvbnbvb7888",
   name: "T1",
   attachments :{
         _id : "6errtfhg6757876898",
         type : 2
   }
  },
  {
   _id : "6e43454gvbnbvb7888",
   name: "T1",
   attachments :{
         _id : "6errtfhg6757876898",
         type : 1
   }
  }
]

The current result is as follows.Here attachments data is filtered as specified but the document is still present.

[
  {
   _id : "6e43454gvbnbvb7888",
   name: "T1",
   attachments :[{
         _id : "6errtfhg6757876898",
         type : 2
   }]
  },
  {
   _id : "6e43454gvbnbvb7888",
   name: "T1",
   attachments :[]
  }
]

The expected Result is as follows.As the attachments data is empty it should not come in result.

[
  {
   _id : "6e43454gvbnbvb7888",
   name: "T1",
   attachments :{
         _id : "6errtfhg6757876898",
         type : 2
   }
  }
]

I need to remove documents where attachments are empty. I'm executing data as follows

return new Promise((resolve, reject) => {
      model.paginate(query, options, (err, data) => {
          if (err) reject(err);
          else resolve(data);
      });
});

Solution

  • Check the below query, I just implemented a filter in find(), and as per your requirement i think this will work no need to do any thing extra

     Model.find({ "attachments.type": 2 })
          .populate({
            path: "attachments",
            select: "_id type",
            match: { type: { $in: [2] } }
          })
          .exec((err, users) => {
            if (err) {
              // handle error
            }
            // do something with the populated data
          });
    

    another method is you can use filter()

    const userData = [
      {
       _id : "6e43454gvbnbvb7888",
       name: "T1",
       attachments :[{
             _id : "6errtfhg6757876898",
             type : 2
       }]
      },
      {
       _id : "6e43454gvbnbvb7888",
       name: "T1",
       attachments :[]
      }
    ];
    

    above is the data you have given, I just checked length of the attachment if its equal to 0 then filter it

    const filteredData = userData.filter(user => user.attachments.length === 0);
    
    console.log(filteredData);
    

    If any issue comment me down