【问题标题】:Updating all Users Data Nodejs Rest PUT更新所有用户数据 Nodejs Rest PUT
【发布时间】:2018-04-08 07:08:47
【问题描述】:

我正在使用 Nodejs 和 Mongo 创建一个 REST Api。我对 Node 很陌生,除了更新所有用户之外,我能够执行所有其他请求,例如 GET、POST、DELETE、PUT(针对单个用户)。

我想更新所有用户数据。以下是我的代码。

import mongoose from 'mongoose';
import { Router } from 'express';
import User from '../model/user';
import bodyParser from 'body-parser';

export default({ config, db }) => {
  let api = Router();

  api.put('/', (req, res) => {
    User.find({}, (err, user) => {
      if (err) {
        res.send(err);
      }

      user.name = req.body.name;
      user.salary = req.body.salary;

      user.save(function(err) {
        if (err) {
          res.send(err);
        }
        res.json({ message: 'All User info updated' });
      });
    });
  });

  return api;
}

我收到 user.save is not a function 当发出请求时。我在 Stack Overflow 上解决了所有关于此问题的问题,但这对我来说非常困惑。

【问题讨论】:

    标签: node.js mongoose put


    【解决方案1】:

    你可以这样做。在此处查看 Mongoose 的文档更新功能 http://mongoosejs.com/docs/documents.html

    import mongoose from 'mongoose';
    import {
        Router
    } from 'express';
    import User from '../model/user';
    import bodyParser from 'body-parser';
    
    export default ({
        config,
        db
    }) => {
        let api = Router();
    
        api.put('/', (req, res) => {
            User.update({}, {
                name: req.body.name,
                salary: req.body.salary
            }, {
                multi: true
            }, (err, data) => {
                if (err) {
                    res.send(err);
                }
                res.json({
                    message: 'All User info updated'
                });
            });
        });
    
        return api;
    }
    

    【讨论】:

    • 非常感谢 vinay
    【解决方案2】:

    您面临的问题是find 方法的返回类型,或者我会说查询。

    find 在 mongo 中返回一个 cursor(它是一个迭代器并包含您的查询结果),它在 mongoose 中的实现为您返回文档数组

    因此,无论您的数据库只有一个用户还是多个用户,User.find({}) 总是会返回一个数组(空数组或包含您的文档的数组)。并且由于 .save() 方法仅适用于有效的猫鼬模型,而数组(查询的结果)不是该模型,因此您收到错误 user.save is not a function.

    尝试记录你在回调中查找查询后得到的用户,你会得到一个数组。

    可能的解决方案

    1.完全不推荐

    迭代用户(我会说用户),您在回调中,然后在每个用户的每个迭代中调用.save()。跟踪保存文档时可能产生的错误,如果发生任何错误,则中断迭代(您也可以选择继续)。

    类似的东西-

    User.find({}, (err, users) => {
      if (err) {
        res.send(err);
      }
    
      let errorWhileSaving = null;
    
      for (let user of users) {
    
        if (errorWhileSaving) {
          res.send(ererrorWhileSaving);
          break;
        }
    
        user.name = req.body.name;
        user.salary = req.body.salary;
    
        user.save(function(err) {
          errorWhileSaving = err;
        });
      }
    
      res.json({ message: 'All User info updated' });
    });
    

    我从不推荐这种方法,因为我们使用这种方法会失去事务的原子性。保存任何用户的任何失败都会导致数据库的部分更新,这确实是有害的。

    它还会向数据库服务器发出多个查询,这肯定会影响事务的性能。

    我所说的事务是指对数据库进行操作的任何一组查询(简单或复杂)。

    2。推荐

    使用.update()方法,而不是使用.find()然后迭代文档然后通过发出多个.save()调用保存它们。

    有点像这样-

    User.update(
      {}, 
      {
        $set: {
          name: req.body.name,
          salary: req.body.salary
        }
      },
      {
        multi: true
      },
      function (err, results) {
        if (err) {
          res.send(err);
        }
    
        res.json({ message: 'All User info updated' });
      }
    );
    

    说明

    .update 方法期望 -

    1. 搜索条件 - 用于查找要更新的文档的条件。 这里我们提供了{},这意味着我们要更新users 集合中的所有文档网。
    2. 更新选项 - 这些选项是mongodb 的更新操作符。 在这里,我们使用$set 在我们所有的文档上设置两个字段。
    3. 表示查询行为的对象。在这里,我们使用了{muti: true},它要求 mongodb 对匹配搜索条件的多个文档运行此更新查询。
    4. 回调(可选)- 查询完成后将调用的函数,无论是错误还是结果。

    使用这种方法的好处是 -

    1. 要么所有用户都将得到更新,要么没有。原子性
    2. 向数据库发出单一查询,从而提高查询性能。

    您可以在 mongodb 文档中找到有关 .update() 的更多信息。

    改进点

    我注意到,您仍在使用回调来处理异步任务。如果你还不熟悉 Promises,那就去研究它们,而不是使用回调,优化你的代码以使用 Promises。我见过优秀的应用程序开发人员努力推理包含在回调中的代码,所以要明智并开始使用 Promises 来创造更美好的未来。

    Here 是一篇从 Promises 开始的好文章。

    【讨论】:

    • 感谢您的回答,但 vinay 先回答了,所以我接受了他的回答
    • 是的。事实上,你只是让我想起了一些事情。我应该在我的更新中编辑 Vinay 的答案,因为除了我添加的一些建议之外,我们俩都指向相同的解决方案。要走的路:)
    猜你喜欢
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    • 2015-12-30
    • 2023-03-21
    • 2016-10-12
    • 1970-01-01
    • 2019-04-25
    相关资源
    最近更新 更多