2016-04-14 53 views
0

我正在爲幾乎實時的統計模塊創建數據庫結構。我想統計不同產品的用戶行爲:新的喜歡,投票,新評論和總活動(總票數,喜歡等)。MongoDB中重疊日期的聚合查詢

該模塊需要在過去的8,16或24小時內發送最多的活動的 N產品。 我的第一個想法是爲一個文件下面的模式:

{ 
    "_id" : ObjectId("570e37d0db8c0897d651509c"), 
    "date" : "2016-04-13", 
    "trackId" : 35, 
    "count" : { 
     "hour_1" : { 
      "total" : 120, 
      "downVote" : 35, 
      "newComment" : 26, 
      "upVote" : 34, 
      "like" : 25 
     }, 
     "hour_2" : { 
      "total" : 124, 
      "downVote" : 32, 
      "like" : 28, 
      "upVote" : 33, 
      "newComment" : 31 
     }, 
     // ... 
     "hour_24" : { 
      "total" : 119, 
      "downVote" : 42, 
      "newComment" : 30, 
      "upVote" : 31, 
      "like" : 16 
     } 
    } 
} 

在這種情況下,我有X產品X文件在一天與此查詢我什麼,我需要快速維伊獲取數據。

db.getCollection('HourlyStat') 
    .aggregate([ 
    {$match: {date: '2016-04-13'}}, 
    { 
     $project: {'trackId': "$trackId", 
     count: { 
     $sum: ["$count.hour_1.total", "$count.hour_2.total", ..., "$count.hour_8.total"] } 
     } 
    }, 
    {$sort: {'count': -1}}, {$limit: 10} 
    ]) 

不幸的是,這是不適用於包括兩天的時間段。 例如:從2016-04-13 12:00:002016-04-14 12:00:00

我可以爲此編寫一個查詢,或者我應該更改我的數據結構嗎?一個簡單的解決方法是將小時數據存儲在獨立的文檔中,但它將包含多達24倍的數據,而對於大量的產品,它可能會很慢。

+0

好了,你就需要爲每個時隙運行多個聚集查詢,並在應用程序中合併返回文檔的情況下。 – Saleem

+0

@Saleem這不是一個可以接受的解決方案,因爲在這種情況下,應用程序服務器需要處理大量的數據,消耗內存。 – Festo

回答

0

我認爲你需要改變你的模式,因爲你建議獨立文檔中的小時數據。您還應該爲日期使用正確的Date()字段,這將使您在基於日期的查詢中變得更加靈活。

db.getCollection('HourlyStat') 
    .aggregate([ 
    {$match: {date: {$gt: new Date(new Date()-1000*60*60*24)}}} 
    //... 
    ]) 

如果它更容易,你也可以生成客戶端搜索的開始結束時間,而不是限制到最後n個小時,例如。這有一個簡單的尋找查詢的優勢(我喜歡簡單的查詢)

db.getCollection('dates') 
    .aggregate([ 
    {$match: {date: {$gte: ISODate("2016-04-13T09:00:00.000+0000"), $lt: ISODate("2016-05-16T20:00:00.000+0000") }}} 
    ])