2

编辑:这实际上是有效的

正如猫鼬 - 子文档:“添加子文档”文档所说,我们可以使用该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);

我需要每个子文档都有名称 - 也就是说,不可能将新文档插入到该数组中,该数组的值已经存在于子文档中。thingsuniquename

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

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​​子文档添加到BoxSchema'thing数组中的正确方法是什么(如果有另一个名称相同的子文档,则不得添加子文档),而不是Mongoose Docs方式?$push


编辑:这实际上是问题

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

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

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

{ _id: ObjectId("an_obj_id") }

我想要这种情况,当 与thingObj不匹配时ThingSchema,无需添加任何内容。

4

1 回答 1

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
  ...
});

并且当您获取使用.populatethings获取完整的文档时。

这不完全是您想要的方式,但这是一种可以实现您的目标的设计。

于 2015-11-04T00:53:31.423 回答