2017-07-07 7 views
1

Je tente d'importer des données à partir d'une source externe dans mon mongodb avec PHP. Chaque ligne des données externes est un document mongodb. Chaque rangée a un identifiant unique appelé uid.Upsert de nombreux documents dans MongoDB et php

Maintenant j'essaye ce qui suit: Je veux insérer une nouvelle rangée, si aucun document avec le même uid n'existe déjà (Upsert).

Pour un seul document, je ferais ce qui suit:

$collection->updateOne(
    ["uid" => "2"], 
    ['$set' => [ 
     "newfield" => date("Y-m-d H:i:s"), 
     "name" => "Test" 
    ]], 
    [ 
     "upsert" => true 
    ] 
); 

Étape 1:

Est-il possible de passer outre le document complet, non seulement définir des champs spécifiques? Quelque chose comme ceci:

$collection->updateOne(
    ["uid" => "2"], 
    [ 
     "newfield" => date("Y-m-d H:i:s"), 
     "name" => "Test" 
    ], 
    [ 
     "upsert" => true 
    ] 
); 

Ce ne fonctionne pas, car je reçois une erreur First key in $update argument is not an update operator. Comment faire?

Étape 2

Pour des raisons de performance, je veux utiliser la fonction insertMany ou updateMany en vrac upsert plusieurs documents.

Mais quel filtre ai-je besoin pour updateMany:

$db->updateMany(
    [???????], 
    [ 
     "newfield" => date("Y-m-d H:i:s"), 
     "name" => "XXX" 
    ], 
    [ 
     "upsert" => true 
    ] 
); 
+0

https://meta.stackexchange.com/questions/39223/one-post-with-multiple-questions-or-multiple-posts#answer-39224 –

+0

Mais, fondamentalement, les deux questions sont connectées ensemble. Je ne peux pas résoudre la question 2 sans la question 1. – bernhardh

+0

Vous ne pouvez pas les résoudre, peu importe dans quel ordre. Sinon, vous ne demanderiez pas les deux à droite? Respecter les recommandations ne blessera pas, mais peut augmenter les chances d'obtenir une réponse. –

Répondre

0

Les questions sont totalement indépendantes.

Le premier:

Utilisation update avec multi: false (qui est par défaut) au lieu de updateOne. Le premier permet de replaces an existing document entirely.

La seconde:

updateMany ne fonctionne pas de cette façon. Il ressemble plus à update avec multi: true - il applique des opérations de mise à jour à tous les documents correspondant au filtre. Lorsqu'il est utilisé avec upsert: truethe filter fields should be uniquely indexed to avoid multiple upserts.

Si vous souhaitez effectuer plusieurs upserts avec des filtres individuels en une seule fois, vous pouvez utiliser bulk update:

$bulk = new MongoDB\Driver\BulkWrite(['ordered' => false]); 
$bulk->update(["uid" => "2"], [ 
    "newfield" => date("Y-m-d H:i:s"), 
    "name" => "Test" 
]]); 
$bulk->update(["uid" => "3"], [ 
    "newfield" => date("Y-m-d H:i:s"), 
    "name" => "Another Test" 
]]); 
$bulk->update(["uid" => "4"], [ 
    "newfield" => date("Y-m-d H:i:s"), 
    "name" => "One more Test" 
]]); 
$result = $manager->executeBulkWrite('db.collection', $bulk, $writeConcern); 

S'il vous plaît lire la page derrière le dernier lien pour les limites des opérations en vrac.