How can I populate reference, and delete element in array after based on the ID of the reference

So I have a situation where I need to delete elements in an array of reference / ObjectIds, but the delete condition will be based on a field in the reference.

For example, I have the following schemas:

const UserSchema = new mongoose.Schema({
   firstName: String,
   lastName: String,
   homeFeeds:[{type: Schema.Types.ObjectId, requried: true, ref: "Activity"}];
}); // User , is the referenece name

const ActivitySchema = new mongoose.Schema({
   requester: {type: Schema.Types.ObjectId, requried: true, ref: "User"},
   message: String,
   recipient: {type: Schema.Types.ObjectId, requried: true, ref: "User"},
}) // Activity, is the reference name

Now I need to delete some of the homeFeeds for a user, and the ones that should be deleted need to be by certain requester. That’ll require the homeFeeds (array of 'Activity’s) field to be populated first, and then update it with the $pull operator, with a condition that the Activity requester matches a certain user.

I do not want to read the data first and do the filtering in Nodejs/backend code, since the array can be very long.

Ideally I need something like:

await User.find({_id: ID})
          .populate("homeFeeds", "requester")
          .updateMany({
               $pull: {
                  homeFeeds.requester: ID
               }
          });

But it does not work, Id really appreciate if anyone can help me out with this?

Thanks

Originally I was thinking you can do this using aggregation pipeline update syntax (new in 4.2). I’m not familiar with Mongoose so I’m not sure I understand your schema nor do I know if they support this syntax for updates but it allows referencing fields in the document in update expression.

But looking at this a bit closer it seems like it’s fields stored in another document that you would want to base your update on, right?

Can you provide a sample document from User and Activity collections - it’s possible that this can be done using $merge stage in aggregation (along with $lookup) but again, Mongoose would have to support it (otherwise you can do it in the shell if it’s a one-off operation).

Asya

1 Like
const friendId = req.body.friendId;

  const userId = req.params.id;

  User.findByIdAndUpdate(

    userId,

    { $pull: { friends: friendId } },

    { new: true }

  )

If you wanna delete some ObjectId ref its simple like this using $in with updateMany

User.updateMany({},
{ $pull: { homeFeeds: { $in: idToDelete } } }, { new: true }
)

if you wanna delete ObjectId ref at specific id User document the same but with updateOne

User.updateOne({ _id: idUser },
{ $pull: { homeFeeds: { $in: idToDelete } } }, { new: true }
)