2014-10-07 203 views
0

在我們的mongodb數據庫中,我們有一組用戶。每個用戶文檔都包含有關用戶的一些基本信息,例如位置,出生日期和性別。它包含一些額外的屬性,但這是我們存儲的數據類型。MongoDB Scema Design - 查詢用戶信息和月度統計信息

我們也爲每個用戶收集每月的統計數據。我們爲用戶收集了許多不同的統計數據,但總體思路是每個月都會有一個文檔供每個用戶使用。該文檔將包含許多不同的屬性,主要包含數字數據。這裏是一個月度文檔的例子。

{ 
    "UserId": ObjectId(""), 
    "SummaryDate": ISODate("2014-09-01T04:00:00Z"), 
    TotalViews: 34, 
    Points: 300, 
    Growth: 20.3 
} 

業務想根據統計信息查詢用戶。我過去使用過mongodb,但不是用於此用途。我的第一個想法是將其他屬性合併到每月統計信息收集中,但想知道其他人的想法。

一些示例報告

  • 給我在密歇根州的所有用戶,他們的起始月份和結束月份之間增長(每月彙總統計)是大於X.
  • 給我的所有用戶在密歇根州和表演我的統計數據爲6月,7月和8月,我們希望能夠按特定月份的統計數據進行排序。表如下所示: [ Full Name | Location | June 2014 Views | June 2014 Growth | July 2015 | July 2015 Growth ]

欣賞你的想法。

編輯:我也必須支持某種形式的分頁和排序的所有領域。

+1

做排序的維查詢你需要或者保持在摘要中的文件,這些屬性(如果沒有太多請記住它們應該被編入索引,這會減慢寫入的速度)*或*您可能會查詢用戶標識的相應屬性,然後僅查詢您希望的用戶標識的彙總集合,但如果您有例如,來自密歇根州的數百萬用戶。我會建議保留摘要文檔中的屬性。 – 2014-10-07 15:39:23

+0

謝謝。我看到的唯一問題是分頁和排序。如果他們要對用戶過濾的數據進行排序很容易,但是如果他們在統計信息列上進行排序,則會按照第一批用戶中包含的用戶進行排序。 – 2014-10-07 19:09:10

+0

似乎是[MongoDB的聚集管道]的候選人(http://docs.mongodb.org/manual/core/aggregation-introduction/)。 – zamnuts 2014-10-07 19:14:04

回答

1

要進行維度查詢,您需要在摘要文檔中保留這些屬性(假設它們不是太多,因爲它們應該被編入索引,這會減慢寫入的速度)。

因此,假設一個文件:

{ 
    "UserId": ObjectId(""), 
    "FullName":"Joe Shmoe", 
    "Location":"Michigan", 
    "SummaryDate": ISODate("2014-09-01T04:00:00Z"), 
    TotalViews: 34, 
    Points: 300, 
    Growth: 20.3 
} 

要做到基於狀態的第二查詢將是這樣的:

在密歇根州(任選的其它屬性過濾器)的所有用戶,並告訴我他們的統計6月,7月和8月按7月份的統計數據排序。

db.collection.aggregate([ 
    {"$match":{ 
     "Location":"Michigan", 
     "SummaryDate":{"$gt":ISODate("2014-06-01T04:00:00Z"), "$lt":ISODate("2014-09-01T04:00:00Z")} 
    } }, 
    {"$group": { 
     "_id":"$UserId", 
     "Full Name":{$first:"$FullName"}, 
     "Location":{$first:"$Location"}, 
     "June views": {$sum:{$cond:{if:{$eq:[{$month:"$SummaryDate"},6]},then:"$TotalViews",else:0}}}, 
     "June growth": {$sum:{$cond:{if:{$eq:[{$month:"$SummaryDate"},6]},then:"$Growth",else:0}}}, 
     "July views": {$sum:{$cond:{if:{$eq:[{$month:"$SummaryDate"},7]},then:"$TotalViews",else:0}}}, 
     "July growth": {$sum:{$cond:{if:{$eq:[{$month:"$SummaryDate"},7]},then:"$Growth",else:0}}}, 
     "Aug views": {$sum:{$cond:{if:{$eq:[{$month:"$SummaryDate"},8]},then:"$TotalViews",else:0}}}, 
     "Aug growth": {$sum:{$cond:{if:{$eq:[{$month:"$SummaryDate"},8]},then:"$Growth",else:0}}}, 
    } }, 
    {"$sort":{"July views":1} } 
]); 

輸出將文件是這樣的樣本名單:

{ 
    "_id" : ObjectId("543445dd19b404b29e503f94"), 
    "Full Name" : "Jane Shmoe", 
    "Location" : "Michigan", 
    "June views" : 0, 
    "June growth" : 0, 
    "July views" : 40, 
    "July growth" : 20.3, 
    "Aug views" : 340, 
    "Aug growth" : 20.3 
} 
+0

非常感謝您對此的反饋。偉大的,有用的例子。欣賞它。 – 2014-10-07 20:34:21