Como já mencionado por @Blakes Seven, $group não pode usar índices. Consulte este tópico .
Assim, sua consulta já está ótima. Uma maneira possível de otimizar esse caso de uso é pré-calcular e persistir os dados em uma coleção paralela.
Você pode tentar esta estrutura de dados:
{
"_id" : ObjectId("560a5139b56a71ea60890201"),
"ccy" : "USDNOK",
"date_time_first" : ISODate("2007-01-01T00:00:07.904Z"),
"date_time_last" : ISODate("2007-09-09T00:00:07.904Z")
}
Consultar isso pode ser feito em milissegundos em vez de mais de 500 segundos e você pode se beneficiar dos índices.
Então, é claro, cada vez que você adiciona, atualiza ou exclui um documento da coleção principal, você precisa atualizar a coleção secundária.
Dependendo de quanto você precisa que os dados sejam "frescos", você também pode optar por pular esse "processo de atualização ao vivo" e regenerar inteiramente a coleta lateral apenas uma vez por dia com um lote e lembre-se de que seus dados podem não ser " fresco".
Outro problema que você pode corrigir:seu servidor definitivamente precisa de mais RAM e CPU. Seu conjunto de trabalho provavelmente não cabe na RAM, especialmente com esse tipo de agregação.
Além disso, você provavelmente pode fazer bom uso de um SSD e eu FORTEMENTE recomendo usar um Replicaset de 3 nós em vez de uma única instância para produção.