【问题标题】:Upsert - php mongodb- Can't insert a new recordUpsert - php mongodb - 无法插入新记录
【发布时间】:2016-07-02 05:19:33
【问题描述】:

我正在运行以下代码。如果记录已经存在,它会用 $updated_fields_array 处的新字段覆盖现有字段。但是,如果记录不存在,我不知道如何使用新字段($new_fields_array)添加新记录。我应该使用哪个运算符?有人可以帮我吗?

    $current_time = time();
    $current_mongo_date = new MongoDate($current_time);

    $collection = $this->mongo->selectCollection(MONGO_NOTIFY_DB, 'AccountSettings');

    $criteria_array=array("email" => $email, "name" => $name);

    $updated_fields_array = array (
        'last_sent' => $current_time,
        'updated' => $current_mongo_date
    );

    $new_fields_array = array (
        'created' => $current_mongo_date,
        'updated' => $current_mongo_date,
        'email' => $email,
        'name' => $name,
        'last_sent' => $current_time,
        'deleted' => FALSE
    );

    try {

        $collection->update(
            $criteria_array,
            array('$set' => $updated_fields_array),
            array("upsert" => true)
        );

    } catch (MongoCursorException $mce) {
        log_message('error', 'QUERY UPDATE FAILED :: AccountSettings :: ' . print_r($updated_fields_array, true) . ' :: ' . $mce->getMessage());
    }
    return;

【问题讨论】:

    标签: php mongodb upsert


    【解决方案1】:

    您可以将 UPDATE 命令与 upsert 选项和 $set/$setOnInsert 运算符一起使用(请参阅https://docs.mongodb.org/manual/reference/operator/update/setOnInsert/)。请参阅下面的示例(注意,您应该在 {email:1,name:1} 上具有唯一索引)

     $current_time = time();
     $current_mongo_date = new MongoDate($current_time);
    
     $collection = $this->mongo->selectCollection(MONGO_NOTIFY_DB, 'AccountSettings');
    
    $criteria_array=array("email" => $email, "name" => $name);
    
    $updated_fields_array = array (
        'last_sent' => $current_time,
        'updated' => $current_mongo_date
    );
    
    $new_fields_array = array (
        'created' => $current_mongo_date,
        'deleted' => FALSE
    );
    
    try {
    
        $collection->update(
            $criteria_array,
            array('$set' => $updated_fields_array, '$setOnInsert'=> $new_fields_array),
            array("upsert" => true)
        );
    
    } catch (MongoCursorException $mce) {
        log_message('error', 'QUERY UPDATE FAILED :: AccountSettings :: ' . print_r($updated_fields_array, true) . ' :: ' . $mce->getMessage());
    }
    return;
    

    【讨论】:

    • @YannaGenkin 它到底是怎么不工作的 - 没有文档插入操作系统某些字段丢失或错误?
    • 很遗憾,没有插入任何文档。
    • 您对集合是否有任何特定限制,例如唯一索引或文档验证可能会阻止插入新文档?
    • 不,我在映射yml文件中没有这样的定义。
    • 您是否有权访问 mongodb shell,您可以在其中使用 db.AccountSettings.getIndexes() 检查索引,使用 db.getCollectionInfos() 查看集合约束并尝试使用 db.AccountSettings.update 插入示例文档?
    【解决方案2】:

    Evgeny 的答案还可以,但你漏掉了一个问题

    updated_fields_array 和 new_fields_array 中有重复的键,这会抛出 MongoDB WriteException,因为 Mongo 将首先创建新对象,然后才更新它。

    所以改变

    $updated_fields_array = array (
        'last_sent' => $current_time,
        'updated' => $current_mongo_date
    );
    
    $new_fields_array = array (
        'created' => $current_mongo_date,
        'updated' => $current_mongo_date,
        'email' => $email,
        'name' => $name,
        'last_sent' => $current_time,
        'deleted' => FALSE
    );
    

    到

    $updated_fields_array = array (
        'last_sent' => $current_time,
        'updated' => $current_mongo_date
    );
    
    $new_fields_array = array (
        'created' => $current_mongo_date,
        'email' => $email,
        'name' => $name,
        'deleted' => FALSE
    );
    

    并更改查询(如 Evgeny 所写或Documentation)

    $collection->update(
            $criteria_array,
            array('$set' => $updated_fields_array, '$setOnInsert'=> $new_fields_array),
            array("upsert" => true)
    );
    

    【讨论】:

      【解决方案3】:

      我不得不使用 updateOne

      $result = $collection->updateOne(
              array('first_id' => 123456,'some_number' => 333333),
              array('$set' => array('some_status' => 'Delayed')),
              array('upsert' => true)
      );
      

      【讨论】:

        猜你喜欢
        • 2016-04-04
        • 2016-08-11
        • 1970-01-01
        • 1970-01-01
        • 2019-09-07
        • 1970-01-01
        • 1970-01-01
        • 2012-07-02
        • 1970-01-01
        相关资源
        最近更新 更多