2014-10-07 3 views
0

В нашей базе данных mongodb у нас есть коллекция пользователей. Каждый пользовательский документ содержит некоторую базовую информацию о пользователе, такую ​​как местоположение, дата рождения и пол. Он содержит несколько дополнительных свойств, но это тип данных, которые мы храним.MongoDB Scema Design - Запрос пользовательской информации и ежемесячной статистики

Мы собираем ежемесячную статистику для каждого пользователя. Есть много разных статистических данных, которые мы собираем для пользователя, но общая идея заключается в том, что для каждого месяца для каждого пользователя будет один документ. Этот документ будет содержать много разных атрибутов, содержащих в основном числовые данные. Вот пример ежемесячного документа.

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

Бизнес хотел бы запросить пользователей на основе статистики. Я использовал mongodb в прошлом, но не для этого. Моя первая мысль заключалась в том, чтобы объединить дополнительные свойства в коллекцию ежемесячных статистических данных, но хотелось узнать, что думают другие люди.

Некоторые примеры отчетов

  • Дайте мне все пользователи в Мичигане, где их рост (стат в ежемесячном резюме) между началом месяца и конец месяца больше, чем X.
  • Дайте мне все пользователи в Мичигане и шоу мне их статистика за месяцы июня, июля и августа в строке, и мы хотим иметь возможность сортировать по статистике за определенный месяц. Таблица будет выглядеть следующим образом: [ Full Name | Location | June 2014 Views | June 2014 Growth | July 2015 | July 2015 Growth ]

Цените свои мысли.

EDIT: Я также должен поддерживать некоторую форму разбиения на страницы и сортировку по всем полям.

+1

, чтобы сделать вид мерная запроса вам нужно будет либо сохранить эти атрибуты в сводных документах (если не слишком много из них, помните, что они должны быть проиндексированы, что несколько замедлит ваши записи) * или * вы могли бы запросить идентификатор пользователя для соответствующего атрибута, а затем запросить итоговую коллекцию только для идентификаторов пользователя, но это вряд ли будет масштабироваться, если у вас есть миллионы пользователей из Мичигана, например. Я бы предложил пойти с сохранением атрибутов в сводном документе. –

+0

Спасибо. Единственная проблема, с которой я вижу, - разбиение на страницы и сортировку. Это легко, если они сортируют данные, отфильтрованные пользователем, но если они сортируются в столбце stat, они будут отсортированы пользователями, включенными в первую партию пользователя. –

+0

Похоже, кандидат на [Агрегационный трубопровод MongoDB] (http://docs.mongodb.org/manual/core/aggregation-introduction/). – zamnuts

ответ

1

Чтобы выполнить сортировку по размеру, вам нужно будет сохранить эти атрибуты в сводных документах (при условии, что их не так уж много, поскольку они должны быть проиндексированы, что несколько замедлит ваши записи).

Так принимая документ:

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

Чтобы сделать второй запрос, основанный на состоянии будет что-то вроде этого:

Все пользователи в Мичигане (возможно, другие фильтры атрибутов), и показать мне свою статистику за месяцы июнь, июль и август, отсортированные по июльской статистике.

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

Большое спасибо за ваши отзывы об этом. Отличный, полезный пример. Ценить это. –

Смежные вопросы