2013-02-22 3 views
3

Мне было интересно, может ли кто-нибудь помочь мне получить мою функцию агрегации правильно. Я пытаюсь подсчитать количество раз, когда часть текста появляется в час в указанный день. До сих пор я получил:Агрегация: подсчет товаров в час

db.daily_data.aggregate(
    [ 
    { $project : { useragent: 1, datetime: 1, url: 1, hour: {$hour: new Date("$datetime")} } }, 
    { $match : { datetime: {$gte: 1361318400000, $lt: 1361404800000}, useragent: /.*LinkCheck by Siteimprove.*/i } }, 
    { $group : { _id : { useragent: "$useragent", hour: "$hour" }, queriesPerUseragent: {$sum: 1} } } 
    ] 
); 

Но я, очевидно, получить это неправильно, как час всегда 0:

{ 
    "result" : [ 
    { 
     "_id" : { 
     "useragent" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.0) LinkCheck by Siteimprove.com", 
     "hour" : 0 
     }, 
     "queriesPerUseragent" : 94215 
    } 
    ], 
    "ok" : 1 
} 

Вот урезана пример записи тоже:

{ 
    "_id" : ObjectId("50fe63c70266a712e8663725"), 
    "useragent" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.0) LinkCheck by Siteimprove.com", 
    "datetime" : NumberLong("1358848954813"), 
    "url" : "http://www.somewhere.com" 
} 

Я также пытался использовать new Date("$datetime").getHours() вместо функции $hour, чтобы попытаться получить тот же результат, но не повезло. Может ли кто-нибудь указать мне в сторону, где я ошибаюсь?

Спасибо!

+1

Функция $ hour предполагает, что у вас есть формат ISODate() или Date(), и пока нет формата даты, установленного в инфраструктуре agg (хотя для него есть билет jira). –

ответ

3

Это рекомендация скорее ответ на вашу проблему.

В MongoDB для аналитики рекомендуется предварительно агрегировать ваши ведра (почасовые ведра в вашем случае использования) для каждого показателя, который вы хотите рассчитать.

Таким образом, для метрики вы можете обновить предварительно агрегированных коллекцию (ускоряя время запроса):

db.user_agent_hourly.update({url: "your_url", useragent: "your user agent", hour: current_HOUR_of_DAY, date: current_DAY_Date}, {$inc: {counter:1}}, {upsert:true}) 

Примите во внимание, что в current_DAY_Date вы должны указывать на стабильное значение даты для текущего дня , т. е. current_year/current_month/current_day 00:00:00, используя тот же час: минута: вторая для каждой метрики, полученной в текущий день.

Затем, вы можете запросить эту коллекцию, извлекая агрегированную аналитику для любого заданного периода времени следующим образом:

db.user_agent_hourly.aggregate(
    {$match:{date:{$gte: INITIAL_DATE, $lt: FINAL_DATE}}}, 
    {$group:{ _id : { useragent: "$useragent", hour: "$hour" } ,queriesPerUseragent: {$sum: "$count"} } }, 
    {$sort:{queriesPerUseragent:-1}} 
) 

Если вы хотите, чтобы отфильтровать результаты с помощью специального агента пользователя, вы можете использовать следующий запрос :

db.user_agent_hourly.aggregate(
    {$match:{date:{$gte: INITIAL_DATE, $lt: FINAL_DATE, useragent: "your_user_agent"}}}, 
    {$group:{ _id : { useragent: "$useragent", hour: "$hour" }, queriesPerUseragent: {$sum: "$count"} } } 
) 

PS: Мы храним каждый получил метрику в другой коллекции, чтобы быть в состоянии переработать его в случае стихийного бедствия или других потребностей.