2016-08-12 82 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