Pergunta

Estou reunindo algumas estatísticas de um serviço da web e armazenando -o em uma coleção. Os dados parecem semelhantes a isso (mas com mais campos):

{"downloads": 30, "dt": "2010-02-17T16:56:34.163000"}
{"downloads": 30, "dt": "2010-02-17T17:56:34.163000"}
{"downloads": 30, "dt": "2010-02-17T18:56:34.163000"}
{"downloads": 30, "dt": "2010-02-17T19:56:34.163000"}
{"downloads": 30, "dt": "2010-02-17T20:56:34.163000"}
{…}
{"downloads": 30, "dt": "2010-02-18T17:56:34.163000"}
{"downloads": 30, "dt": "2010-02-18T18:56:34.163000"}
{"downloads": 30, "dt": "2010-02-18T19:56:34.163000"}
{"downloads": 30, "dt": "2010-02-18T20:56:34.163000"}

Se alguém solicitar os números diários nos últimos trinta dias, isso significaria a quantidade máxima de (neste exemplo) 'downloads'. dia. Que é o último registro do dia.

Usando collection.find({"dt": {"$gt": datetime_obj_30_days_ago}}), É claro que pego todas as linhas, o que não é muito adequado. Então, estou procurando uma maneira de devolver apenas o último dia para o período determinado.

Foi -me dito que group() Pode ser o caminho a percorrer, mas não consigo entender como fazê -lo funcionar nesse caso.

Quaisquer dicas, os ponteiros seriam muito apreciados!

Foi útil?

Solução

Você pode fazer isso usando grupo. No seu exemplo, você precisará fornecer uma função JavaScript para calcular a chave (também a função de redução), porque você deseja apenas o componente da data do campo DateTime. Isso deve funcionar:

db.coll.group(
    key='function(doc) { return {"dt": doc.dt.toDateString()} }',
    condition={'dt': {'$gt': datetime_obj_30_days_ago}},
    initial={'downloads': 0},
    reduce='function(curr, prev) { prev.downloads = Math.max(curr.downloads, prev.downloads) }'
)

Lembre -se de que ainda faz uma varredura linear do mês passado, apenas no servidor em vez do cliente. Isso é possível que simplesmente selecionar o valor máximo de cada dia individualmente é mais rápido.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top