使用Mongoose、Express和NodeJS更新模型

23

我正在尝试更新一个已实例化的模型('Place'-我知道它可以从其他路线正常工作)在MongoDB中,并花费了一段时间来正确地执行此操作。我还尝试重定向回查看“place”的页面以查看更新后的属性。

节点v0.4.0,表达式v1.0.7,Mongoose 1.10.0

模式:

var PlaceSchema = new Schema({
name  :String
,  capital: String
,  continent: String
});

控制器/路由:

app.put('/places/:name', function(req, res) {
var name = req.body.name;
var capital = req.body.capital;
var continent = req.body.continent;
Place.update({ name: name, capital: capital, continent: continent}, function(name) {
    res.redirect('/places/'+name)
});

我尝试了许多不同的方法,但似乎无法成功。
此外,我声明三个{name、capital和continent}变量的方式是否会阻止后续操作? 感谢您的一般调试帮助。在声明下面的console.log(name)没有输出任何内容。

Jade表单:

h1 Editing #{place.name}
form(action='/places/'+place.name, method='POST')
  input(type='hidden', name='_method', value='PUT')
  p
    label(for='place_name') Name:
    p
    input(type='text', id='place_name', name='place[name]', value=place.name)
    p
    label(for='place_capital') Capital: 
    p
    input(type='text', id='place_capital', name='place[capital]', value=place.capital)
    p
    label(for='place_continent') Continent:
    p
    textarea(type='text', id='place_continent', name='place[continent]')=place.continent
    p
    input(type="submit")
4个回答

41

在进行任何更新之前,您必须先找到该文档:

Place.findById(req.params.id, function(err, p) {
  if (!p)
    return next(new Error('Could not load Document'));
  else {
    // do your updates here
    p.modified = new Date();

    p.save(function(err) {
      if (err)
        console.log('error')
      else
        console.log('success')
    });
  }
});

在我使用与您相同的设置的生产代码中有效。除了findById之外,您可以使用mongoose提供的任何其他查找方法。只需确保在更新文档之前获取文档即可。


谢谢!快速问题:在db.query之后的匿名回调函数如何知道您示例中的“p”是/应该是查询结果?那只是内置行为吗? - JohnAllen
它本身并不“知道”。这就是为什么你必须检查它是否为空(因为在错误时结果总是为空)。在我的例子中,我没有使用err对象,这就是确切的错误消息所包含的位置。如果你查询错误的成员(例如p.foo,而p没有foo成员),你会得到undefined - schaermu
1
@JohnAllen,我不知道这是否是您要求的内容:findById承诺始终将相同的参数列表传递给其回调函数;一个错误和文档。由于function(err, p)将第二个参数称为“p”,因此p就是文档。 - grantwparks
有人知道我是否可以使用findByIdAndUpdate一次性查找ID并更新文档吗? - Nam Nguyen
我遇到了“ReferenceError: next未定义”的问题。 - maudulus

26

现在,我认为你能做到这一点:

Place.findOneAndUpdate({name:req.params.name}, req.body, function (err, place) {
  res.send(place);
});

你也可以通过ID查找:

Place.findOneAndUpdate({_id:req.params.id}, req.body, function (err, place) {
  res.send(place);
});

1
帮助了我很大,干净而有效。 - Asfand Shabbir
非常好的、干净的方式 - Anuj Choudhary

6

现在,你可以直接通过id查找和更新内容了,这是针对Mongoose v4的。

Place.findByIdAndUpdate(req.params.id, req.body, function (err, place) {
  res.send(place);
});

需要注意的是,如果您需要更新对象,则需要传递{new: true},例如:

Place.findByIdAndUpdate(req.params.id, req.body, {new: true}, function (err, place) {
  res.send(place);
});

0

我认为你的问题在于你正在使用node 0.4.0 - 尝试切换到0.2.6,应该可以解决问题。在github上记录了一个问题,即bodyDecoder在node >= 0.3.0中无法填充req.body.variable字段。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接