Existem alguns problemas que tornam isso não prático:
- Como a consulta é um parâmetro distinto da capacidade de fazer uma projeção, isso não é possível apenas com uma única consulta, pois a projeção não pode ser influenciada pelos resultados da consulta
- Como não há como a estrutura de agregação iterar campos e verificar o tipo, isso também não é uma opção
Dito isto, há uma maneira um pouco maluca de usar um Map-Reduce que obtém respostas semelhantes, embora em uma saída de estilo Map-Reduce que não seja incrível:
map = function() {
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
var numerics = [];
for(var fn in this) {
if (isNumber(this[fn])) {
numerics.push({f: fn, v: this[fn]});
}
if (Array.isArray(this[fn])) {
// example ... more complex logic needed
if(isNumber(this[fn][0])) {
numerics.push({f: fn, v: this[fn]});
}
}
}
emit(this._id, { n: numerics });
};
reduce = function(key, values) {
return values;
};
Não está completo, mas os resultados são semelhantes ao que você queria:
"_id" : ObjectId("52fac254f40ff600c10e56d4"),
"value" : {
"n" : [
{
"f" : "list",
"v" : [
1,
2,
3,
4,
5
]
},
{
"f" : "views",
"v" : 5
}
]
}
O mapa está apenas olhando para cada propriedade e decidindo se ela se parece com um número ... e se for, adicionando a uma matriz que será armazenada como um objeto para que o mecanismo de redução de mapa não engasgue com a saída da matriz. Eu mantive simples no código de exemplo - você pode melhorar a lógica da verificação numérica e de matriz com certeza. :)
Claro, não é ao vivo como um
find
ou agregação, mas como o MongoDB não foi projetado com isso em mente, isso pode ter que ser feito se você realmente quiser essa funcionalidade.