8 votes

Mise à jour avec l'expression au lieu de la valeur

Je suis totalement novice en matière de MongoDB... Il me manque une étiquette "newbie", pour que les experts ne voient pas cette question.

J'essaie de mettre à jour tous les documents d'une collection à l'aide d'une expression. La requête que j'attendais pour résoudre ce problème était la suivante :

db.QUESTIONS.update({}, { $set: { i_pp : i_up * 100 - i_down * 20 } }, false, true);

Toutefois, cela donne lieu au message d'erreur suivant :

ReferenceError : i_up n'est pas défini (shell):1

En même temps, la base de données n'a pas eu de problème à manger celle-ci :

db.QUESTIONS.update({}, { $set: { i_pp : 0 } }, false, true);

Est-ce que je dois faire ça un document à la fois ou quelque chose comme ça ? Cela semble excessivement compliqué.

Mise à jour Merci à Sergio Tulentsev de m'avoir dit que ça ne marche pas. Maintenant, j'ai vraiment du mal à savoir comment faire. J'offre 500 Points de profit à l'âme secourable, qui peut écrire ceci d'une manière que MongoDB comprend. Si vous vous inscrivez sur notre forum Je peux y ajouter les points de profit sur votre compte.

6voto

mu is too short Points 205090

Je viens de tomber sur ceci en cherchant l'équivalent MongoDB du SQL de ce type :

update t
set c1 = c2
where ...

Sergio a raison de dire que vous ne pouvez pas faire référence à une autre propriété comme valeur dans une mise à jour directe. Cependant, db.c.find(...) renvoie un et ce curseur a un forEach méthode :

Les requêtes adressées à MongoDB renvoient un curseur, qui peut être itéré pour récupérer les données suivantes résultats. La manière exacte d'effectuer une requête varie en fonction du pilote de langue. Les détails ci-dessous se concentrent sur les requêtes effectuées à partir du shell MongoDB (c.-à-d. la commande mongo processus).

La coquille find() renvoie un objet curseur que nous pouvons ensuite itérer pour récupérer des documents spécifiques dans le résultat. Nous utilisons hasNext() y next() méthodes à cette fin.

for( var c = db.parts.find(); c.hasNext(); ) {
   print( c.next());
}

En outre, dans la coquille, forEach() peut être utilisé avec un curseur :

db.users.find().forEach( function(u) { print("user: " + u.name); } );

Donc vous pouvez dire des choses comme ça :

db.QUESTIONS.find({}, {_id: true, i_up: true, i_down: true}).forEach(function(q) {
    db.QUESTIONS.update(
        { _id: q._id },
        { $set: { i_pp: q.i_up * 100 - q.i_down * 20 } }
    );
});

pour les mettre à jour un par un sans quitter MongoDB.

Si vous utilisez un pilote pour vous connecter à MongoDB, il devrait y avoir un moyen d'envoyer une chaîne de caractères JavaScript dans MongoDB ; par exemple, avec le pilote Ruby, vous utiliseriez eval :

connection.eval(%q{
    db.QUESTIONS.find({}, {_id: true, i_up: true, i_down: true}).forEach(function(q) {
        db.QUESTIONS.update(
            { _id: q._id },
            { $set: { i_pp: q.i_up * 100 - q.i_down * 20 } }
        );
    });
})

Les autres langues devraient être similaires.

5voto

Sergio Tulentsev Points 82783

Vous ne pouvez pas utiliser d'expressions dans les mises à jour. Ou, plutôt, vous ne pouvez pas utiliser d'expressions qui dépendent des champs du document. Les expressions mathématiques simples et autonomes sont acceptables (par ex. 2 * 2 ).

Si vous voulez définir un nouveau champ pour tous les documents qui est une fonction d'autres champs, vous devez les parcourir en boucle et les mettre à jour manuellement. Les mises à jour multiples ne sont d'aucune utilité dans ce cas.

3voto

Igor Lesikov Points 31

Rha7 a donné une bonne idée, mais le code ci-dessus ne fonctionne pas sans définir une variable temporaire.

Cet exemple de code produit un calcul approximatif de l'âge (années bissextiles derrière la scène) sur la base du champ "anniversaire" et insère la valeur dans le champ approprié pour tous les documents qui n'en contiennent pas :

db.employers.find({age: {$exists: false}}).forEach(function(doc){
    var new_age = parseInt((ISODate() - doc.birthday)/(3600*1000*24*365));
    db.employers.update({_id: doc._id}, {$set: {age: new_age}});
});

3voto

//the only differnce is to make it look like and aggregation pipeline
db.table.updateMany({}, [{
      $set: {
        col3:{"$sum":["$col1","$col2"]}
      },
    }]
 )

0voto

Rha7 Points 93

Exemple pour supprimer le "00" du début d'une identification de l'appelant :

db.call_detail_records_201312.find(
    { destination: /^001/ }, 
    { "destination": true }
).forEach(function(row){
    db.call_detail_records_201312.update(
        { _id: row["_id"] },
        { $set: {
                destination: row["destination"].replace(/^001/, '1')
            }
        }
    )
});

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