Эти примеры не делают то же самое ...
В примерах JS вы объявили объект mongo
> var mongo = db.things.findOne({name:"mongo"});
Затем вы изменили тот же объект , добавив type ...
> mongo.type = "database";
В примере с PHP вы объявили ДВА объекта ...
$a=array('_id'=>'test_a','field1'=>'anything');
$b=array('_id'=>'test_a','field2'=>'anything else');
Это похоже на выполнение следующих действий в оболочке JS ...
> 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 ...
<code><?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 "
";
?>
Примечание : я бы настоятельно рекомендовал вам не устанавливать свой собственный объект _id и вместо этого позволить водителю сделать это за вас, как я сделал в примере выше.