Показать сообщение отдельно
  #1 (permalink)  
Старый 22.01.2015, 18:56
Аспирант
Отправить личное сообщение для Ichigeki Посмотреть профиль Найти все сообщения от Ichigeki
 
Регистрация: 24.10.2008
Сообщений: 48

Структура MongoDB БД для аггрегации больших объемов данных
У меня есть коллекция, в которой хранится статистика кликов. На основе этих данных нужно строить отчеты. Вот пример документа
Код:
{
   "_id": {
     "dateVisited": ISODate("2014-11-05T00:00:00.0Z"),
     "campaignId": "4c29dc888be98a9488e6876133852c72",
     "landingpageId": "c5557aedab04ad1444b0ee28b5ddaab9",
     "offerId": null,
     "trafficAccountId": "84d06369b9872e9a2685483b7a532a10",
     "serverId": "32",
     "browser": "Safari",
     "platform": "Android",
     "c1": "chat",
     "c2": "au",
     "c3": "12b-ad1a",
     "c4": "mtv2",
     "city": "Perth",
     "country": "Australia",
     "deviceType": "mobile",
     "isp": "Telstra Internet",
     "netspeedId": NumberLong(3),
     "set": "" 
  },
   "value": {
     "lpCount": 2,
     "offersCount": 0,
     "grandConversionCount": 0,
     "grandConversionAmount": 0 
  } 
}
Вот пример того, что должно получится на выходе
Код:
2014-12-24    |  50 lp clicks  |  21 offer clicks  | $600 // srv1 + srv2
  srv1        |  20 lp clicks  |  11 offer clicks  | $400 // campaign1 + campaign2
    campaign1 |  10 lp clicks  |   6 offer clicks  | $100
    campaign2 |  10 lp clicks  |   5 offer clicks  | $300
  srv2        |  30 lp clicks  |  10 offer clicks  | $200 // campaign3 + campaign4
    campaign3 |  20 lp clicks  |   4 offer clicks  | $100
    campaign4 |  10 lp clicks  |   6 offer clicks  | $100
Вот упрощенный пример запроса
db.clicks.aggregate([
  {$match: {'_id.dateVisited': new Date('2014-12-24')}},
  {$group:{
    _id: '$_id.dateVisited',
    totalLandingpageClicksCount: {$sum: '$value.landingpageClicksCount'},
    totalOfferTrackingsCount: {$sum: '$value.offerTrackingsCount'},
    totalOfferTrackingsAmount: {$sum: '$value.offerTrackingsAmount'}
  }}
])


В $match может быть включено несколько параметров (в зависимости что выберет пользователь), $group тоже может быть по нескольми параметрам, например по по dateVisited, serverId и campaignId и т.д.
Аггрегация для такой коллекции работает оочень медленно, т.к. на каждый dateVisited приходится ~10000 документов, и если пользователь захочет получить отчет за год, то $group должен обработать 365*10000=3650000 документов

Есть идеи, как спроектировать структуру БД, чтобы построение отчетов работало быстро?
Ответить с цитированием