2017-07-07 47 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); 

請閱讀頁面的最後一個環節進行批量操作的侷限性後面。