Mongoose / MongoDB更新不起作用

我知道这个问题已经在这里被打死了,但我已经尝试了一切,无法解决这个问题。 这让我发疯。

我有一个看起来像这样的模型:

customer { email: String, password: String, addresses: [addresses_schema] } 

和addresses_schema看起来像

 address { addr1: String, ... Other address fields primary_address: Boolean } 

现在,我想更新一个用户的特定地址logging,以使primary_address为true。

所以我这样做:

 var modifyUser = function(address_id){ User.findOne( { email: email } ).then(function(user){ user.update({ 'addresses._id': address_id }, { $set: { 'addresses.$.primary_address': 'true' } } ) .then(function(){ console.log('Should eventually reach here'); }).catch (err) { console.log('err:', err.message); }); user.save(); }); } 

但是,如果我在更新之前和之后抓取user.addresses,则没有任何更改。 相反,它给了我错误:

 cannot use the part (addresses of addresses._id) to traverse the element ({addresses[ {addr1: '123 test street', addr2: '', city: 'test city' ... ]} 

有人能帮我吗? 我真的很感激。 谢谢!

我的钱在这里,你正在查找的“address_id”值实际上不匹配任何东西。 在retrived文档上执行.update()通常不是你想要的,这会在代码中混淆问题。

相反,最初执行一个.findOneAndUpdate() ,通过匹配的“email”和“addresses._id”值进行检索,就像在这个完整的例子中所做的那样:

 var async = require('async'), mongoose = require('mongoose'), Schema = mongoose.Schema; var addressSchema = new Schema({ name: String, primary: { type: Boolean, default: false } }); var userSchema = new Schema({ email: String, addresses: [addressSchema] }); var User = mongoose.model('User',userSchema); mongoose.connect('mongodb://localhost/utest'); mongoose.set("debug",true); async.series( [ function(callback) { User.remove({},callback); }, function(callback) { async.waterfall( [ function(callback) { User.create({ email: "example@example.com", addresses: [ { "name": "One" },{ "name": "Two" } ] },callback) }, function(user,callback) { console.log(user); User.findOneAndUpdate( { "email": user.email, "addresses._id": user.addresses[1]._id }, { "$set": { "addresses.$.primary": true } }, { "new": true } ).then(function(newUser) { console.log(newUser); callback(); }).catch(function(err) { callback(err); }); } ], callback ) } ], function(err) { if (err) console.log(err.stack); mongoose.disconnect(); } ); 

这将持续产生这样的输出:

 { __v: 0, email: 'example@example.com', _id: 55ecf31a53558e183d208aa2, addresses: [ { name: 'One', _id: 55ecf31a53558e183d208aa4, primary: false }, { name: 'Two', _id: 55ecf31a53558e183d208aa3, primary: false } ] } { _id: 55ecf31a53558e183d208aa2, email: 'example@example.com', __v: 0, addresses: [ { name: 'One', _id: 55ecf31a53558e183d208aa4, primary: false }, { name: 'Two', _id: 55ecf31a53558e183d208aa3, primary: true } ] } 

并且有这样的debugging输出:

 Mongoose: users.remove({}) {} Mongoose: users.insert({ email: 'example@example.com', _id: ObjectId("55ecf35627cddb243d3d8e22"), addresses: [ { name: 'One', _id: ObjectId("55ecf35627cddb243d3d8e24"), primary: false }, { name: 'Two', _id: ObjectId("55ecf35627cddb243d3d8e23"), primary: false } ], __v: 0 }) Mongoose: users.findAndModify({ 'addresses._id': ObjectId("55ecf35627cddb243d3d8e23"), email: 'example@example.com' }) [] { '$set': { 'addresses.$.primary': true } } { new: true, upsert: false, remove: false } 

这只是设置示例,但主要的事情发生在.findOneAndUpdate()在承诺的解决scheme中,您看到返回的文档从指定数组元素的原始forms“更新”。

这就是你基本上应该在这里做的事情,对返回文档的任何进一步修改都是在“最初的”更新和获取“之后”完成的。

我不知道你是否真的需要使用mongoose,不知道这是否是你的问题的要求。

这里是直Monogodb驱动程序的例子:

 var MongoClient = require('mongodb').MongoClient , format = require('util').format; MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) { if(err) throw err; db.collection('test').findAndModify( {hello: 'world'}, // query [['_id','asc']], // sort order {$set: {hi: 'there'}}, // replacement, replaces only the field "hi" {}, // options function(err, object) { if (err){ console.warn(err.message); // returns error if no matching object found }else{ console.dir(object); } }); });