【问题标题】:MongoDB & PHP - handling duplicate documentsMongoDB 和 PHP - 处理重复文档
【发布时间】:2023-03-13 09:06:01
【问题描述】:

我有一个集合,我想限制具有特定字段的文档的重复项。按照SO thread 的指导,我手动实现了一个索引:

{
  "playerName": 1,
  "comp.compName": 1,
  "comp.roundNo": 1
},
{
  "unique": true
}

现在,当我尝试插入会导致重复的新文档时,PHP 页面/脚本错误:

致命错误:未捕获的 MongoDB\Driver\Exception\BulkWriteException: E11000 重复键错误集合:golf.round 索引: playerName_1_comp.name_1_comp.roundNo_1 dup key: { playerName: "Ernie Els”,comp.name:“2021 年美国公开赛”,comp.roundNo:3 } in /usr/bin/vendor/mongodb/mongodb/src/Operation/InsertOne.php:134 堆栈 跟踪:#0 /usr/bin/vendor/mongodb/mongodb/src/Operation/InsertOne.php(134): MongoDB\Driver\Server->executeBulkWrite('golf.round', 对象(MongoDB\Driver\BulkWrite),数组)#1 /usr/bin/vendor/mongodb/mongodb/src/Collection.php(931): MongoDB\Operation\InsertOne->execute(对象(MongoDB\Driver\Server)) #2 /var/www/html/selectComp.php(90): MongoDB\Collection->insertOne(Array) #3 {main} 在 /usr/bin/vendor/mongodb/mongodb/src/Operation/InsertOne.php 上线 134

要获取插入的所有数据字段,我需要循环另一个comp 集合查询的结果,子查询进入round 嵌入对象。完全完成后,它还应该需要查询选定的player 数据(可能是用户登录功能,尽管试图避免它!):

$insertOneResult = $collectionRound->insertOne(
  [
    'playerName' => "Ernie Els", //$_COOKIE['playerName'],
    'playerId' => "a1b2c3", //$_COOKIE['playerId'],
    'date' => new MongoDB\BSON\UTCDateTime(strtotime("today")*1000),
    'comp' => [
      'id' => $comp['_id'],
      'name' => $comp['compName'],
      'tees' => $newScore['courseTee'],
      'roundNo' => $round['roundNo'],
      'scoringMethod' => $comp['compScoringMethod']
    ],
    'hcap' => 0, //$_COOKIE['playerHcap'],
    'holeCount' => 9, // from course or comp?
    'computedScore' => 0,
    'computedThru' => 0,
    'holes' => [],
    'team' => "PGA Tour", //$_COOKIE['playerTeam'],
    'countbackScores' => []
  ]
);

我该如何处理这个错误?我的意图是简单地限制添加重复项,并忽略此请求。根据使用情况,这可能会通知用户或直接忽略。

【问题讨论】:

  • 你能展示你是如何在集合中插入的吗?也许那时我们可以为您提供更好的帮助。
  • 编辑帖子以包含insert 声明

标签: php mongodb


【解决方案1】:

插入文档时为什么不使用trycatch异常处理。当有重复时,它会给你一个错误,你可以在 catch 块中捕获 exception 而什么都不做。

试试这个:

try{
    $insertOneResult = $collectionRound->insertOne(
        [
        'playerName' => "Ernie Els", //$_COOKIE['playerName'],
        'playerId' => "a1b2c3", //$_COOKIE['playerId'],
        'date' => new MongoDB\BSON\UTCDateTime(strtotime("today")*1000),
        'comp' => [
            'id' => $comp['_id'],
            'name' => $comp['compName'],
            'tees' => $newScore['courseTee'],
            'roundNo' => $round['roundNo'],
            'scoringMethod' => $comp['compScoringMethod']
        ],
        'hcap' => 0, //$_COOKIE['playerHcap'],
        'holeCount' => 9, // from course or comp?
        'computedScore' => 0,
        'computedThru' => 0,
        'holes' => [],
        'team' => "PGA Tour", //$_COOKIE['playerTeam'],
        'countbackScores' => []
        ]
    );
}
catch(Exception $e){
    // This block will catch the duplicate exception
    // Dont do anything here, and just ignore the request
    echo 'Error message: ' .$e->getMessage();
}

替代:你可以先尝试查找条目是否存在,使用.find(),如果存在,不要插入文档,忽略请求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    • 2021-05-11
    • 2017-12-10
    • 2015-05-15
    • 2020-03-16
    • 1970-01-01
    相关资源
    最近更新 更多