MongoDB-PHP更新会覆盖现有内容 - 为什么?

时间:2012-09-14 10:10:53

标签: php mongodb

我在mongo db collection中有以下内容,

{ "_id" : ObjectId("5052f343381ef8bc10000011"), "first_name" : "Tadataka", "midle_name"  :      
"", "last_name" : "Yamada", "title" : "Independent Director", "biogra
phy" : "Dr. Tadataka Yamada, M.D., is Independent Director of Agilent Technologi
es Inc., ", "rank" : " ", "department" : " ", "current" : "true", "company_id" :     ObjectId("50072714b4a6deba100051d3"
) } }

当我尝试为少数字段更新上述内容并且如果不存在则插入新字段时,现有字段将被覆盖。这是我的代码,

$mycollection->update(array("_id" => $id), array('$set' => array("first_name" => $first_name, "updated_at" => $uat));

我得到的结果是

{ "_id" : ObjectId("5052f343381ef8bc10000011"), "first_name" : "Tadataka", "updated_at" : 134567894 }

而不是只更新值,我的整个内容都会被覆盖,而我却不知道。

2 个答案:

答案 0 :(得分:5)

试试这个

$mycollection->update(
            array("_id" => $id),
            array('$set' => array("first_name" => $first_name, "updated_at" => $uat)),
            array("upsert" => true)
);

答案 1 :(得分:3)

您分享的代码中的update()是正确的。由于您使用的是原子修饰符$set,因此没有理由覆盖给定_id的整个文档。以下脚本可以轻松地重现这一点,并输出示例文档,其first_name字段已更改并添加了updated_at字段:

<?php

$m = new Mongo();
$c = $m->test->foo;
$c->drop();

$document = array(
    '_id' => new MongoId('5052f343381ef8bc10000011'),
    'first_name' => 'Tadataka',
    'middle_name' => '',
    'last_name' => 'Yamada',
    'title' => 'Independent Director',
    'company_id' => new MongoId('50072714b4a6deba100051d3')
);

$c->insert($document);

$c->update(
    array('_id' => $document['_id']),
    array('$set' => array('first_name' => 'foobar', 'updated_at' => new MongoDate()))
);

var_dump($c->findOne());

如果你在本地运行,你应该看到:

array(7) {
  ["_id"]=>
  object(MongoId)#8 (1) {
    ["$id"]=>
    string(24) "5052f343381ef8bc10000011"
  }
  ["company_id"]=>
  object(MongoId)#9 (1) {
    ["$id"]=>
    string(24) "50072714b4a6deba100051d3"
  }
  ["first_name"]=>
  string(6) "foobar"
  ["last_name"]=>
  string(6) "Yamada"
  ["midle_name"]=>
  string(0) ""
  ["title"]=>
  string(20) "Independent Director"
  ["update_at"]=>
  object(MongoDate)#10 (2) {
    ["sec"]=>
    int(1347908855)
    ["usec"]=>
    int(551000)
  }
}

如果您分享了如何获得粘贴的最后结果,那可能会有所帮助,但您的更新查询肯定不应该归咎于此。

作为旁注,您可能希望为文档中的current字段使用正确的布尔值,而不是字符串"true"