1

I want to pull a nested document in the userSignedUpEvent field that matches the given eventId. The part that is giving me a hard time is that I want to run this for all users in the users collection. Because many users will have signed up for this event and if it gets removed I need to remove it from every user's userSignedUpEvents field.

Example User Doc:

{
  "_id": {
    "$oid": "636c1778f1d09191074f9690"
  },
  "name": "Wayne Wrestler",
  "email": "wakywayne80@gmail.com",
  "image": "https://lh3.googleusercontent.com/a/ALm5wu32gXjDIRxncjjQA9I4Yl-
  "userSignedUpEvents":[
        0:{
              eventId: 636c1778f1d09191074f9690
              eventName: "onmygod"
}
]
}

Attempts:

db.users.updateMany({"userSignedUpEvents.eventId": ObjectId('636c2c6dcb82e7ae6aac0960')}, 

{$pull: {"userSignedUpEvents.$[el]": true}}, {arrayFilters:[{"el.eventId":ObjectId('636c2c6dcb82e7ae6aac0960')}]})
db.users.updateMany({"userSignedUpEvents": {$elemMatch: {eventId: ObjectId('636c2c6dcb82e7ae6aac0960')}}}, 

{$pull: {"userSignedUpEvents.$.eventId": ObjectId('636c2c6dcb82e7ae6aac0960')}})
Wayne
  • 660
  • 6
  • 16
  • 1
    The objectId you provided in the filter and pull doesn't match with the `userSignedUpEvents.eventId` in your provided document. [Demo](https://mongoplayground.net/p/guK1DdiMnTL) – Yong Shun Nov 23 '22 at 14:34

1 Answers1

1

One option is:

db.users.updateMany(
  {userSignedUpEvents: {$elemMatch: {eventId: eventId}}},
  {$pull: {userSignedUpEvents: {eventId: eventId}}},
)

See how it works on the playground example

EDIT: Another option is:

db.collection.update(
  {userSignedUpEvents: {$elemMatch: {eventId: eventId}}},
  [
    {$set: {
      userSignedUpEvents: {
        $filter: {
          input: "$userSignedUpEvents",
          cond: {$ne: ["$$this.eventId", eventId]}
        }
      }
    }}
  ],
  {multi: true}
)

See how it works on the playground example

nimrod serok
  • 14,151
  • 2
  • 11
  • 33
  • with node driver: ```javascript const query = await db.collection('users').updateMany( { userSignedUpEvents: { $elemMatch: { eventId: new ObjectId(eventId) } } }, { $pull: { userSignedUpEvents: { eventId: new ObjectId(eventId) } } }, ) ``` is throwing an error on the $pull : > Type '{ userSignedUpEvents: { eventId: ObjectId; }; }' is not assignable to type 'PullOperator'. – Wayne Nov 23 '22 at 15:21
  • I added another option to the answer – nimrod serok Nov 23 '22 at 16:30
  • Hey I am looking over your answer and I think my problem is that I have a hard time understanding what field the update part of the query is modifying by default. I had this problem another time, but the solution seemed totally different whick led me in the wrong direction. If it isn't a complete bother if you could help me better understand how to know what is being modified I would really appreciate it. **Here is the link** to the other question I mentioned for reference: – Wayne Nov 24 '22 at 03:37
  • https://stackoverflow.com/questions/74396113/mongodb-update-an-array-of-documents-with-two-levels-deep-which-matches-condit/74396451?noredirect=1#comment131336808_74396451 – Wayne Nov 24 '22 at 03:37
  • 1
    If you look at solution 2 on the link you attached here, the solution will update the field: `"weights.$[el].spotsAvailable.$[el2]"` using the `arrayFilters`: `[{"el.weight": 0 }, {"el2.userId": "empty" }]`. This means `weights` is an array, that the query will update **items** in it where `weight` is `0`, and on this items there is a nested array called `spotsAvailable` , and the query will update **nested items** where `userId` is `empty`. All of this is done to choose the items to update. On these items it will set whatever is on the `$set` part of the query. – nimrod serok Nov 24 '22 at 08:33