2015-10-15 175 views
0

因此,这里是一个文档的样品中的mongodb我的收藏:MongoDB的PHP查询与嵌套对象

{ 
    "_id" : ObjectId("561e0de61c9218b7bf9877c3"), 
    "Date" : NumberLong(20151014), 
    "Hour" : NumberLong(10), 
    "ProductId" : ObjectId("5614ba9c2e131caa098b4567"), 
    "ProductName" : "Test", 
    "ProducerId" : ObjectId("5617802151f8adf4db329d52"), 
    "ProducerName" : "Producer", 
    "ProducerRate" : NumberLong(300), 
    "ProducerMedium" : "Emailer", 
    "TotalLead" : NumberLong(6), 
    "VerifiedLead" : NumberLong(3), 
    "UnverifiedLead" : NumberLong(2), 
    "UnQualifiedLead" : NumberLong(1), 
    "TotalEarning" : NumberLong(660), 
    "Consumers" : [ 
     { 
      "ConsumerId" : ObjectId("5617802151f8adf4db329d54"), 
      "ConsumerName" : "Consumer1", 
      "ConsumedRate" : NumberLong(120), 
      "ConsumedLead" : NumberLong(3), 
      "Earning" : NumberLong(360) 
     }, 
     { 
      "ConsumerId" : ObjectId("5617802151f8adf4db329d58"), 
      "ConsumerName" : "Consumer2", 
      "ConsumedRate" : NumberLong(100), 
      "ConsumedLead" : NumberLong(3), 
      "Earning" : NumberLong(300) 
     } 
    ] 
} 

现在我想从PHP中的数据库中ConsumerId和产品编号分组的ConsumedLead。

我已经做了这么远给我TotalLead和VerifiedLead产品编号分组,但不知道如何获得consumerbased结果相同:

$keyf = new MongoCode('function(doc) {  
       return {\'ProductId\': doc.ProductId,\'ProductName\': doc.ProductName}; 
     }'); 
     $initial = array('TotalLead'=>0,'VerifiedLead'=>0); 

     $reduce = "function(obj, prev) { 
     prev.TotalLead += obj.TotalLead; 
     prev.VerifiedLead += obj.VerifiedLead; 

     }"; 
     $result = $collection->group($keyf, $initial, $reduce); 
     var_dump($result); 

任何帮助请。

编辑: 预期的结果wpuld是:

{ [0]=> array(4) { ["ProductId"]=> object(MongoId)#8 (1) { ["$id"]=> string(24) "5614ba9c2e131caa098b4567" } ["ProductName"]=> string(4) "Test" ["ConsumerId"]=> object(MongoId)#8 (1) { ["$id"]=> string(24) "5617802151f8adf4db329d58" } ["ConsumedLead"]=> float(4) } } 

回答

1

的解决方案是使用aggregation framework其中操作包括$unwind操作者初始流水线级,因为这会从解构Consumers阵列字段输入文档并输出每个元素的文档。每个输出文档用一个元素值替换数组。于是,这将有可能使在$group步工作$sum组蓄电池操作,因而givies你所需ConsumedLead通过ConsumerIdProductId分组:

db.collection.aggregate([ 
    { 
     "$unwind": "$Consumers" 
    }, 
    { 
     "$group": { 
      "_id": { 
       "ProductId": "$ProductId", 
       "ConsumerId": "$Consumers.ConsumerId" 
      }, 
      "TotalConsumedLead": { 
       "$sum": "$Consumers.ConsumedLead" 
      } 
     } 
    } 
]) 

在上面的示例运行此聚合操作将导致:

/* 0 */ 
{ 
    "result" : [ 
     { 
      "_id" : { 
       "ProductId" : ObjectId("5614ba9c2e131caa098b4567"), 
       "ConsumerId" : ObjectId("5617802151f8adf4db329d58") 
      }, 
      "TotalConsumedLead" : NumberLong(3) 
     }, 
     { 
      "_id" : { 
       "ProductId" : ObjectId("5614ba9c2e131caa098b4567"), 
       "ConsumerId" : ObjectId("5617802151f8adf4db329d54") 
      }, 
      "TotalConsumedLead" : NumberLong(3) 
     } 
    ], 
    "ok" : 1 
} 

因此,最终的工作aggregation in PHP应该是:

$pipeline = array( 
    array('$unwind' => '$Consumers'), 
    array(
     '$group' => array(
      '_id' => array(
       'ProductId' => '$ProductId', 
       'ConsumerId' => '$Consumers.ConsumerId', 
      ), 
      'TotalConsumedLead' => array(
       '$sum' => '$Consumers.ConsumedLead' 
      ), 
     ) 
    ), 
); 

$out = $collection->aggregate($pipeline ,$options); 
+1

谢谢,完美的工作:) – Nero

+0

@Nero真棒,很高兴帮助:-) – chridam