【问题标题】:Set array element to null with Mongoose使用 Mongoose 将数组元素设置为 null
【发布时间】:2014-07-08 18:51:27
【问题描述】:

我遇到了一个有趣的问题,试图用 mongoose 将 mongo 中的子数组的一个元素设置为 null(这似乎很明显,是的)。

我的架构看起来像:

var ItemSchema = new Schema({
  name : String,
  slots: { type: [{ type : Schema.Types.ObjectId, ref: 'Slot' }], default: [] }
});

我的数据如下:

{
  _id  : ObjectId("53bafbfd00cbcc3a1178e11b"),
  name : "item 1",
  slots: [null, null, ObjectId("53baf297d63228631029d2f8"), null, null]
},
{
  _id  : ObjectId("53baf297d63228631029d2f8"),
  name : "item 2",
  slots: [ObjectId("53baf1b3fecfe25c10233801"), null, null, null, null]
}

nb:nullvalues 对于顺序逻辑目的很重要。

所以,假设我得到了这些物品中的第一个:

Items.findById('53bafbfd00cbcc3a1178e11b', function (err, item) {

  console.log(item.slots);
  // [null, null, "53baf297d63228631029d2f8", null, null] --> OK

  // BIG update here
  item.slots[2] = null;

  item.save(function (err, itemSaved) {

    // no errors

    console.log(itemSaved.slots);
    // [null, null, null, null, null] --> Well, so everything works, right ?

    // so let's find the same item again !

    Items.findById('53bafbfd00cbcc3a1178e11b', function (err, itemSearched) {

      console.log(itemSearched.slots);
      // [null, null, "53baf297d63228631029d2f8", null, null] --> what ?? id still here ?

    });

  });

});

所以即使save 工作,ID 也没有设置为null。我不明白,真的。我需要这么多的解释!提前致谢。

【问题讨论】:

  • 你可以试试 console.logging item.save(function (err, itemSaved) { itemSaved 吗?
  • 我以这种方式更新了我的问题:保存的项目看起来不错,但在最后一次查找查询之后却没有..
  • slots 在您的架构中是如何定义的?
  • 我更新了我的问题,所以你现在可以看到我的架构
  • 实际上,我不久前遇到过这个问题。 item.save 有时不会正确调用更改值的更新,如果您真的使用调试器逐步完成,您会看到有趣的东西。

标签: node.js mongoose node-mongodb-native


【解决方案1】:

您似乎需要将该元素显式标记为已修改,否则save 将不会接受更改:

item.slots[2] = null;
item.markModified('slots.2');
item.save(function (err, itemSaved) {
    ....

可能是因为null 不是有效的ObjectId

另一种方法是使用update$unset

Items.update(
    {_id: '53bafbfd00cbcc3a1178e11b'},
    {$unset: {'slots.2': 1}}, function(err, numAffected) {
        ...

【讨论】:

  • 很好的解决方案,你也可以item.markModified('slots')对吧?
  • @tpae 这也行得通,但它不如猫鼬那么有效,然后必须更新整个数组而不仅仅是修改后的元素。
【解决方案2】:

试试这个:

Items.update(
    {_id: '53bafbfd00cbcc3a1178e11b'}, 
    {$set: { slots: [null, null, null, null, null] } }, 
function(err, results) {
  Items.findById('53bafbfd00cbcc3a1178e11b', function (err, itemSearched) {
      console.log(itemSearched.slots);
    });
  });
});

围绕它创建一个包装函数,如下所示:

ItemSchema.statics.clearSlot = function(id, slot, cb) {
  var self = this;
  this.findById(id, function(err, item) {
    var slots = item.slots;
    slots[slot] = null;
    self.update({_id: id}, {$set: {slots: slots}}, cb);
  });
});

类似的东西。哈哈

这样称呼

Item.clearSlot(id, 2, function(err, updated) {

【讨论】:

  • 抱歉,但这并不是我搜索的内容。我需要将'slots'数组的一个元素设置为null,而不是将其重置为空白状态(不确定我是否解释得很好^^)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-30
  • 2020-07-16
  • 2017-01-30
  • 1970-01-01
  • 1970-01-01
  • 2019-05-16
  • 2018-05-04
相关资源
最近更新 更多