4 votes

Mise à jour de plusieurs documents avec des valeurs différentes

J'utilise la fonction triable de l'interface utilisateur de Jquery ( source ) pour réorganiser les éléments. J'ai construit des callbacks personnalisés pour créer une liste de ces éléments. Ainsi, lorsque je déplace un élément, tous les éléments reçoivent un nouvel identifiant de position. Cela pourrait ressembler à ceci :

[{
    id_of_element_in_database: 12,
    new_position: 0
}, {
    id_of_element_in_database: 16,
    new_position: 1
}, {
    id_of_element_in_database: 14,
    new_position: 2
}]

J'envoie cette liste à mon back-end en faisant un simple Poste d'Ajax

$.post('/position', { data: list });

Route

router.post('/position', (req, res) => {
    console.log(req.body.data); // This prints the array of objects above.
});

Schéma

mongoose.Schema({
    id: Number,
    position: Number,
    ...
});

Maintenant, je n'arrive pas à trouver comment modifier efficacement la position de tous les documents. Créer une boucle merdique du tableau et faire de multiples requêtes à la base de données ne peut pas être la meilleure approche.

J'ai essayé ça ici et ça ne me semble pas correct.

for (let i in req.body.data) {
    collection.update({ id: req.body.data[i].id }, { position: req.body.data[i].position });

Il doit y avoir quelque chose d'autre que je puisse faire pour y parvenir. J'ai essayé de consulter Google sans succès.

3voto

chridam Points 3903

Vous pouvez essayer le bulkWrite API pour effectuer les mises à jour d'une meilleure manière, sans requêtes multiples au serveur :

var callback = function(err, r){
    console.log(r.matchedCount);
    console.log(r.modifiedCount);
}
// Initialise the bulk operations array
var ops = req.body.data.map(function (item) { 
    return { 
        "updateOne": { 
            "filter": { 
                "id": parseInt(item.id),
                "position": { "$ne": parseInt(item.position) }
            },              
            "update": { "$set": { "position": parseInt(item.position) } } 
        }         
    }    
});

// Get the underlying collection via the native node.js driver collection object
Model.collection.bulkWrite(ops, callback);

0voto

Devin McQueeney Points 655

Voici comment je l'ai fait avec Node.js :

var forEach = require('async-foreach').forEach;
var bulk = Things.collection.initializeOrderedBulkOp();

  Things.find({}).lean().execAsync(execSettings).then(function(resp){

    forEach(resp, function(template, index, arr) {

      var done = this.async();

      bulk.find({'_id': template._id}).update({$set: {_sid: generateShortId()}});
      bulk.execute(function (error) {
           done();                  
      });

    }, function(notAborted, arr){

        res.json({done: true, arr: arr.length});

    });

  });

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X