如何更新Mongoose中的部分字段,但不是所有字段

niwlg2el  于 2023-10-19  发布在  Go
关注(0)|答案(5)|浏览(135)

下面是UserSchema:

var UserSchema = new Schema({
    username: { type: String, required: true, index:{unique: true} },
    firstName: { type: String, required: true },
    lastName: { type: String, required: true },
    email: { type: String, required: true, index:{unique: true} }, 
    password: { type: String, required: true, select: false }
});

下面是http PUT请求:

// update user information
  api.put('/users/:username', function(req, res) {

    User.findOne({username: req.params.username}, function(err, user) {

      if (err){
        res.send(err);
        return;
      }

      if (!user){
        res.status(404).send({
          success: false,
          message: "user not found"
        });
      } else {
        user.username = req.body.username;
        user.email = req.body.email;
        user.password = req.body.password;
        user.firstName = req.body.firstName;
        user.lastName = req.body.lastName;

        user.save(function(err) {
          if (err){
            res.send(err);
            return;
          }

          res.json({
            success: true,
            message: "user information updated."
          });
        });
      }
    });
  });

问题是,如果用户只想更新有限的字段,例如,只更新用户名,那么上面的代码不起作用,错误看起来像这样:

{
  "message": "User validation failed",
  "name": "ValidationError",
  "errors": {
    "lastName": {
      "properties": {
        "type": "required",
        "message": "Path `{PATH}` is required.",
        "path": "lastName"
      },
      "message": "Path `lastName` is required.",
      "name": "ValidatorError",
      "kind": "required",
      "path": "lastName"
    },
    "firstName": {
      "properties": {
        "type": "required",
        "message": "Path `{PATH}` is required.",
        "path": "firstName"
      },
.........

那么,我如何实现允许用户更新部分字段而不是所有字段?
任何意见和建议都很感激!

bqucvtff

bqucvtff1#

在update对象中使用findOneAndUpdate和运算符$set

User.findOneAndUpdate({username: req.params.username}, { $set: req.body }, { new: true }, callback);

$set将允许您仅修改req.body对象中提供的字段。

a1o7rhls

a1o7rhls2#

我最终使用了这个解决方案:

const dot = require('dot-object'); // this package works like magic

const updateData = { some: true, fields: true };

User.updateOne(
  { _id: req.user._id },
  { $set: dot.dot(updateData) },
  (err, results) => {
    if (err) res.json({ err: true });
    else res.json({ success: true });
  }
);

我在这里找到了这个想法:https://github.com/Automattic/mongoose/issues/5285#issuecomment-439378282

8iwquhpp

8iwquhpp3#

这是一个很好的妥协:
指定用户可以更新的字段

let fieldToUpdate = {
    name: req.body.name,
    email: req.body.email,
  };

然后删除所有包含falsy值的键

for (const [key, value] of Object.entries(fieldToUpdate)) {
    if (!value) {
      delete fieldToUpdate[key];
    }
  }

然后使用$set运算符更新值

const user = await User.findByIdAndUpdate(
    req.user.id,
    { $set: { ...fieldToUpdate } },
    {
      runValidators: true,
      new: true,
    }
  );
oyt4ldly

oyt4ldly4#

可以使用'findOneAndUpdate'方法。

User.findOneAndUpdate({username: req.params.username}, {username: req.body.username}, function(err, user) {
  //...
});
8fq7wneg

8fq7wneg5#

据我所知,您希望能够更新任何数量的字段。下面的代码来自一个过去的项目。
模型

const ingredientSchema = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    name: { type:String, required: true },   
    quantity: { type: Number, default: 0}
});

HTTP PUT

router.put('/:ingredientId', (req, res, next) => {
    // extracting ingredient id from url parameters
    const id = req.params.ingredientId;

    //creating a map from the passed array
    const updateOps = {};
    for(const ops of req.body){
        updateOps[ops.propName] = ops.value;
    }

    //updating the found ingredient with the new map
    Ingredient.update({_id: id}, { $set: updateOps})
        .exec()
        .then(result =>{
            console.log(result);
            //returning successful operation information
            res.status(200).json(result);
        })
        //catching any errors that might have occured from above operation
        .catch(err => {
        console.log(err);
            //returning server error
            res.status(500).json({
                error: err
            });
        });
});

PUT请求(json)

[
    {"propName": "name", "value": "Some other name"},
    {"propName": "quantity", "value": "15"},
]

或者如果你想更新一个字段

[
    {"propName": "name", "value": "Some other name"}
]

基本上,你有一个数组的这些属性/字段名称和它们的新值。你可以只更新一个或所有这些方式,如果你愿意。或者我都不相信。
希望这能有所帮助!有什么问题尽管问!

相关问题