2016-08-12 72 views
0

我最近開始使用Mongo db。 這是蒙戈DB我的樣本文件中DB homeconfig和收集數據PHP Mongo Library沒有更新一些文檔

{ 
    "_id": {}, 
    "user_id": "user", 
    "rooms": [ 
      { 
      "name": "abhi", 
      "metadata": { 
       "user_id": "user", 
       "is_expired": "false", 
       "expired_on": null 
      } 
     } 
    ], 
    "sections": [ 
      { 
      "name": "section1", 
      "metadata": { 
       "user_id": "user", 
       "room": "abhi", 
       "is_expired": "false", 
       "expired_on": null 
      } 
     } 
    ], 
    "devices": [ 
      { 
      "id": "aur.01.Jpzp0o", 
      "metadata": { 
       "section_less": "true", 
       "label": "aa", 
       "is_active": null, 
       "is_loading": null, 
       "is_dimmable": null, 
       "type": "aura", 
       "sub_device": "aur.01", 
       "is_favourite": "false", 
       "dimming": null, 
       "energy_usage": 0, 
       "usage_today": 0, 
       "avg_usage": 0, 
       "ir_control": null, 
       "user_id": "user", 
       "room": "abhi", 
       "section": null, 
       "is_expired": "false", 
       "expired_on": null 
      } 
     } 
    ] 
} 

上面顯示的JSON只是我的文檔的例子。實際的相當大,我不能透露原件。

下面是我用來更新文檔中的集合的函數。

function removeSectionsFromMongo($user_id, $data, $date) 
{    
    $collection = (new MongoConnect())->connect('homeconfig', 'data');   
    foreach ($data as $key) {   
     $update = $collection->updateOne(['user_id'=>$user_id, 'sections' => ['$elemMatch' => ['name' => $key['name'], 'metadata.is_expired' => 'false' ]]], 
       ['$set'=>['sections.$.metadata.is_expired'=>'true', 'sections.$.metadata.expired_on'=>$date]] 
      ); 
     if($update->getModifiedCount() == 1) 
     { 
      echo "Section <".$key['name']."> removed from room <".$key['metadata']['room'].">."."\n"; 
     } 
    }   
} 

可變$data低於所示的陣列:

Array 
(
    [0] => Array 
     (
      [name] => Appliances 
      [metadata] => Array 
       (
        [user_id] => CubicalPrime 
        [room] => Dhruv 
        [is_expired] => false 
        [expired_on] => 
       ) 

     ) 

    [1] => Array 
     (
      [name] => Bathroom 
      [metadata] => Array 
       (
        [user_id] => CubicalPrime 
        [room] => Dhruv 
        [is_expired] => false 
        [expired_on] => 
       ) 

     ) 

    [2] => Array 
     (
      [name] => Others 
      [metadata] => Array 
       (
        [user_id] => CubicalPrime 
        [room] => Dhruv 
        [is_expired] => false 
        [expired_on] => 
       ) 

     ) 

) 

當我執行的功能,它應該更新所有sections傳入的陣列$data在我的文檔匹配。

但是,它正在更新文檔。但是,當文檔大小增加時,sections中的某些對象有時不會更新。即is_expired字段沒有更新到true & expired_on在通過的日期沒有更新。

當我再次運行相同的函數時,整個更新發生在第二次。

我只在查詢結果表明修改計數等於1時纔回顯。這表示查詢正在正確執行。但很少有文件沒有得到更新。

if($update->getModifiedCount() == 1) 
    { 
     echo "Section <".$key['name']."> removed from room <".$key['metadata']['room'].">."."\n"; 
    } 

我想弄清楚爲什麼文件沒有在第一時間得到更新,但第二次得到更新!

幫我看看我的代碼出了什麼問題?

回答

0

有點大挖成我的代碼後,我增加了一個條件,用於更新記錄的驗證。

function removeSectionsFromMongo($user_id, $data, $date) 
{    
    $collection = (new MongoConnect())->connect('homeconfig', 'data');   
    foreach ($data as $key) {   
     $update = $collection->updateOne(['user_id'=>$user_id, 'sections' => ['$elemMatch' => ['name' => $key['name'], 'metadata.is_expired' => 'false', 'metadata.room' => $key['metadata']['room'] ]]], 
       ['$set'=>['sections.$.metadata.is_expired'=>'true', 'sections.$.metadata.expired_on'=>$date]] 
      ); 
     if($update->getModifiedCount() == 1) 
     { 
      echo "Section <".$key['name']."> removed from room <".$key['metadata']['room'].">."."\n"; 
     } 
    }   
} 

在上面的代碼中看到這個'metadata.room' => $key['metadata']['room']

現在記錄正在像往常一樣更新。此外,我現在使用bulkWrite(),chridam建議在其他答案減少服務器上的負載。見下面的代碼:

function removeSectionsFromMongo($user_id, $data, $date, $collection, $debug) 
{    
    $bulkOps = array();  
    $sections = array(); $rooms = array(); 
    foreach ($data as $key) { 
     $update = [ 
      'updateOne' => [ 
       [ 
        'user_id' => $user_id, 
        'sections' => [ 
         '$elemMatch' => [ 
          'name' => $key['name'], 
          'metadata.user_id' => $user_id, 
          'metadata.room' => $key['metadata']['room'], 
          'metadata.is_expired' => 'false' 
         ] 
        ] 
       ], 
       [ 
        '$set' => [ 
         'sections.$.metadata.is_expired' => 'true', 
         'sections.$.metadata.expired_on' => $date 
        ] 
       ] 
      ] 
     ];   
     array_push($bulkOps, $update); 
     if($debug) 
     { 
      array_push($sections, $key['name']);   
      array_push($rooms, $key['metadata']['room']);     
     }       
    } 
    $result = $collection->bulkWrite($bulkOps); 

    if($result->getModifiedCount() == count($data)) 
    { 
     if($debug) 
     { 
      for($i = 0; $i < count($sections); $i++) 
      { 
       echo "Section -".$sections[$i]."- removed from room -".$rooms[$i]."-."."\n"; 
      } 
     } 
     return true; 
    } 
    return false; 
}//end removeSectionsFromMongo() 

仍然我沒有得到爲什麼我以前的代碼不工作與記錄的一些驗證。 它是在Mongo圖書館或其他東西的錯誤!

如果有人弄清楚是什麼問題,請讓我知道。

0

您可以使用bulkWrite() API利用你的更新與你在一個循環中發送異步更新目前的實現,因此,爲什麼你正在更新,有些不是一些文件。

bulkWrite() API有一些方法,可以讓你的更新操作的服務器,因此在效率上一批被執行,你不每次迭代發送到服務器的每個更新操作,只有一次在500說操作。

下面演示的方法:

function removeSectionsFromMongo($user_id, $data, $date) { 
    $bulkOps = array();  
    foreach ($data as $key) { 
     $update = [ 
      'updateOne' => [ 
       [ 
        'user_id' => $user_id, 
        'sections' => [ 
         '$elemMatch' => [ 
          'name' => $key['name'], 
          'metadata.is_expired' => 'false' 
         ] 
        ] 
       ], 
       [ 
        '$set' => [ 
         'sections.$.metadata.is_expired' => 'true', 
         'sections.$.metadata.expired_on' => $date 
        ] 
       ] 
      ] 
     ];   
     array_push($bulkOps, $update);   
    } 
    $operation = new BulkWrite($databaseName, $collectionName, $bulkOps); 
    $result = $operation->execute($primaryServer); 
    echo $result->getModifiedCount(); 
} 
+0

同樣的問題仍然存在。很少有結果沒有得到更新。這些與以前的實施完全相同。 ;-( – Choxx

+0

查看我的答案,我添加了幾個驗證參數,代碼工作起來就像一個魅力一樣,並且我更新了我的代碼,按照您的建議使用'bulkwrite()'。 – Choxx