更新所有用户数据 Nodejs Rest 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在提出放置请求时不是一个函数。我在堆栈溢出上浏览了所有关于这个问题的问题,但这对我来说非常令人困惑。

你可以这样做。在此处查看猫鼬的文档更新功能 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;
}

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

mongo 中的find返回一个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. 推荐

不要先使用.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集合中的所有文档。
  2. 更新选项 - 这些选项是mongodb的更新运算符。 在这里,我们使用$set在所有文档上设置两个字段。
  3. 表示查询行为的对象。在这里,我们使用了{muti: true},它要求mongodb对与搜索条件匹配的多个文档运行此更新查询。
  4. 回调(可选)- 查询完成执行后将调用的函数,出现错误或结果。

使用这种方法的好处是 -

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

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

改进点

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

这是一篇从承诺开始的好文章。

最新更新