在 MongoDB 和 php 中更新许多文档

Upsert many documents in MongoDB and php

我尝试使用 php 从外部源将数据导入我的 mongodb。外部数据的每一行都是一个 mongodb 文档。每行都有一个名为 uid 的唯一 ID。

现在我正在尝试以下操作:如果不存在具有相同 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
    ]
);

问题完全独立。

第一个:

使用update with multi: false (which is default) instead of updateOne. The former allows to replaces an existing document entirely.

第二个:

updateMany doesn't work this way. It is more like update with multi: true - it applies update operations to all documents that match the filter. When used with upsert: true the filter fields should be uniquely indexed to avoid multiple 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);

请阅读最后link后面的页面以了解批量操作的限制。