编辑:这确实有效
正如Mongoose-Subdocs:"添加子域"文档所说,我们可以使用push
方法(即parent.children.push({ name: 'Liesl' });
)添加子域
但我想更进一步,并希望使用$push
运算符来插入子文档。
我有两个模式:ThingSchema
:
var ThingSchema = mongoose.Schema({
name: {
type: String,
required: true
},
description: {
type: String
}
});
以及具有ThingSchema
:的子文档(things
)阵列的主文档BoxSchema
var BoxSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
description: {
type: String
},
things: {
type: [ThingSchema]
}
});
var BoxModel = mongoose.model('Box', BoxSchema);
我需要things
中的每个子文档都有unique
名称,也就是说,不可能将一个新文档插入到这个数组中,而该数组具有已经存在于子域中的name
值。
我正在尝试做一些类似的事情:
var thingObj = ... // the 'thing' object to be inserted
BoxModel.update({
_id: some_box_id, // a valid 'box' ObjectId
"things.name": { "$ne": thingObj.name }
},
{
$push: { things: thingObj}
},
function(err) {
if (err) // handle err
...
});
但是没有得到任何期望的结果。
在查询中使用$push
运算符将ThingSchema
子文档添加到BoxSchema
的thing
数组中的正确方法是什么(如果有另一个同名子域,则必须不添加该子域),而不是Mongoose Docs的方法?
编辑:这就是问题所在
我犯了一个错误,上面的代码按预期运行,但现在我遇到的问题是,当thingObj
与ThingSchema
不匹配时,会在things
数组中插入一个空对象:
// now thingObj is trash
var thingObj = { some: "trash", more: "trash" };
在执行给定上述垃圾对象的查询时,将以下空对象插入子域数组:
{ _id: ObjectId("an_obj_id") }
在这种情况下,当thingObj
与ThingSchema
不匹配时,我想要的是不添加任何内容。
$addToSet
为数组添加了一些唯一的内容(就像在中检查重复项一样)。但它只适用于基元。
您应该做的是将things
放入它们自己的集合中,并对名称进行唯一索引。然后,进行此更改
things: {
type: [{type: ObjectId, ref: 'thingscollection'}]
}
这样你就可以进行
BoxModel.update({
_id: some_box_id, // a valid 'box' ObjectId
"things": { "$ne": thingObj._id }
},
{
$addToSet: { things: thingObj._id}
},
function(err) {
if (err) // handle err
...
});
当您提取时,请使用things
上的.populate
来获取其中的完整文档。
这并不完全是你想要的,但这是一个可能实现你目标的设计。