TLDR;
O equivalente do mangusto seria executar a consulta aninhada primeiro e passar os resultados para a agregação.
groups.distinct("p", {"enable": true}).exec().then(matchingGroups => {
return users.aggregate([
{$match: {"id": {$in: ["0", "1", "2"]}, p: {$in: matchingGroups}}},
{$group:{_id:"$v", number:{$sum:1 }}}
]).exec();
}).then(aggregationResult => {
console.log(aggregationResult);
});
Explicação
Ao executar o script a seguir no shell do mongo, o que acontece é que a consulta interna (distinta) é enviada primeiro e, em seguida, o resultado é passado para a consulta externa (agregação) que é enviada para execução. Isso pode ser confirmado capturando um rastreamento de pacote. Nas imagens anexadas, podemos ver o primeiro envio de consulta (pacote 9) a resposta recebida (pacotes 10 e 11) e o envio de consulta de agregação a> (pacotes 12 e 13).