Search code examples
node.jsmongodbmongoose

$pull object from embedded array of objects


I have structure:

{
  items: [{
    //...some object fields
    tags: [
      {  _id: 1,
         name: 'Tag 1'  
      },
      {  _id: 2,
         name: 'Tag 2'  
      },
    ]}, 
  {...}
 , ...
]
}

How do I pull tag that has _id 1 for example? Also I need to do this on multiple documents, so it needs to be .updateMany().

I tried like so but it won't update:

    await Rankings.RankingData.updateMany(
      { 'items.tags': { $elemMatch: { _id: id } } },
      { $pull: { 'items.$[item].tags': { $elemMatch: { _id: id } } } },
      { multi: true, arrayFilters: [{ 'item.tags': { $elemMatch: { _id: id } } }] },
    );

I succeed on fetching the right documents with the query, so its the problem of $pull or arrayFilters...? Note again I need to pull a tag from items array, not the whole item!


Solution

  • In this case, use the positional operator $ to refer to the element in the items array that satisfied the condition in the filter.

    $pull already assumes that all of its criteria must be matched by a the same array element, os $elemMatch is not necessary when filtering the array. It is also not required when there is only 1 criterion in the filter:

     await Rankings.RankingData.updateMany(
          { 'items.tags': { _id: id }  },
          { $pull: { 'items.$.tags': { _id: id }  } },
          { multi: true},
        );
    

    Playground