更新所有用户数据节点休息PUT

时间:2018-04-08 07:08:48

标签: node.js mongoose put

我正在使用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不是函数。我在Stack Overflow上讨论了所有关于此问题的问题,但它对我来说非常混乱。

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:1)

您遇到的问题是由于find方法的返回类型,或者我会说查询。

mongo中的

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

因此,如果您的数据库只有一个用户或多个用户并不重要,User.find({})总是会返回一个数组(一个空数组或包含您的文档的数组)。并且由于.save()方法仅适用于有效的mongoose模型,因为数组(查询结果)不是因此您得到了错误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。推荐

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

有点像这样 -

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个集合中的所有documnet。
  2. 更新选项 - 这些选项是mongodb的更新运算符。 在这里,我们使用$set在我们的所有文档上设置两个字段。
  3. 表示查询行为的对象。在这里,我们使用了{muti: true},要求mongodb在符合搜索条件的多个文档上运行此更新查询。
  4. Callback(可选) - 一旦查询完成执行就会调用的函数,无论是错误还是结果。
  5. 使用这种方法的好处是 -

    1. 要么所有用户都会更新,要么都不会。原子
    2. 向数据库发出单个查询,从而提高查询性能。
    3. 您可以在mongodb docs中找到有关.update()的更多信息。

      改善点

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

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