MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Mongo convertit le document intégré en tableau

Vous devez toujours itérer sur le contenu, mais à la place, vous devriez réécrire en utilisant des opérations en masse :

Soit pour MongoDB 2.6 et supérieur :

var bulk = db.collection.initializeUnorderedBulkOp(),
    count = 0;

db.collection.find({ 
   "$where": "return !Array.isArray(this.experience)"
}).forEach(function(doc) {
    bulk.find({ "_id": doc._id }).updateOne({
        "$set": { "experience": [doc.experience["0"]] }
    });
    count++;

    // Write once in 1000 entries
    if ( count % 1000 == 0 ) {
        bulk.execute();    
        bulk = db.collection.initializeUnorderedBulkOp();
    }
})

// Write the remaining
if ( count % 1000 != 0 )
    bulk.execute();

Ou dans les versions modernes de MongoDB 3.2 et supérieures, le bulkWrite() la méthode est préférée :

var ops = [];

db.collection.find({ 
   "$where": "return !Array.isArray(this.experience)"
}).forEach(function(doc) {
   ops.push({
       "updateOne": {
           "filter": { "_id": doc._id },
           "update": { "$set": { "experience": [doc.experience["0"]] } }
       }
   });

   if ( ops.length == 1000 ) {
       db.collection.bulkWrite(ops,{ "ordered": false })
       ops = [];
   }
})

if ( ops.length > 0 )
    db.collection.bulkWrite(ops,{ "ordered": false });

Ainsi, lors de la réécriture dans la base de données sur un curseur, les opérations d'écriture en bloc avec un ensemble "non ordonné" sont la voie à suivre. Il s'agit d'une seule écriture/réponse par lot de 1000 requêtes, ce qui réduit considérablement les frais généraux, et "non ordonné" signifie que les écritures peuvent se produire en parallèle plutôt que dans un ordre en série. Tout cela le rend plus rapide.