2012-06-26 56 views
1

我試圖爲網站設置消息收件箱,並且需要將用戶(發件人或收件人)的所有文檔分組到線程中。這些消息收集充滿了這樣的文件:MongoDb/PHP,無法使用聚合框架使分組正常工作

{ 
"_id" : ObjectId("4fe8d8ac0a6d2ad9350000d9"), 
"message" : "booo", 
"recipient" : { 
    "user_id" : ObjectId("4fd9f0600a6d2ac94f000003"), 
    "viewed" : 1 
}, 
"sender" : { 
    "user_id" : ObjectId("4fdb3b780a6d2a9d29000047"), 
}, 
"thread" : "c03a4e49348d009f4ddd8aae325128e1" 
"date_sent" : ISODate("2012-06-25T21:31:24.230Z"), 

}

我能夠使用蒙戈的組功能得到想要的結果,但不能進行排序或組的限制,所以我非常喜歡使用聚合框架,但我無法獲得理想的結果。基本上,我需要這樣做:

$groupBy = array(
      'thread' => 1, 
     ); 
    $initial = array('count' => 0); 

    $reduce = "function (obj, prev) { 
      prev.count++; 
      prev.message = obj.message; 
      prev.sender = obj.sender.user_id; 
      prev.recipient = obj.recipient.user_id; 
      prev.date_sent = obj.date_sent; 
      prev.viewed = obj.recipient.viewed; 
     }"; 

    $condition = array(
      '$or' => array(
          array('sender.user_id'  => new MongoId($options['user_id'])), 
          array('recipient.user_id' => new MongoId($options['user_id'])) 
         ) 
     ); 
    return $this->_collection->group($groupBy, $initial, $reduce, $condition); 

隨着總框架,但我沒有得到我需要的結果...基本上,我有這樣的:

$condition = array(
      '$or' => array(
          array('sender.user_id'  => new MongoId($options['user_id'])), 
          array('recipient.user_id' => new MongoId($options['user_id'])) 
         ) 
     ); 
    $returnFields = array(
      'message'   => 1, 
      'sender.user_id' => 1, 
      'recipient.user_id' => 1, 
      'date_sent'   => 1, 
      'thread'   => 1, 
     ); 
    $sort  = array('date_sent' => 1); 
    $groupBy = array('_id'  => '$thread'); 

    $input = array(
     'aggregate' => $this->_collectionName, 
     'pipeline' => array(
       array('$project' => $returnFields), 
       array('$match' => $condition), 
       array('$group' => $groupBy), 
       array('$sort'  => $sort), 
      ) 
    ); 
    return $this->_db->command($input); 

而且它只有返回線程,就像它忽略了我的$項目...任何想法?

+0

我已經想通了。不太確定爲什麼$ project不能運行,但是,我可以使用$ first運算符來選擇$ group語句中的字段 – giantNinja

回答

0

我已經想通了。真的不知道爲什麼在$項目不攜帶雖不過,我可以使用$第一家運營商選擇在$組聲明

$condition = array(
      '$or' => array(
          array('sender.user_id'  => new MongoId($options['user_id'])), 
          array('recipient.user_id' => new MongoId($options['user_id'])) 
         ) 
     ); 

    $sort  = array('date_sent' => -1); 

    $groupBy = array(
      '_id'  => '$thread', 
      'sender' => array('$first' => '$sender.user_id'), 
      'recipient' => array('$first' => '$recipient.user_id'), 
      'date_sent' => array('$first' => '$date_sent'), 
      'message' => array('$first' => '$message'), 
      'viewed' => array('$first' => '$recipient.viewed'), 
     ); 

    $input = array(
     'aggregate' => $this->_collectionName, 
     'pipeline' => array(
       array('$match' => $condition), 
       array('$sort'  => $sort), 
       array('$group' => $groupBy), 
       array('$sort'  => $sort), 

      ) 
    ); 

    return $this->_db->command($input); 

基本上,我需要匹配正確的文件領域,他們如此排序最新的消息是第一個,做$組,我可以用$ first操作符選擇字段,然後再次對它們進行排序,以便它們按照正確的順序排列。沒有想到這將是必要的,但這似乎工作正常。

相關問題