2017-07-07 68 views
1

我尝试从外部源导入数据到我的MongoDB与PHP。来自外部数据的每一行都是一个mongodb文档。每行都有一个称为uid的唯一标识。Upsert在MongoDB和php中的许多文档

现在我正在尝试以下操作:我想要插入一个新行,如果没有具有相同uid的文档已经存在(Upsert)。

对于一个单一的文件,我将做到以下几点:

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

第1步:

是否可以覆盖完整的文档,而不是仅仅设置特定的领域?类似这样的:

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

这是行不通的,因为我得到一个First key in $update argument is not an update operator错误。怎么做?

步骤2

出于性能方面的原因,我想用insertMany或updateMany功能来批量更新插入多个文档。

但是,过滤器,我需要为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

但基本上这两个问题都连接在一起。我不能解决问题2没有问题1. – bernhardh

+0

你无法解决它们,无论顺序如何。否则,你不会问这两个权利?尊重建议不会受到伤害,但可能会增加答案的机会。 –

回答

0

的问题是完全独立的。

第一:

使用updatemulti: false(这是默认值),而不是updateOne。前者允许replaces an existing document entirely

第二:

updateMany不以这种方式工作。它更像是updatemulti: true - 它将更新操作应用于与过滤器匹配的所有文档。与upsert: truethe filter fields should be uniquely indexed to avoid multiple upserts一起使用时。

如果你想一次过个别过滤器,以执行多个upserts,您可以使用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); 

请阅读页面的最后一个环节进行批量操作的局限性后面。