简体   繁体   中英

MongoDB $set operator. Trying to update an object inside array of objects

I am trying to update a specific field in my MongoDB schema in my Node.js API.

Specifically, the function works to accept a friend request for a user ( the accepter ) The friend will be stored in the friends array, and when the user ( the accepter ) accepts the request, the status of the friend in the friends array will change from 'pending' to 'accepted'

From other similar posts, I understand that the $set operator allows me to find and edit inside the friends array, but the database does not update to "accepted." It seems none of the solutions work so far.

Additional Info:

  • My HTTP Client hangs when I access the route
  • My accepterID works (when I console.log, I am able to view the entire user object ( the accepter )
  • The requesterID also works

Any Help would be greatly appreciated! I am brand new to this!

Here is the function:

 User.findById(accepterID)
          .then(accepter => {
            accepter.update(
              { "friends.friendID" : requesterID }, 
              { $set: { "friends.$.status" : "accepted" }},
            )
            res.json(accepter)
          })
        }

Here is the Schema:

const UserSchema = new Schema({

  method: {
    type: String,
    enum: ['local', 'google', 'facebook'],
    required: true
  },

  friends: [
    {
      status: {
        type: String,
        enum: ['requested', 'pending', 'accepted']
      },
      addedWhen: {
        type: Date
      },
      friendID: {
        type: Schema.Types.ObjectId,
        ref: 'users'
      }
    }
  ],

  local: {
    firstName: {
      type: String
    },
    lastName: {
      type: String
    },
    email: {
      type: String,
      lowercase: true
    },
    password: {
      type: String,
    },
    date: {
      type: Date,
      default: Date.now
    }
  },

});

Trying such an update gives me a deprecation warning (it seems update is an alias for the collection's update ), then crashes because "cannot use part (friends of friends.status) to traverse the element" . Not sure why it says so.

So maybe your HTTP client hangs because somewhere you don't handle errors properly? (Anyway, no reason res.json fails on itself.)

Independently from this HTTP debugging of yours, I had the update working like this:

User.findById(accepterID).then(accepter => {
  // updateOne works as well, but no way it gives the fresh doc
  User.findOneAndUpdate(
    { _id: accepterID, 'friends.friendID': requesterID },
    { $set: { friends.$.status: 'accepted' } },
    { new: true },
    (err, freshAccepter) => {
      if (err) throw err;
      res.json(freshAccepter);
    }
  );
});

Or shorter, since you don't need the original accepter, no need for the wrapping findById .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM