使用 Mongoose、Express、NodeJS 更新模型

Posted

技术标签:

【中文标题】使用 Mongoose、Express、NodeJS 更新模型【英文标题】:Update model with Mongoose, Express, NodeJS 【发布时间】:2011-06-28 19:53:42 【问题描述】:

我正在尝试更新 MongoDB 中的实例化模型('Place' - 我知道它适用于其他路线)并且花了一段时间尝试正确执行此操作。我还试图重定向回查看“地点”的页面以查看更新的属性。

Node v0.4.0、Express 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)(声明正下方)不记录任何内容。

玉形态:

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")

【问题讨论】:

【参考方案1】:

您必须在更新任何内容之前找到该文档:

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”是/应该是查询结果?这只是一种内置行为吗? 它自己并不“知道”它。这就是为什么你必须检查它是否为空(因为结果总是在错误时为空)。在我的示例中,我没有使用 err 对象,这是包含确切错误消息的地方。如果您查询了错误的成员(例如 p.foo 而 p 没有 foo 成员),您将得到 undefined @JohnAllen,IDK,如果这是您的要求: findById 承诺始终将相同的参数列表传递给它的回调;错误和文档。由于 function(err, p) 调用第二个参数“p”,所以 p 是文档。 有人知道我是否可以使用 findByIdAndUpdate 来查找 ID 并使用一个命令更新文档吗? 我收到ReferenceError: next is not defined【参考方案2】:

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

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);
);

【讨论】:

帮了我很多,干净有效。 非常干净整洁的方式【参考方案3】:

所以现在您可以直接通过 id 查找和更新,这是针对 Mongoose v4 的

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

顺便提一下,如果你需要更新的对象,那么你需要通过new: truelike

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

【讨论】:

【参考方案4】:

我认为您的问题是您使用的是节点 0.4.0 - 尝试移动到 0.2.6 并且它应该可以工作。在 github 上记录了一个问题,bodyDecoder 没有填充节点 >= 0.3.0 中的 req.body.variable 字段。

【讨论】:

【参考方案5】:

你可以根据下图做类似的事情

更新:

在我的解决方案中:我创建了一个模型、控制器和路由,以在 Nodejs MVC 框架中以 MongoDB 作为数据库来描述类似的场景(interacting with MongoDB method like updating/creating data to the database)

// user.js - this is the user model

const mongoose = require('mongoose')
const validator = require('validator')

const User = mongoose.model('User', 
  name: 
    type:  String,
    required:  true,
    trim:  true
  ,
  email: 
    type:  String,
    required:  true,
    trim:  true,
    lowercase:  true,
    validate(value) 
      if (!validator.isEmail(value)) 
        throw  new  Error('Email is invalid')
      
    
  ,
  password: 
    type:  String, 
    required:  true, 
    minlength:  7, 
    trim:  true,
    validate(value) 
      if (value.toLowerCase().includes('password'))  
        throw  new  Error('Password cannot contain "password"') 
       
     
  ,
  age:  
    type:  Number, 
    default:  0, 
    validate(value)  
      if (value  <  0)  
        throw  new  Error('Age must be a positive number') 
      
    
  
);   

module.exports  =  User

// userController.js**

exports.updateUser = async(req, res) => 
  const updates = Object.keys(req.body)
  const allowedUpdates = ['name', 'email', 'password', 'age']
  const isValidOperation = updates.every((update) =>  
    allowedUpdates.includes(update))
    if (!isValidOperation) 
      return res.status(400).send('Invalid updates!')
    
    try 
      const user = await UserModel.findByIdAndUpdate(req.params.id, 
        req.body,  new: true, runValidators: true )
      if (!user) 
        return res.status(404).send( message: 'You do not seem to be registered' )
      
      res.status(201).send(user)
     catch (error) 
      res.status(400).send(error)
    


// **router.js**
router.patch('/user/:id', userController.updateUser)

希望对大家有帮助,也可以Read more。

【讨论】:

以上是关于使用 Mongoose、Express、NodeJS 更新模型的主要内容,如果未能解决你的问题,请参考以下文章

使用 Mongoose 和 Express 创建嵌入式文档

Mongoose & Express:从子文档发布数据

Mongoose & Express:从子文档发布数据

使用护照使用 NodeJs mongodb(mongoose) express 的注册表单

使用 Mongoose、Express、NodeJS 更新模型

node.js + express.js:使用 mongodb/mongoose 处理会话