Upsert - php mongodb-无法插入新记录

时间:2016-03-16 11:04:00

标签: php mongodb upsert

我正在运行以下代码。如果记录已存在,则使用$ 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;

3 个答案:

答案 0 :(得分:2)

您可以将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;

答案 1 :(得分:1)

Evgeny的答案还可以,但你错过了一个问题

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

答案 2 :(得分:0)

我必须使用 updateOne

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