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

É possível classificar, agrupar e limitar de forma eficiente no Mongo com um pipeline?


Para responder sua primeira pergunta:$group não preservar a ordem. Há uma solicitação de alterações em aberto que também destaca um pouco os fundos, mas não parece que o produto será alterado para preservar a ordem dos documentos de entrada:

Em geral, duas coisas podem ser ditas:você geralmente deseja agrupar primeiro e depois fazer a classificação. A razão é que classificar menos elementos (que o agrupamento geralmente produz) será mais rápido do que classificar todos os documentos de entrada.

Em segundo lugar, o MongoDB vai certificar-se de classificar da forma mais eficiente e o menos possível. A documentação afirma:

Portanto, este código faz o trabalho no seu caso:
collection.aggregate({
    $group: {
        _id: '$age',
        names: { $push: '$name' }
    }
}, {
    $sort: { 
        '_id': 1 
    }
}, {
    $limit: 10
})

EDITAR seguindo seus comentários:

Eu concordo com o que você diz. E levando sua lógica um pouco mais longe, eu diria:If $group era inteligente o suficiente para usar um índice, então não deveria nem exigir um $sort etapa no início. Infelizmente, não é (ainda não provavelmente). Como as coisas estão hoje, $group nunca usará um índice e não terá atalhos com base nas seguintes etapas ($limit nesse caso). Veja também este link onde alguém executou alguns testes básicos.

A estrutura de agregação ainda é muito jovem, então acho que há muito trabalho sendo feito para tornar o pipeline de agregação mais inteligente e rápido.

Há respostas aqui no StackOverflow (por exemplo, aqui ) onde as pessoas sugerem usar um $sort inicial stage para "forçar" o MongoDB a usar um índice de alguma forma. Isso, no entanto, desacelerou meus testes (1 milhão de registros de sua forma de amostra usando diferentes distribuições aleatórias) significativamente.

Quando se trata de desempenho de um pipeline de agregação, $match estágios no início são o que realmente ajuda mais. Se você puder limitar a quantidade total de registros que precisam passar pelo pipeline desde o início, essa é sua melhor aposta - obviamente...;)