Eliminar una clave de un documento de MongoDB usando Mongoose


103

Estoy usando la biblioteca Mongoose para acceder a MongoDB con node.js

¿Existe alguna forma de eliminar una clave de un documento ? es decir, no solo establecer el valor en nulo, sino eliminarlo.

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
Pensé que lo había encontrado, pero después de algunas pruebas: probablemente no. Sin embargo, esto tiene una buena discusión sobre el tema. groups.google.com/group/mongoose-orm/browse_thread/thread/…
Stephen

LOL no importa, supongo que esta fue tu publicación!
Stephen

Respuestas:


168

En las primeras versiones, habría tenido que desplegar el controlador node-mongodb-native. Cada modelo tiene un objeto de colección que contiene todos los métodos que ofrece node-mongodb-native. Entonces puede hacer la acción en cuestión de esta manera:

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

Desde la versión 2.0 puedes hacer:

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

Y desde la versión 2.4, si ya tienes una instancia de un modelo puedes hacer:

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

Esto se ha solucionado en Mongoose 2.X, por lo que puede dejar la colección fuera.
staackuser2

4
De cualquier uso User.update({ _id: id }, { $unset: { field: 1 }}, callback)o si tiene una instancia de documento, establecer la ruta a indefinido y guardarla:doc.field = undefined; doc.save()
aaronheckmann

25
Solo una nota de que si está tratando de eliminar una propiedad antigua que ya no está definida en su esquema, debe hacerlodoc.set('field', undefined)
evilcelery

3
¿qué pasa con la eliminación doc.field.foo?
chovy

28
@evilcelery doc.set('field', undefined)puede no ser suficiente ya que el modo estricto (predeterminado) no permite establecer campos que ya no están en el esquema. doc.set('field', undefined, { strict: false })funcionó bien.
Alexander Link


30

Yo uso mangosta y el uso de cualquiera de las funciones anteriores me hizo el requisito. La función compila sin errores, pero el campo aún permanecería.

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

hizo el truco para mí.


Al votar a favor de esta útil respuesta, lástima que @ alexander-link no la convirtió en una respuesta en 2015 ( stackoverflow.com/questions/4486926/… )
w00t

1
Gracias por su respuesta, para mí, ¡las otras soluciones no funcionaron para objetos anidados en matrices!
BenSower

@BenSower Este también fue mi caso. Solo esta solución funcionó bien porque tuve que eliminar un campo con una matriz después de encontrar la identificación de un documento específico
Luis Febro

Tenga en cuenta que la cadena es una ruta a la clave. Por lo tanto, si el objeto que desea eliminar está anidado, debe acceder a él. ¡Esta respuesta resolvió mi problema!
Bradyo

8

En la sintaxis de mongo para eliminar alguna clave, debe hacer lo siguiente:

{ $unset : { field : 1} }

En Mongoose parece lo mismo.

Editar

Mira este ejemplo.


¿Puede aclarar esta respuesta y dar un ejemplo de código que se relacione con el código de ejemplo anterior?
Daniel Beardsley

lo siento, pero no tengo experiencia en mangosta. La sintaxis anterior es la sintaxis mongo, así que supongo que el controlador para cualquier idioma lo admite. Encontré un ejemplo, compruébalo en mi respuesta.
Andrew Orsich

1

¿Podría ser esto un problema secundario como usar

function (user)

en vez de

function(err, user)

para la devolución de llamada del hallazgo? Solo trato de ayudar con esto, ya que ya tenía el caso.


1

El documento Mongoose NO es un objeto simple de JavaScript y es por eso que no puede usar el operador de eliminación (o unsetde la biblioteca 'lodash').

Sus opciones son establecer doc.path = null || undefined o usar el método Document.toObject () para convertir el documento de mangosta en un objeto simple y desde allí usarlo como de costumbre. Leer más en mongoose api-ref: http://mongoosejs.com/docs/api.html#document_Document-toObject

El ejemplo se vería así:

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

1

Tratar:

User.findOne({}, function(err, user){
  // user.key_to_delete = null; X
  `user.key_to_delete = undefined;`

  delete user.key_to_delete;

  user.save();
});

0

el problema con todas estas respuestas es que funcionan para un campo. por ejemplo, digamos que quiero eliminar todos los campos de mi documento si fueran una cadena vacía "". Primero debe verificar si el campo es una cadena vacía y ponerlo en $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

si desea eliminar una clave de la colección, pruebe este método. esto funcionó para mí

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.