Estoy construyendo una api utilizando Nodo, MongoDB y la Mangosta. Una cosa que me molesta es que parece que no puede establecer varios campos a la vez:

app.put('/record/:id', function(req, res) {
  Record.findById(req.params.id, function(err, doc) {
    if (!err) {
      doc.update(req.params);
      doc.save();
...

Sin embargo, parece que tienes que salir de la consulta de actualización y ejecutar en el Modelo de objeto en lugar de en el objeto de documento. A menos que usted desea asignar propiedades individuales y ejecutar save() en la final.

¿Hay alguna forma de lograr esto sin tener que escribir un Mongo consulta?

OriginalEl autor James | 2012-02-20

5 Comentarios

  1. 12

    jsaak la respuesta es buena, pero no funciona para objetos anidados. He elaborado en su respuesta mediante la búsqueda y configuración de objetos anidados.

    He añadido estas funciones a un utility.js archivo

    var _ = require('underscore');
    
    exports.updateDocument = function(doc, SchemaTarget, data) {
        for (var field in SchemaTarget.schema.paths) {
           if ((field !== '_id') && (field !== '__v')) {
                var newValue = getObjValue(field, data);
                console.log('data[' + field + '] = ' + newValue);
                if (newValue !== undefined) {
                    setObjValue(field, doc, newValue);
              }  
           }  
        }
        return doc;
    };
    
    function getObjValue(field, data) {
        return _.reduce(field.split("."), function(obj, f) { 
            if(obj) return obj[f];
        }, data);
    }
    
    function setObjValue(field, data, value) {
      var fieldArr = field.split('.');
      return _.reduce(fieldArr, function(o, f, i) {
         if(i == fieldArr.length-1) {
              o[f] = value;
         } else {
              if(!o[f]) o[f] = {};
         }
         return o[f];
      }, data);
    }

    implementar como:

    var util = require('./utility');
    
    app.put('/record/:id', function(req, res) {
      Record.findById(req.params.id, function(err, doc) {
        if (!err) {
          utils.updateDocument(doc, Record, req.params);
          doc.save();
        ...
    En retrospectiva, no es necesario el uso de subrayado del lib .reducir
    Muy buen método!
    Yo había estado tratando de actualizar un elemento en un array de objetos. Por alguna razón el markModified método no funcionaría. Su método funcionaba de maravilla.
    Gracias @justin! Haces que mi día! Gran respuesta, @james debe ser marcado como ‘respuesta correcta’. Su respuesta ha solucionado mi problema de actualización de objetos anidados. Sólo tengo una anotación. Se están definiendo los ‘util’ como la variable que contiene los métodos y, de ahora en adelante, usted lo está utilizando como ‘utils’.
    Gracias,es increible pero tengo que hacer una pregunta si el campo consta de updatedDate entonces tengo que actualizar la fecha también en el esquema de updatedDate= new Date (), a continuación, cómo hacerlo y dónde agregar esto utility.js archivo

    OriginalEl autor justin

  2. 8

    la actualización directa no se recomienda de acuerdo a este documento:
    http://mongoosejs.com/docs/2.7.x/docs/updating-documents.html

    he resuelto así:

      Book.findOne({isbn: req.params.isbn}, function (err, book){
         if (err) {
            res.send(422,'update failed');
         } else {
            //update fields
            for (var field in Book.schema.paths) {
               if ((field !== '_id') && (field !== '__v')) {
                  if (req.body[field] !== undefined) {
                     book[field] = req.body[field];
                  }  
               }  
            }  
            book.save();
         }
      });
    Funciona perfecto, he hecho una función genérica de este para usar en todas partes:
    Funciona muy bien hasta que haya objetos anidados. justin tiene el más completo método.
    imagina el caso cuando un campo está expresamente a la izquierda vacía ( desactivada ), no se actualiza con el código, y el valor antiguo se mantiene.

    OriginalEl autor jsaak

  3. 2

    Para aclarar la cuestión, parece que usted está tomando los parámetros de la Petición y los uso para encontrar y actualizar el documento dado.

    ¿Hay alguna forma de lograr esto sin tener que escribir un Mongo consulta?

    La respuesta obvia es para actualizar el Modelo de objeto con el valor de la Solicitud. Que es lo que sugieren…

    A menos que usted desea asignar propiedades individuales y ejecutar save() en la final.

    Pero parece que usted no quiere hacer esto? Suena como que usted desea actualizar el Modelo de objetos directamente desde el objeto Request?

    Usted puede hacer esto si usted realmente desea. Usted acaba de bucle a través de req.params y establecer el doc valores donde corresponda.

    for(var i in req.params) {
      if(req.params[i] != doc[i]){
        doc[i] = req.params[i];
      }
    }

    Que debería ser tan sencillo como esto. Sin embargo, usted sólo que desee hacer esto si usted tiene un montón de código de validación en el Modelo de objetos. El punto central del Modelo es que usted no quiere quedar al azar de los datos en la DB. La línea de arriba se genéricamente «conjunto» los valores correctos, pero que definitivamente se necesita para incluir código para la autenticación, autorización y validación de alrededor de simple for bucle.

    OriginalEl autor Gates VP

  4. 2

    trate de la actualización de la colección, sin encontrar, como este

    Record.update({_id:req.params.id}, {$set: { field: request.field }}, {upsert: true}, function(err{...})

    La opción upsert crear el documento si no existe.

    Me sorprendió!, mongoError: máxima de la pila de llamadas supera problema resuelto con la solución

    OriginalEl autor pepo

Dejar respuesta

Please enter your comment!
Please enter your name here