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

时间:2015-11-03 23:39:09

标签: node.js mongodb mongoose mongodb-query subdocument

编辑:这实际上正在运作

正如Mongoose - Subdocs: "Adding subdocs"文档所述,我们可以使用push方法添加一个子网(即parent.children.push({ name: 'Liesl' });

但我想更进一步,并希望使用$push运算符来插入子文档。

我有两个模式:ThingSchema

var ThingSchema = mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  description: {
    type: String
  }
});

BoxSchema,主文档包含things的子文档(ThingSchema)数组:

var BoxSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  description: {
    type: String
  },
  things: {
    type: [ThingSchema]
  }
});

var BoxModel = mongoose.model('Box', BoxSchema);

我需要things中的每个子文档才能拥有unique个名称 - 也就是说,将新文档插入到具有{{{{ 1}}已存在于subdocs中的值。

我正在尝试做类似的事情:

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 ... }); 运算符在ThingSchema的{​​{1}}数组中将BoxSchema子文档添加到查询中的正确方法是什么(必须不添加suboc,如果有另一个名为相同的子网站,而不是 Mongoose Docs 方式?

编辑:这实际上是问题

我犯了一个错误,上面的代码按预期工作现在我遇到的问题是当thing$push不匹配时,会插入一个空对象进入thingObj数组:

ThingSchema

在给定上述垃圾对象的情况下执行查询时,以下空对象将插入到subdocs数组中:

things

我希望这种情况,当// now thingObj is trash var thingObj = { some: "trash", more: "trash" }; { _id: ObjectId("an_obj_id") } 不匹配时,无需添加任何内容。

1 个答案:

答案 0 :(得分:1)

$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获取完整文档时。

它并不完全是你想要的,但这是一种可能达到你所瞄准目标的设计。