Mongoose - удалить свойство из субдокумента

У меня есть следующая схема и код 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.

Каковы фактические условия для удаления собственности? Это когда значение меньше или равно 0, а затем удалить?

chridam 29.12.2018 20:57

@chridam Конкретно 0, да

APixel Visuals 29.12.2018 20:59

Вы пробовали использовать метод set(): if (targetData.inv[item] === 0) targetData.set(`inv.${item}`, undefined, {strict: false} );?

chridam 29.12.2018 21:13

@chridam Интересно, это работает. Не могли бы вы объяснить, почему это работает вместо других моих попыток в ответе? Спасибо!

APixel Visuals 29.12.2018 21:15

Какую версию мангуста вы используете?

drinchev 29.12.2018 21:17

@chridam Update: если inv имеет несколько свойств, использование set() будет установлено как null, даже если я предоставлю undefined. Так что это работает, только если inv имеет одно свойство ...

APixel Visuals 29.12.2018 21:18

@drinchev 5.3.15

APixel Visuals 29.12.2018 21:19

@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 29.12.2018 21:21

@drinchev Простите, проверил не то, у меня 5.3.15

APixel Visuals 29.12.2018 21:23

@apxx тоже работает. gist.github.com/drinchev/9957a01d1db60c3cf4cdeb8a17e20fd1. Это мой код.

drinchev 29.12.2018 21:25

@drinchev Это странно ... Вот то, что я пробовал, и его результат hastebin.com/yaqukupipa.js - Здесь что-то не так

APixel Visuals 29.12.2018 21:36
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
11
226
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Выяснил, в чем дело. Все, что мне нужно было сделать, это вручную сообщить Mongoose, что inv был изменен с помощью targetData.markModified("inv"). Документы. Это связано с тем, что SchemaType имеет значение Смешанный (Object)

Я знаю, что вы решили проблему, но у меня есть идея. Обычно в этой ситуации я хотел бы получить документ, пройтись по объекту, найти элемент, удалить его и снова сохранить документ. Я поступаю наивно.

Не уверен, что вы имеете в виду. У вас есть пример?

APixel Visuals 30.12.2018 01:02

Другие вопросы по теме