2016-03-16 132 views
3

我正在運行以下代碼。如果記錄已經存在,它將使用新的$ updated_fields_array覆蓋現有的字段。但是,如果記錄不存在,我不知道如何添加新記錄與新字段($ new_fields_array)。我應該使用哪個操作符?有人可以幫我嗎?Upsert - php mongodb-無法插入新記錄

$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; 

回答

1

葉夫根的回答是好,但你缺少一個問題

你必須在重複鍵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 
); 

和更改查詢(如葉夫根寫道或Documentation

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

您可以使用UPDATE命令UPSERT選項和設置$/$ setOnInsert操作符(見https://docs.mongodb.org/manual/reference/operator/update/setOnInsert/)。見下面的例子(注意,你應該有唯一索引{電子郵件:1,名稱: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; 
+0

我試過了。它不起作用。 –

+0

@YannaGenkin它究竟如何不起作用 - 沒有插入文檔os某些字段丟失或錯誤? –

+0

不幸的是,沒有插入文檔。 –

0

我不得不使用updateOne

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