我遇到了一个有趣的问题,尝试使用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:null
值对于订单逻辑目的很重要。
所以,让我们想象一下我得到的第一个项目:
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 ?
});
});
});
因此即使null
工作,ID也不会设置为save
。我真的没有得到它。我需要这么多解释!提前谢谢。
答案 0 :(得分:3)
您似乎需要将该元素明确标记为已修改或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) {
...
答案 1 :(得分:1)
请改为尝试:
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) {