如何在查询中使用$push将数据插入子文档,而不是检索文档并将其保存回



编辑:这确实有效

正如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子文档添加到BoxSchemathing数组中的正确方法是什么(如果有另一个同名子域,则必须不添加该子域),而不是Mongoose Docs的方法?


编辑:这就是问题所在

我犯了一个错误,上面的代码按预期运行,但现在我遇到的问题是,当thingObjThingSchema不匹配时,会在things数组中插入一个空对象:

// now thingObj is trash
var thingObj = { some: "trash", more: "trash" };

在执行给定上述垃圾对象的查询时,将以下空对象插入子域数组:

{ _id: ObjectId("an_obj_id") }

在这种情况下,当thingObjThingSchema不匹配时,我想要的是不添加任何内容。

$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来获取其中的完整文档。

这并不完全是你想要的,但这是一个可能实现你目标的设计。

最新更新