首页 文章

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

提问于
浏览
2

编辑:这实际上是有效的

正如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 ,主文档有 ThingSchema 的子文档数组( things ):

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

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

我需要 things 中的 every subdocument 来拥有 unique 名称 - 也就是说,不可能将新文档插入到具有 name 值的数组中,该数据已存在于subdocs中 .

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

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 子文档添加到 BoxSchemathing 数组中使用 $push 运算符在查询中执行此操作的正确方法是什么( must 如果还有另一个名为相同的子文件,则不添加子文件),而不是Mongoose Docs方式?


编辑:这实际上是问题所在

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

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

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

{ _id: ObjectId("an_obj_id") }

我想要这种情况,当 thingObjThingSchema 不匹配时,没有什么可以添加的 .

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

    当你在 things 上使用.populate来获取那里的完整文件时 .

    这不完全是你想要的,但这是一个可能达到你的目标的设计 .

相关问题