MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

agrupar por datas no mongodb

Nova resposta usando a estrutura de agregação do Mongo


Depois que essa pergunta foi feita e respondida, a 10gen lançou o Mongodb versão 2.2 com uma estrutura de agregação, que agora é a melhor maneira de fazer esse tipo de consulta. Essa consulta é um pouco desafiadora porque você deseja agrupar por data e os valores armazenados são carimbos de data/hora, portanto, você precisa fazer algo para converter os carimbos de data/hora em datas correspondentes. Para fins de exemplo, vou apenas escrever uma consulta que obtém as contagens corretas.
db.col.aggregate(
   { $group: { _id: { $dayOfYear: "$date"},
               click: { $sum: 1 } } }
   )

Isso retornará algo como:
[
    {
        "_id" : 144,
        "click" : 165
    },
    {
        "_id" : 275,
        "click" : 12
    }
]

Você precisa usar $match para limitar a consulta ao intervalo de datas em que você está interessado e $project para renomear _id para date . Como você converte o dia do ano de volta para uma data é deixado como exercício para o leitor. :-)

10gen tem um gráfico de conversão de SQL para Mongo Aggregation útil que vale a pena marcar. Há também um artigo específico sobre operadores de agregação de datas.

Ficando um pouco mais sofisticado, você pode usar:
db.col.aggregate([
  { $group: {
      _id: {
        $add: [
         { $dayOfYear: "$date"}, 
         { $multiply: 
           [400, {$year: "$date"}]
         }
      ]},   
      click: { $sum: 1 },
      first: {$min: "$date"}
    }
  },
  { $sort: {_id: -1} },
  { $limit: 15 },
  { $project: { date: "$first", click: 1, _id: 0} }
])

que lhe dará os últimos 15 dias e retornará algum datetime dentro de cada dia no date campo. Por exemplo:
[
    {
        "click" : 431,
        "date" : ISODate("2013-05-11T02:33:45.526Z")
    },
    {
        "click" : 702,
        "date" : ISODate("2013-05-08T02:11:00.503Z")
    },
            ...
    {
        "click" : 814,
        "date" : ISODate("2013-04-25T00:41:45.046Z")
    }
]