2014-05-23 9 views
1

Je veux ajouter à tous les documents myCollection un champ « série » avec un nombre entier de série, par exemple:Ajouter un champ dans tous les documents d'une collection existante (mongodb)?

{"_id" : "507f191e810c19239de098db", "name" : "John", "serie" : "1"} 
{"_id" : "507f191e810c19729de860ea", "name" : "Dave"}, "serie" : "2"} 
{"_id" : "507f191e810c19729de564ou", "name" : "Kate"}, "serie" : "3"} 
...... 

ObjectId (_id) n'est pas sexy pour afficher ou de se rappeler par Humains, donc Je veux le garder et ajouter un autre champ 'série' contenant des nombres simples, courts et uniques pour identifier chaque document, comme un numéro de série. J'ai donc essayé le script suivant, mais je suis la même valeur « serie » dans tous les docs:

for(var i=1; i < 543; i++){  
    db.myCollection.update({}, 
    { $set: {"serie": i}}, 
    { upsert:false, multi: true }); 
} 

Merci pour votre aide.

+0

Cette question est également beaucoup plus large que vous ne le pensez et n'est pas très clair pour votre objectif. Quel type d'ordre voulez-vous ajouter à ce champ croissant? Avez-vous pensé à la façon dont vous feriez une telle chose dans quelque chose comme une base de données SQL et comment croiriez-vous que le processus serait différent ici? Etes-vous conscient que la valeur '_id' que vous affichez ici est à la fois une clé primaire de valeurs uniques et monotone (toujours croissante)? –

+0

@NeilLunn, Désolé de ne pas être clair, j'ai édité ma question, merci – user2981029

Répondre

5

Le problème avec ce que vous faites ici est essentiellement la partie multi: true de votre déclaration. Essentiellement, vous dites mettre à jour "tout" avec ce numéro, 543 fois.

Pour obtenir un nombre croissant faire:

var i = 1; 
db.myCollection.find().forEach(function(doc) { 
    db.myCollection.update(
     { "_id": doc._id }, 
     { "$set": { "serie": i } } 
    ); 
    i++; 
) 

Ou encore plus rapide avec des lots de MongoDB 2.6 et au-delà

var i = 1; 

var cmd = { 
    "update": "myCollection", 
    "updates": [] 
}; 

db.myCollection.find().forEach(function(doc) { 

    cmd.updates.push({ 
     "q": { "_id": doc._id }, 
     "u": { "$set": { "serie": i } } 
    }); 

    if (batch.length % 500 == 0) { 
     db.runCommand(cmd); 
     cmd.updates = []; 
    } 
    i++; 

}); 

if (cmd.updates.length > 0) 
    db.runCommand(cmd); 

Ainsi, non seulement plus rapide en raison de ne pas tirer la reconnaissance d'écriture sur chaque mise à jour mais aussi parce qu'elle envoie des mises à jour dans des tailles de lots de 500 à la fois.

1

Merci, je l'ai, je viens d'ajouter NumberInt (i) à votre réponse pour obtenir { "serie": "1"} au lieu de { "serie": "1.00000"}

var i = 1 
db.myCollection.find().forEach(function(doc) { 
    db.myCollection.update(
     { "_id": doc._id }, 
     { "$set": { "serie": NumberInt(i)} } 
    ); 
    i++; 
    }) 

Merci Neil pour votre aide

Questions connexes