0

Использование mongodb через mongoose в моем node.js проекта. Мои документы имеют следующую структуру:Группа по дате несколько переменных

{ created: new Date("2014-12-24"), last_visited: new Date("2014-12-24") }, 
{ created: new Date("2014-12-16"), last_visited: new Date("2014-12-24") }, 
{ created: new Date("2014-12-13"), last_visited: new Date("2014-12-13") }, 
{ created: new Date("2014-12-12"), last_visited: new Date("2014-12-20") }, 
{ created: new Date("2010-01-01"), last_visited: new Date("2014-12-20") } 

Я хочу показать, как были созданы/обновлены на определенную дату в течение последних 30 дней много документов. Таким образом, выход должен быть следующим:

{ date: ISODate("2014-12-12"), created: 2, last_visited: 0 }, 
{ date: ISODate("2014-12-13"), created: 1, last_visited: 0 }, 
{ date: ISODate("2014-12-16"), created: 1, last_visited: 0 }, 
{ date: ISODate("2014-12-20"), created: 0, last_visited: 2 }, 
{ date: ISODate("2014-12-22"), created: 0, last_visited: 1 }, 
{ date: ISODate("2014-12-24"), created: 0, last_visited: 2 }, 

Уведомление о том, что год 2010 года был пропущен из-за того, что он старше 30 дней.

Как я могу это сделать?

+0

Могу ли я просто сказать, что * «Я написал дату таким образом, чтобы быть коротким здесь» * действительно это ужасный способ представить это. Должны ли мы действительно читать весь ваш контент, чтобы понять, что это на самом деле ISODate или действительно ** Объекты BSON Date **? Почему бы не использовать [** '$ gt' **] (http://docs.mongodb.org/manual/reference/operator/query/gt/) с даты 30 дней назад? –

+0

Не ужасно вообще, потому что некоторые могут подумать, что даты хранятся как текст в БД и каким-то образом должны быть преобразованы в формат даты в запросе. – kaytrance

+0

Нет Ужасно. Дата типа «String». Это также не «лексический», что означает операторы диапазона, такие как ** $ gt ** и ** $ lt **, а кузены не работают. Дополнительный ** факт ** заключается в том, что «String» занимает ** больше памяти **, чем дата BSON, которая является «Long Integer» с маркером «type», чтобы показать, что это дата. Даты являются полезными типами, когда вы хотите их сохранить. Использование чего-либо еще в основном неправильное. –

ответ

1

карта уменьшить проблему:

var old = new Date(); 
old.setDate(old.getDate()-30); 

var filter = { created : {$gt : old}, last_visited : {$gt : old} }; 

var map = function() 
{   
    emit(this.created, {created : 1, last_visited : 0 });  
    emit(this.last_visited, {created : 0, last_visited : 1 });  
} 

var reduce = function(key, values) 
{ 
    var out = {created : 0, last_visited : 0 }; 

    for(i in values) 
    { 
     var value = values[i]; 
     if(value.created != 0) 
     { 
      out.created++; 
     } 
     else 
     { 
      out.last_visited++; 
     } 
    } 

    return out; 
} 

db.runCommand(
       { 
       mapReduce: "test2", 
       map: map, 
       reduce: reduce,     
       out: { "inline": 1 }, 
       query: filter 
       } 
      ).results 
+2

Пригвожденный +1. Но вы должны исправить вариант «out», который не должен быть действительно действительным или хорошим примером для других драйверов. –

+0

Как насчет части вопроса, где я хочу только последние 30 дней, чтобы быть отраженным? Решение, похоже, не используется с мангустом. – kaytrance

+1

@Quest Не имеет значения, чем использовать опцию ** query ** на [mapReduce] (http://docs.mongodb.org/manual/reference/command/mapReduce/), как я уже упоминал. Также «out» должен быть «{« out »: {" inline ": 1}}' или '{" out ": {" replace ":" out "}}', как уже упоминалось. См. Опции ["out"] (http://docs.mongodb.org/manual/reference/command/mapReduce/#out-options) в руководстве. –

1

Попробуйте это

db.users.aggregate([ 
    {$group: { 
      "_id": { 
       month: {$month: "$created"}, 
       day: {$dayOfMonth: "$created"}, 
       year: {$year: "$created"}, 
      }, 
      date: {$max: '$created'}, 
      created: {$sum: 1}, 
      last_visited: {$sum: 1}, 
     }}, 
     {$sort: { 
      'date': -1 
     }} 
]) 

Благодаря