У меня есть следующая схема и код Mongoose:
Схема:
{
...
inv: {
type: Object,
default: {}
},
...
}
Код (версия 1), где targetData - это Mongoose Document, item - это String, а amount - это Number:
targetData.inv[item] = targetData.inv[item] - amount;
if (!targetData.inv[item]) delete targetData.inv[item];
await targetData.save();
Код (версия 2):
targetData.inv[item] = targetData.inv[item] - amount;
if (!targetData.inv[item]) targetData.inv[item] = undefined;
await targetData.save();
Проблема в том, что ни одна из этих попыток не удаляет targetData.inv[item] из документа. Моя цель - удалить элемент, например "thing", из вложенного документа. Например:
До:
{
...
inv: {
thing: 5
},
...
}
После:
{
...
inv: {},
...
}
Примечание. Когда число amount меньше, чем число 5 (в приведенном выше примере), код работает нормально. Если я удаляю все 5, тогда он не обновляется, он останется как 5.
Примечание 2: я использую Mongoose 5.3.15.
Как я могу этого добиться?
Обновлено: Похоже, это происходит, только если inv имеет только 1 свойство. Наличие чего-то вроде inv: { thing: 5, anotherThing: 6 } отлично подойдет для ключевого слова delete.
@chridam Конкретно 0, да
Вы пробовали использовать метод set(): if (targetData.inv[item] === 0) targetData.set(`inv.${item}`, undefined, {strict: false} );?
@chridam Интересно, это работает. Не могли бы вы объяснить, почему это работает вместо других моих попыток в ответе? Спасибо!
Какую версию мангуста вы используете?
@chridam Update: если inv имеет несколько свойств, использование set() будет установлено как null, даже если я предоставлю undefined. Так что это работает, только если inv имеет одно свойство ...
@drinchev 5.3.15
@apxx последняя версия 5.4.1 (mongoosejs.com) Вы уверены? Ваш код работает (по крайней мере, часть с delete item.inv.foo. Он просто присваивает null значение в базе данных mongo. В любом случае const item = new Item( { inv : { foo : "bar" } } ); item.save().then( item => { console.info( item ); delete item.inv.foo; item.save().then( item => { console.info( item ); } ); } );
@drinchev Простите, проверил не то, у меня 5.3.15
@apxx тоже работает. gist.github.com/drinchev/9957a01d1db60c3cf4cdeb8a17e20fd1. Это мой код.
@drinchev Это странно ... Вот то, что я пробовал, и его результат hastebin.com/yaqukupipa.js - Здесь что-то не так



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Выяснил, в чем дело. Все, что мне нужно было сделать, это вручную сообщить Mongoose, что inv был изменен с помощью targetData.markModified("inv"). Документы. Это связано с тем, что SchemaType имеет значение Смешанный (Object)
Я знаю, что вы решили проблему, но у меня есть идея. Обычно в этой ситуации я хотел бы получить документ, пройтись по объекту, найти элемент, удалить его и снова сохранить документ. Я поступаю наивно.
Не уверен, что вы имеете в виду. У вас есть пример?
Каковы фактические условия для удаления собственности? Это когда значение меньше или равно
0, а затем удалить?