2011-01-01 11 views
8

alle. Ich liebe Manga. Und jetzt lerne ich auch, Mongo zu lieben :-)MongoDB: Verwenden Sie save(), um ein vorhandenes Dokument in einer Sammlung zu aktualisieren

Gibt es eine Erklärung von how to use save() to update an existing document in a collection in MongoDB PHP? aber ich konnte es nicht auf die „Realität“ PHP gelten :-)

> var mongo = db.things.findOne({name:"mongo"}); 
> print(tojson(mongo)); 
{"_id" : "497dab624ee47b3a675d2d9c" , "name" : "mongo"} 
> mongo.type = "database"; 
database 
> db.things.save(mongo); 
> db.things.findOne({name:"mongo"}); 
{"_id" : "497dab624ee47b3a675d2d9c" , "name" : "mongo" , "type" : "database"} 

Hier ist mein Testcode:

<?php 
$a=array('_id'=>'test_a','field1'=>'anything'); 
$b=array('_id'=>'test_a','field2'=>'anything else'); 

$m=new Mongo(); 
$c=$m->db->test; 
$c->save($a); 
$c->save($b);//overwrites the previous record 

/* 
//With update() it works fine 
$filter=array('_id'=>'test_a'); 
$update=array('$set'=>array('field2'=>'anything else')); 
$c->update($filter,$update); 
//$c->save($filter,$update);//Also tried... 
*/ 

$f=$c->find(); 
echo $f->count()." found \n"; 
$i=iterator_to_array($f);//mongo cursos iterator 
$m->close();//disconnect mongo 

print_r($i); 
?> 

Tatsache ist, dass in der PHP-Beispiel speichern() überschreibt das Objekt während Im JS-Beispiel wird es aktualisiert. Ich wünschte, ich könnte in PHP das gleiche wie in JS reproduzieren.

Vielen Dank im Voraus.

+0

In http://www.mongodb.org/display/DOCS/Updating#Updating-ModifierOperations heißt es, dass "save() ein upsert macht, wenn x ein _id Feld hat (x ist ein JSON style Objekt und upsert bedeutet update falls vorhanden; einfügen falls fehlend) ". – Roger

+0

Ich sehe nicht, was das Problem ist, machen die JS- und PHP-Beispiele nicht dasselbe? Sagen Sie uns, was Sie erwarten. Erwarten Sie nicht, dass wir die Umgebung einrichten und Ihren Code ausführen, nur um die Ausgabe zu sehen. – Theo

+0

Danke für die Antwort. Wenn Sie das PHP-Beispiel ausführen, sehen Sie, dass save() das Objekt überschreibt, während es im JS-Beispiel aktualisiert wird. Ich wünschte, ich könnte in PHP das gleiche wie in JS reproduzieren. – Roger

Antwort

12

Diese Beispiele sind die gleiche Sache nicht zu tun ...

In den JS Beispiele erklärt das Objekt Mongo

> var mongo = db.things.findOne({name:"mongo"}); 

Dann Sie verändert die gleichen Objekt hinzufügen typ ...

> mongo.type = "database"; 

In der PHP Beispiel erklären Sie zwei Objekte ...

$a=array('_id'=>'test_a','field1'=>'anything'); 
$b=array('_id'=>'test_a','field2'=>'anything else'); 

Die folgenden wie das Tun in dem JS-Shell ...

> var apples = db.things.findOne({name:"mongo"}); 
> var orange = db.things.findOne({type:"database"}); 

So Äpfeln wären ist ein anderes Objekt/Dokument aus Orangen ... daher, wenn Sie save() ausführen und übergeben Sie das neue Objekt es vollständig überschreibt das alte Objekt.

Ihr update() gut funktioniert, weil Sie für das Objekt gesucht ...

$filter=array('_id'=>'test_a'); 

Dann das Update auf lief die Objekt; das neue Feld es ...

$update=array('$set'=>array('field2'=>'anything else')); 
$c->update($filter,$update); 

In den JS Beispiele zu ersetzen, anstatt des Leitens eines neue Objekt übergeben musste man nur ein Objekt so es sie im Grunde auf dem Update beigefügten anstatt sie zu ersetzen.

korrekte PHP-Code

Die folgende PHP würde replizieren, was Sie in der JS Shell taten ...

<?php 

$connection = new Mongo(); 
$db = $connection->foo; 
$collection = $db->testing; 

// create new object & save 
$a = array('color'=>'red'); 
$collection->save($a); 

// add type = fruit to existing object & save 
$a['type'] = 'fruit'; 
$collection->save($a); 

// print out results. 
echo "<pre>"; 
var_dump($collection->findOne(array("color" => "red"))); 
echo "</pre>"; 

?> 

Hinweis: es für Sie tun würde ich stark empfehlen Sie nicht setzen Ihr eigenes Objekt _id s‘und der Fahrer statt lassen, wie ich im obigen Beispiel tat.

+0

Justin, danke für deine sehr brillante Antwort. In meinem Beispiel dachte ich, 'save()' würde nur mit dem Inhalt der Arrays gespeist werden, ohne zu berücksichtigen, dass '$ a' und' $ b' tatsächlich verschiedene Objekte waren. Tatsächlich gab es im JS-Beispiel vor dem "Upsert" eine 'findOne()'. Dieses 'findOne()' erscheint in PHP 'update()', wie Sie gut gesagt haben, in $ filter = array ('_ id' => 'test_a'); 'damit alles, was im nächsten Argument kommt, eingefügt wird in dieses Objekt. Danke für dein letztes Beispiel, es war perfekt. – Roger

+0

Und ich füttere Mongo mit meiner einzigen '_id', um mich nicht zu wiederholen, denn ich brauche eine einzigartige und einfache Möglichkeit, einen Wert zu identifizieren, um zukünftige Updates zu machen. Es war nur natürlich für mich, das '_id' Feld zu verwenden. Wenn es jedoch einen guten Grund dafür gibt, dies nicht zu tun, würde ich es gerne in ein anderes Feld legen und Mongo seinen eigenen Weg bestimmen lassen. Würden Sie mir bitte sagen, warum Sie empfehlen, das Feld '_id' nicht zu verwenden? – Roger

+0

Großartig! Wenn ich Ihre Frage beantwortet habe, markieren Sie diese bitte als "Antwort", so dass sie das große grüne Häkchen daneben hat! –

Verwandte Themen