Видаліть ключ із документа MongoDB за допомогою Mongoose


103

Я використовую бібліотеку Mongoose для доступу до MongoDB за допомогою node.js

Чи є спосіб вилучити ключ з документа ? тобто не просто встановити значення null, а видалити його?

User.findOne({}, function(err, user){
  //correctly sets the key to null... but it's still present in the document
  user.key_to_delete = null;

  // doesn't seem to have any effect
  delete user.key_to_delete;

  user.save();
});

1
Я думав, що знайшов її, але після деяких тестів: напевно, ні. Але в цьому питанні є хороша дискусія. groups.google.com/group/mongoose-orm/browse_thread/thread/…
Стівен

LOL ніколи не думаю, я думаю, це був ваш пост!
Стівен

Відповіді:


168

У ранніх версіях вам потрібно було б випустити власний драйвер node-mongodb. Кожна модель має об'єкт колекції, який містить усі методи, які пропонує власний node-mongodb. Тож ви можете виконати спірну дію цим:

User.collection.update({_id: user._id}, {$unset: {field: 1 }});

З версії 2.0 ви можете:

User.update({_id: user._id}, {$unset: {field: 1 }}, callback);

А з версії 2.4, якщо у вас вже є примірник моделі, ви можете це зробити:

doc.field = undefined;
doc.save(callback);

Це було виправлено у Mongoose 2.X, тож ви можете залишити колекцію.
staackuser2

4
Або використовуйте, User.update({ _id: id }, { $unset: { field: 1 }}, callback)або якщо у вас є екземпляр документа, встановіть шлях до невизначеного та збережіть його:doc.field = undefined; doc.save()
aaronheckmann

25
Лише зауважте, що якщо ви намагаєтесь видалити стару властивість, яка більше не визначена у вашій схемі, вам потрібно це зробитиdoc.set('field', undefined)
evilcelery

3
як щодо видалення doc.field.foo?
chovy

28
@evilcelery doc.set('field', undefined)може бути недостатньо, оскільки суворий режим (за замовчуванням) не дозволяє встановлювати поля, які більше не є в схемі. doc.set('field', undefined, { strict: false })добре працював.
Олександр Лінк

56

Ви хочете зробити це:

User.findOne({}, function(err, user){
  user.key_to_delete = undefined;
  user.save();
});

3
Це просто встановить його на нуль - не те, що просить ОП.
Ян Генрі

25
З версії 2.4.0, якщо встановити ключ документа на невизначений, він передасть $ unset mongodb aaronheckmann.posterous.com/mongoose-240
Джеймс Мур

30

Я використовую мангуст і використання будь-якої з перерахованих вище функцій зробило мені вимогу. Функція компілює вільну помилку, але поле все одно залишатиметься.

user.set('key_to_delete', undefined, {strict: false} );

зробив трюк для мене.


Upvoting цей відповідь, занадто погано @ Олександро-посилання не роблять його відповідь ще в 2015 році ( stackoverflow.com/questions/4486926 / ... )
w00t

1
Дякую за вашу відповідь, для мене інші рішення не спрацювали для об’єктів, вкладених у масиви!
BenSower

@BenSower Це був і мій випадок. Тільки це рішення спрацювало добре, оскільки мені довелося видалити поле з масивом після пошуку ідентифікатора конкретного документа
Луїс Фебро

Зауважте, що рядок - це шлях до ключа. Отже, якщо об’єкт, який ви хочете видалити, вкладений, ви повинні до нього прокласти шлях. Ця відповідь вирішила мою проблему!
Брейдіо

8

У синтаксисі mongo для видалення ключа потрібно зробити наступне:

{ $unset : { field : 1} }

Здається, у Мангуста те саме.

Редагувати

Перевірте цей приклад.


Чи можете ви уточнити цю відповідь і навести приклад коду, який стосується наведеного вище коду?
Даніель Бердслі

Вибачте, але я не маю на увазі мангуста. Вищий синтаксис - це синтаксис монго, тому я думаю, що драйвер для будь-якої мови підтримує це. Я знайшов якийсь приклад, перевірте це у своїй відповіді.
Андрій Орсич

1

Чи може це бути побічною проблемою, як використання

function (user)

замість

function(err, user)

для зворотного виклику знахідки? Просто намагаюся допомогти у цьому, як я вже мав справу.


1

Документ Mongoose НЕ є звичайним об’єктом javascript, і тому ви не можете використовувати оператор видалення (або unsetз бібліотеки 'lodash').

Ваші варіанти - встановити doc.path = null || невизначено або використовувати метод Document.toObject (), щоб перетворити мангустний документ на звичайний об'єкт і звідти використовувати його як завжди. Детальніше читайте у мангустному api-ref: http://mongoosejs.com/docs/api.html#document_Document-toObject

Приклад виглядатиме приблизно так:

User.findById(id, function(err, user) {
    if (err) return next(err);
    let userObject = user.toObject();
    // userObject is plain object
});


0

проблема всіх цих відповідей полягає в тому, що вони працюють для одного поля. Наприклад, скажімо, що я хочу видалити всі поля з мого документа, якщо вони були порожнім рядком "". Спочатку слід перевірити, чи є поле порожнім рядком, покладіть його на $unset:

function unsetEmptyFields(updateData) {
  const $unset = {};
  Object.keys(updatedData).forEach((key) => {
    if (!updatedData[key]) {
      $unset[key] = 1;
      delete updatedData[key];
    }
  });
  updatedData.$unset = $unset;

  if (isEmpty(updatedData.$unset)) { delete updatedData.$unset; }

  return updatedData;
}

function updateUserModel(data){
const updatedData = UnsetEmptyFiled(data);

    const Id = "";
    User.findOneAndUpdate(
      { _id: Id },
      updatedData, { new: true },
    );
}

0

якщо ви хочете вилучити ключ із колекції, спробуйте цей метод. це працювало для мене

 db.getCollection('myDatabaseTestCollectionName').update({"FieldToDelete": {$exists: true}}, {$unset:{"FieldToDelete":1}}, false, true);

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.