2013-01-31 49 views
0

所以我有一個MongoDB文檔跟蹤登錄到我們的應用程序。基本結構因此而出現:MongoDB查詢獲得密鑰發生的次數

[_id] => MongoId Object 
     (
      [$id] => 50f6da28686ba94b49000003 
     ) 

    [userId] => 50ef542a686ba95971000004 
    [action] => login 
    [time] => 1358354984 

現在,挑戰是:這些條目中大約有20,000個。我一直在質疑每個用戶登錄的次數(由userId定義)......所以我正在尋找一個很好的方法來做到這一點。我見過幾種可能的方法(例如,在SQL中,我可能會通過按用戶ID進行分組並對其進行計數來降低登錄次數,例如SELECT userID,count(*)來自... .group by UserId ...然後在該選項上進行子選擇(CASE WHEN或頂部選擇中的某個選項) 反正 - 想知道是否有人對最佳方式有任何建議最差的情況我可以限制結果設置並在內存中進行分組 - 但理想情況下希望直接從Mongo獲得完整答案。 另一個限制(即使在經過第一組之後),我希望按日期進行唯一計數。這將更加困難!

+0

您是否找到解決問題的方法? – infinity

回答

0

您可以使用MapReduce按用戶ID分組結果

http://docs.mongodb.org/manual/applications/map-reduce/#map-reduce-examples

或者你也可以使用組方法:

db.logins.aggregate(
    { $group : { 
     _id : "$userId", 
     loginsPerUser : { $sum : 1 } 
    }} 
); 

MongoDB的20K或更不會走路,他們結合,從而不愁性能問題。

+0

是的 - 我想到了這個......但是我在超時時遇到了問題(有超過20,000個密鑰 - 這意味着PHP組函數是固定的)。 –

2

現在,挑戰是:這些條目大約有20,000個。

在20000你可能會與聚合框架(http://docs.mongodb.org/manual/applications/aggregation/)更好:

$db->user->aggregate(array(
    array('$group' => array('_id' => '$userId', 'num_logins' => array('$sum' => 1))) 
)); 

將由userId和計數(總和:http://docs.mongodb.org/manual/reference/aggregation/sum/#_S_sum)組(http://docs.mongodb.org/manual/reference/aggregation/#_S_group)分組登錄有量是。

注意:如註釋中所述,聚合幫助程序位於PHP驅動程序的1.3+版本中。在版本1.3之前,您必須直接使用command函數。

+0

請記住,這僅在最新版本的mongodb驅動程序中受支持。 – datasage

+0

@datasage真的我應該補充說,謝謝你提醒我 – Sammaye

+0

是的 - 我試圖升級到1.3的安裝驅動程序 - 但沒有setSlaveOkay()我掙扎 - 所以我恢復。可能是時候想出來了! –

0

http://docs.mongodb.org/manual/reference/command/group/

db.user.group({key: {userId: 1}, $reduce: function (curr, result) { result.total++ }, initial: {total: 0}}); 

我在短短的幾秒鐘跑這對191000行,但組被限制到20,000獨特的條目,它確實是不適合你的解決方案。