2011-11-23 4 views
0

Ce que je veux:

  • chercher des documents
  • pour chaque document, définir un champ:
    • changement, si elle existe
    • ajouter, si elle ne

Ce que je fais:

// fresh data 
print_r(iterator_to_array($collection->find()->limit(2))); 

// query 
$docs = $collection->find()->limit(2); 
// fetch 
foreach ($docs AS $id => $doc) { 
    // update 
    $collection->update(array('_id' => $doc['_id']), array(
    '$set' => array(
     'existing_field' => 'x', 
     'new_field' => 'y', 
    ), 
), array('multiple' => false)); 
} 

// verify 
print_r(iterator_to_array($collection->find()->limit(2))); 

Pourquoi ne pas faire quoi que ce soit? Le champ existant n'est pas modifié et le nouveau champ n'est pas ajouté. La condition est peut-être fausse?

PS. Le code complet (avec beaucoup d'ordure entre les deux): http://pastebin.com/CNfCVxex
lignes 33 - 37 - De nouvelles données
lignes 63-76 - requête, chercher & mise à jour
lignes 79-80 - vérifier

Répondre

1

Vous n'êtes pas familier avec le pilote que vous utilisez ici, mais à partir de votre description, vous pouvez obtenir ce que vous voulez dans une seule base de données, pas besoin d'aller chercher/boucler/mettre à jour

L'opérateur $ set va insérer ou mettre à jour un champ selon qu'il existe ou non.

db.Collection.update({}, { $set : { "myfield" : "x" } }, false, true) 

Ce qui précède que le champ « MyField » dans tous les documents de la collection à « x », ou si elle existe déjà, il changerait la valeur de « x ». Est-ce ce que vous voulez accomplir?

+0

J'utilise PHP. Impossible de tout mettre à jour en même temps, car les mises à jour sont différentes. Je pense que le '$ set' ferait ce que je veux, mais pour une raison quelconque ce n'est pas: pas de changement. Votre exemple n'inclut pas non plus le 'limit (2)' btw. – Rudie

+0

Vous pouvez définir deux champs avec $ set. Je ne pense pas vraiment comprendre ce que vous essayez d'accomplir. Vous essayez de définir le champ «a» si le champ «a» existe, et si vous ne définissez pas le champ «b», le document ne contiendra pas «a»? – Joe

+0

J'essaie de faire exactement cela, mais ça ne marchera pas. Si je passe l'objet de mise à jour sans le '$ set' (' {"existing_field": "x", "new_field": "y"} ') le document entier est mis à jour (et remplacé, comme les spécifications le disent. J'utilise '$ set', rien ne se passe! Pf? – Rudie

0

Je suppose que vous devez convertir la chaîne $doc['_id'] en MongoId en utilisant new MongoId. Voir l'exemple en bas de cette page: http://www.php.net/manual/en/class.mongoid.php

+0

' $ doc ['_ id'] instanceof MongoId', pas Je ne pense pas que 'new MongoId ($ row ['_ id'] -> {'$ id'})' est nécessaire. (J'ai essayé et cela n'a pas d'importance.) Sans '$ set', le mises à jour du document (mais est complètement remplacé). . – Rudie

+0

Activez la journalisation détaillée et examinez ce qui est réellement transmis à MongoDB. –

+0

Votre mise à jour semble également avoir un tableau supplémentaire enroulé autour de la commande $ set, pourquoi? Cela ne ferait-il pas le document de mise à jour '{{$ set: {'existing_field': 'x', 'new_field': 'y'}}' '? –

Questions connexes