简体   繁体   English

在MongoDB和php中更新许多文档

[英]Upsert many documents in MongoDB and php

I try to import data from an external source into my mongodb with php. 我尝试使用php将数据从外部源导入到mongodb中。 Every row from the external data is one mongodb document. 外部数据的每一行都是一个mongodb文档。 Every row has an unique id called uid. 每行都有一个唯一的ID,称为uid。

Now I am trying the following: I want to insert a new row, if no document with the same uid exists already (Upsert). 现在,我尝试以下操作:如果不存在具有相同uid的文档,我想插入新行(Upsert)。

For a single document, I would do the following: 对于单个文档,我将执行以下操作:

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

Step 1: 第1步:

Is it possible to override the complete document, not just set specific fields? 是否可以覆盖整个文档,而不仅仅是设置特定的字段? Something like this: 像这样:

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

This is not working, since i get a First key in $update argument is not an update operator error. 这是行不通的,因为我First key in $update argument is not an update operator获得了First key in $update argument is not an update operator错误。 How to do it? 怎么做?

Step 2 第2步

For performance reasons, I want to use insertMany or updateMany function to bulk upsert multiple documents. 出于性能原因,我想使用insertMany或updateMany函数批量上载多个文档。

But what filter do I need for updateMany: 但是我需要什么过滤器来进行更新

$db->updateMany(
    [???????],
    [
        "newfield" => date("Y-m-d H:i:s"),
        "name" => "XXX"
    ],
    [
        "upsert" => true
    ]
);

The questions are totally independent. 这些问题是完全独立的。

The first: 首先:

Use update with multi: false (which is default) instead of updateOne . 使用带有multi: false update multi: false (默认值),而不是updateOne The former allows to replaces an existing document entirely . 前者允许完全替换现有文件

The second: 第二:

updateMany doesn't work this way. updateMany不能这样工作。 It is more like update with multi: true - it applies update operations to all documents that match the filter. 它更像是使用multi: true 更新 multi: true将更新操作应用于与过滤器匹配的所有文档。 When used with upsert: true the filter fields should be uniquely indexed to avoid multiple upserts . 当与upsert: true一起使用时, 应该对索引字段进行唯一索引,以避免出现多次upserts

If you want to perform multiple upserts with individual filters in one go, you can use bulk update : 如果您想一次性使用多个过滤器执行多个upsert,则可以使用批量更新

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

Please read the page behind the last link for limitations of bulk operations. 请阅读最后一个链接后面的页面,以了解批量操作的局限性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM