2013-02-08 18 views
24

Ho un array nel mio documento modello. Vorrei eliminare gli elementi di quell'array in base a una chiave fornita e quindi aggiornare MongoDB. È possibile?Mangano cancella elemento array nel documento e salva

Ecco il mio tentativo:

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

var favorite = new Schema({ 
    cn: String, 
    favorites: Array 
}); 

module.exports = mongoose.model('Favorite', favorite, 'favorite'); 

exports.deleteFavorite = function (req, res, next) { 
    if (req.params.callback !== null) { 
     res.contentType = 'application/javascript'; 
    } 
    Favorite.find({cn: req.params.name}, function (error, docs) { 
     var records = {'records': docs}; 
     if (error) { 
      process.stderr.write(error); 
     } 
     docs[0]._doc.favorites.remove({uid: req.params.deleteUid}); 

     Favorite.save(function (error, docs) { 
      var records = {'records': docs}; 
      if (error) { 
       process.stderr.write(error); 
      } 
      res.send(records); 

      return next(); 
     }); 
    }); 
}; 

Finora trova il documento, ma la rimozione né salvare opere.

risposta

51

È anche possibile eseguire l'aggiornamento direttamente in MongoDB senza caricare il documento e modificarlo tramite codice. Utilizzare i $pull o $pullAll operatori per rimuovere l'elemento dalla matrice:

Favorite.update({cn: req.params.name}, { $pullAll: {uid: [req.params.deleteUid] } }) 

http://docs.mongodb.org/manual/reference/operator/update/pullAll/

+2

Questo è molto meglio per le prestazioni. –

+1

Molto utile, grazie. – Nate

+1

Grazie ... ha funzionato – Dibish

5

Poiché i preferiti sono un array, è sufficiente unire e salvare il documento.

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

var favorite = new Schema({ 
    cn: String, 
    favorites: Array 
}); 

module.exports = mongoose.model('Favorite', favorite); 

exports.deleteFavorite = function (req, res, next) { 
    if (req.params.callback !== null) { 
     res.contentType = 'application/javascript'; 
    } 
    // Changed to findOne instead of find to get a single document with the favorites. 
    Favorite.findOne({cn: req.params.name}, function (error, doc) { 
     if (error) { 
      res.send(null, 500); 
     } else if (doc) { 
      var records = {'records': doc}; 
      // find the delete uid in the favorites array 
      var idx = doc.favorites ? doc.favorites.indexOf(req.params.deleteUid) : -1; 
      // is it valid? 
      if (idx !== -1) { 
       // remove it from the array. 
       doc.favorites.splice(idx, 1); 
       // save the doc 
       doc.save(function(error) { 
        if (error) { 
         console.log(error); 
         res.send(null, 500); 
        } else { 
         // send the records 
         res.send(records); 
        } 
       }); 
       // stop here, otherwise 404 
       return; 
      } 
     } 
     // send 404 not found 
     res.send(null, 404); 
    }); 
}; 
+0

Grazie per una risposta molto approfondita. – occasl

+3

se si tenta di rimuovere 2 elementi contemporaneamente, entrambi possono ottenere l'array, quindi modificarlo e il primo cambiamento salvato viene sovrascritto dal secondo. Preferirei andare con sth come questo http://stackoverflow.com/questions/16959099/how-to-remove-array-element-in-mongodb. – Maximosaic

29

La risposta controllato funziona ma ufficialmente nel MongooseJS ultimo, è necessario utilizzare tirare.

doc.subdocs.push({ _id: 4815162342 }) // added 
doc.subdocs.pull({ _id: 4815162342 }) // removed 

http://mongoosejs.com/docs/api.html#types_array_MongooseArray-pull

Stavo guardando che fino troppo.

Vedere la risposta di Daniel per la risposta corretta. Molto meglio.

0
keywords = [1,2,3,4]; 
doc.array.pull(1) //this remove one item from a array 
doc.array.pull(...keywords) // this remove multiple items in a array 

se si desidera utilizzare ... si dovrebbe chiamare 'use strict'; nella parte superiore del file js; :)

1

Questo funziona per me e davvero molto utile.

SubCategory.update({ _id: { $in: 
     arrOfSubCategory.map(function (obj) { 
      return mongoose.Types.ObjectId(obj); 
     }) 
    } }, 
    { 
     $pull: { 
      coupon: couponId, 
     } 
    }, { multi: true }, function (err, numberAffected) { 
     if(err) { 
      return callback({ 
       error:err 
      }) 
     } 
    }) 
}); 

Ho un modello il cui nome è SubCategory e voglio rimuovere Coupon da questa categoria Array. Ho una serie di categorie, quindi ho usato arrOfSubCategory. Quindi prendo ogni array di oggetti da questo array con la funzione map con l'aiuto dell'operatore $in.

Problemi correlati