我正在使用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上讨论了所有关于此问题的问题,但它对我来说非常混乱。
答案 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
方法的返回类型,或者我会说查询。
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
方法需要 -
{}
,这意味着我们要更新users
个集合中的所有documnet。mongodb
的更新运算符。
在这里,我们使用$set
在我们的所有文档上设置两个字段。{muti: true}
,要求mongodb在符合搜索条件的多个文档上运行此更新查询。使用这种方法的好处是 -
您可以在mongodb docs中找到有关.update()
的更多信息。
改善点
我注意到,您仍在使用回调来处理异步任务。如果你还不熟悉promises,那就去研究它们,而不是使用回调,优化你的代码来使用Promises。我看到很好的应用程序开发人员正在努力推理回调中包含的代码,所以要明智并开始使用Promises以获得更好的未来。
Here是一篇从Promises开始的好文章。