8

大家。我爱漫画。现在我也学会爱蒙戈了:-)

有一个关于如何使用 save() 来更新 MongoDB PHP 集合中的现有文档的解释?但我无法将其应用于 PHP 的“现实”:-)

> 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"}

这是我的测试代码:

<?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);
?>

事实上,在 PHP 示例中 save() 覆盖了对象,而在 JS 示例中它更新了它。我希望我可以像在 JS 中一样在 PHP 中重现。

提前致谢。

4

1 回答 1

12

这些例子没有做同样的事情......

在 JS 示例中,您声明了对象mongo

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

然后,您修改了同一个对象以添加类型...

> mongo.type = "database";

在 PHP 示例中,您声明了两个对象...

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

这就像在 JS shell 中执行以下操作...

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

所以苹果是与橙子不同的对象/文档......因此,当您运行save()并传递 NEW 对象时,它会完全覆盖旧对象。

您的update()工作正常,因为您搜索了对象...

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

然后对该对象运行更新;传递新字段而不是传递一个新对象来替换它......

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

在 JS 示例中,您只有一个对象,因此它基本上将其附加到更新而不是替换它。

正确的 PHP 代码

以下 PHP 将复制您在 JS shell 中所做的事情......

<?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>";

?>

注意:我强烈建议您不要设置自己的对象_id,而是让驱动程序为您完成,就像我在上面的示例中所做的那样。

于 2011-01-02T03:37:53.890 回答