我知道这个问题在这里被打死了,但我已经尝试了一切,无法解决这个问题。这让我很生气。
我的模型看起来像这样:
customer {
email: String,
password: String,
addresses: [addresses_schema]
}
和addresses_schema看起来像
address {
addr1: String,
... Other address fields
primary_address: Boolean
}
现在,我想更新用户的特定地址记录,使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' ... ]}
有人能帮助我吗?我真的很感激。谢谢!
答案 0 :(得分:1)
我的资金将用在" address_id"你正在寻找的价值实际上并不匹配任何东西。在已审阅的文档上执行.update()
通常不是您想要的,这会使代码中的问题混淆。
最初执行.findOneAndUpdate()
,以便通过匹配的"电子邮件"和#34; 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 } ] }
并且调试输出如下:
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()
,在承诺的解决方案中,您看到返回的文档为"更新"来自指定数组元素的原始形式。
这是你基本上应该在这里做的事情,对退回文件的任何进一步修改都来自""最初"更新和获取"已经完成了。
答案 1 :(得分:0)
我不知道你是否真的必须使用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);
}
});
});