假设我有这个模型:
var stuffSchema = new mongoose.Schema({
"id": 1,
"cars": {
"suv": [],
"sports": [],
"supercar": [{
"owner": "nick",
"previousOwners": [
ObjectId("574e1bc0abfb4a180404b17f"),
ObjectId("574e1bdeabfb4a180404b180"),
ObjectId("574e1c4babfb4a180404b181"),
ObjectId("574e1c67abfb4a180404b182"),
ObjectId("574e23abd25baf340e678b2d"),
ObjectId("574e241ec8caa3a81cc85ed5")
]
}]
}
});
var Stuff = mongoose.model('Stuff', stuffSchema);
如果特定的previousOwners
已经存在,我想添加owner
,如果具体的话,我想添加一个新的owner
与相应的previousOwner
owner
尚不存在。
这是我试过的:
Stuff.update({
id: 1,
'cars.supercar.owner': 'olix'
}, {
$addToSet: {
'cars.supercar.$.previousOwners': ObjectId("574e241ec8caa3a81c893e73")
}
}, {
$upsert: true
}, function(err) {
if (err) {
console.log('Error: ' + err);
}
});
我希望这会添加一个名为'olix'的新owner
,并附带其previousOwners
数组。这会使我的文档看起来像这样:
{
"id": 1,
"cars": {
"suv": [],
"sports": [],
"supercar": [{
"owner": "nick",
"previousOwners": [
ObjectId("574e1bc0abfb4a180404b17f"),
ObjectId("574e1bdeabfb4a180404b180"),
ObjectId("574e1c4babfb4a180404b181"),
ObjectId("574e1c67abfb4a180404b182"),
ObjectId("574e23abd25baf340e678b2d"),
ObjectId("574e241ec8caa3a81cc85ed5")
],
"owner": "olix",
"previousOwners": [
ObjectId("574e241ec8caa3a81c893e73")
]
}]
}
}
根本不起作用。它甚至没有产生错误。 我试过了:
db.stuffs.find({id: 1, 'cars.supercar.owner': 'nick'})
并成功返回文档。只是为了确保我的查询是正确的。
我做错了什么?
答案 0 :(得分:1)
首先,您的架构定义不正确,请改用:
var stuffSchema = new mongoose.Schema({
'id': Number,
'cars': {
'suv': [],
'sports': [],
'supercar': [{
_id: false,
'owner': { type: String },
'previousOwners': [{ type: mongoose.Schema.ObjectId }]
}]
}
});
var Stuff = mongoose.model('Stuff', stuffSchema);
将更新查询更改为:
Stuff.update({
id: 1
}, {
$addToSet: {
'cars.supercar': {
'owner': 'olix',
'previousOwners': [ObjectId('574e241ec8caa3a81c893e75')]
}
}
}, function(err) {
if (err) {
console.log('Error: ' + err);
}
});
注意:mongoose检查对象的每个属性,因此如果它的所有者字段和previousOwners数组完全相同,则supercar数组对象是相同的,否则它会将新对象推送到超级数组中。
答案 1 :(得分:0)
我通过手动更新解决了它:
Stuff.findOne({
id: 1
}, function(err, stuff) {
if (err) {
return done(err);
}
var ownersList = stuff.cars.supercar.map(function(supercarCar) {
return supercarCar.owner;
});
var ownerIndex = ownersList.indexOf('nick');
if (ownerIndex != -1) {
stuff.cars.supercar[ownerIndex].previousOwners.push(ObjectId("574e241ec8caa3a81c893e73"));
} else {
stuff.cars.supercar.push({
owner: 'nick',
previousOwners: [ObjectId("574e241ec8caa3a81c893e73")]
})
}
stuff.save(function(err) {
if (err) {
return done(err);
}
});
});
备注强>
这是一个假文件,所有属性名称都因匿名而被更改。
此处使用了完成功能,因为此代码是在 .pre(' save' >模式实例中运行的。
有些值仅为了示例目的而被硬编码。