2016-12-30 2 views
1

Je veux copier les informations sur les prix dans mon document au tableau prices[].Comment copier en bloc un champ dans un premier objet de tableau et mettre à jour le document dans MongoDB?

var entitiesCol = db.getCollection('entities'); 
entitiesCol.find({"type": "item"}).forEach(function(item){ 
    item.prices = [ { 
     "value": item.price 
    }]; 
    entitiesCol.save(item); 
}); 

Cela prend trop de temps et certains champs ne sont pas mis à jour. J'utilise Mongoose côté serveur et je peux aussi l'utiliser.

Que puis-je faire pour cela?

+0

Quelle est votre version de Mongoose et MongoDB? – chridam

+0

MongoDB 3.2.11 Je suppose que – Burak

Répondre

1

Dans le shell mongo, vous pouvez utiliser la méthode bulkWrite() pour effectuer les mises à jour de manière rapide et efficace. Prenons l'exemple suivant:

var entitiesCol = db.getCollection('entities'), 
    counter = 0, 
    ops = []; 
entitiesCol.find({ 
    "type": "item", 
    "prices.0": { "$exists": false } 
}).snapshot().forEach(function(item){ 
    ops.push({ 
     "updateOne": { 
      "filter": { "_id": item._id }, 
      "update": { 
       "$push": { 
        "prices": { "value": item.price } 
       } 
      } 
     } 
    }); 
    counter++; 

    if (counter % 500 === 0) { 
     entitiesCol.bulkWrite(ops); 
     ops = []; 
    } 
}) 

if (counter % 500 !== 0) 
    entitiesCol.bulkWrite(ops); 

La variable counter est au-dessus là pour gérer vos mises à jour en vrac efficacement si votre collection est grande. Il vous permet de mettre en lots les opérations de mise à jour et envoie les écritures au serveur par lots de 500, ce qui vous donne de meilleures performances car vous n'envoyez pas toutes les requêtes au serveur, une fois sur 500 demandes. Pour les opérations en vrac, MongoDB impose default internal limit of 1000 opérations par lot et donc le choix de 500 documents est bon dans le sens où vous avez un certain contrôle sur la taille du lot plutôt que de laisser MongoDB imposer le défaut, c'est à dire pour des opérations plus importantes de l'ampleur de> 1000 documents.

+1

Devrais-je utiliser snapshot()? – Burak

+0

@Burak Oui, en effet, tant qu'il s'agit de collections non-protégées et gardez à l'esprit que 'snapshot()' ne garantit pas l'isolation de l'insertion ou des suppressions. – chridam

+0

Et si je ne veux pas pousser dans le tableau des prix? Je veux juste le définir. Parce que si je cours cela pour la deuxième fois, le tableau aura le prix en double – Burak