You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP操作MongoDB执行Upsert后,无法获取插入/更新ID问题咨询

解决MongoDB Upsert操作后获取文档ID的问题

错误原因

你调用的getUpsertedIds()方法不存在于MongoDB\UpdateResult类中,正确的方法是**getUpsertedId()**(单数形式)——因为updateOne操作最多只会upsert一个文档,所以方法名是单数。

获取ID的两种场景处理

1. 触发插入(Upsert新增文档)

当updateOne的upsert逻辑插入了新文档时,直接调用getUpsertedId()就能拿到新文档的_id:

$upsertedId = $result->getUpsertedId();
if ($upsertedId !== null) {
    // 这是新插入的文档ID
    echo "新增文档ID: " . $upsertedId;
}

2. 仅执行更新(修改已有文档)

如果是更新了已存在的文档,getUpsertedId()会返回null,这时你需要通过查询条件(比如你的email字段)来获取目标文档的_id,示例:

if ($result->getUpsertedId() === null) {
    // 查询已有文档的ID
    $existingDoc = $collection->findOne(['email' => $document['email']]);
    if ($existingDoc) {
        echo "更新的文档ID: " . $existingDoc['_id'];
    }
}

修改后的完整代码示例

$collection = $this->api->MDB->getCollection("verify_code", $db_name = "auth")->email;

// 建议先判断索引是否存在,避免重复创建(可选优化)
$indexes = $collection->listIndexes();
$hasUniqueEmailIndex = false;
foreach ($indexes as $index) {
    if ($index['key']['email'] === 1 && $index['unique'] === true) {
        $hasUniqueEmailIndex = true;
        break;
    }
}
if (!$hasUniqueEmailIndex) {
    $collection->createIndex(
        array("email" => 1),
        array("unique" => true)
    );
}

$document = array(
    "email" => $data['email'],
    "code" => 232
);

$result = $collection->updateOne(
    array("email" => $document["email"]),
    array('$set' => $document,'$setOnInsert' => ['created_at' => time()]),
    array("upsert" => true)
);

echo "<pre>";
// 获取Upsert插入的ID(如果有)
$upsertedId = $result->getUpsertedId();
if ($upsertedId) {
    echo "新增文档ID: " . $upsertedId . "\n";
} else {
    // 查询更新的文档ID
    $existingDoc = $collection->findOne(['email' => $document['email']]);
    if ($existingDoc) {
        echo "更新的文档ID: " . $existingDoc['_id'] . "\n";
    }
}
print_r($result);

补充说明

  • updateOne的返回结果MongoDB\UpdateResult还提供了getMatchedCount()(匹配的文档数)和getModifiedCount()(实际修改的文档数)方法,可以用来判断操作类型:
    • 如果getMatchedCount() === 0且getUpsertedCount() === 1,说明是新增了文档;
    • 如果getMatchedCount() >=1,说明是更新了已有文档。

内容的提问来源于stack exchange,提问作者Kodr.F

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 01:03:03