Existuje několik problémů, kvůli kterým to není praktické:
- Vzhledem k tomu, že dotaz je parametr, který se odlišuje od schopnosti provádět projekci, není to možné pouze z jednoho dotazu, protože projekci nelze ovlivnit výsledky dotazu.
- Vzhledem k tomu, že s agregačním rámcem neexistuje žádný způsob, jak iterovat pole a kontrolovat typ, ani to není možnost
Jak již bylo řečeno, existuje trochu šílený způsob použití Map-Reduce, který dostává podobné odpovědi, i když ve výstupu ve stylu Map-Reduce, který není úžasný:
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;
};
Není to kompletní, ale výsledky jsou podobné tomu, co jste chtěli:
"_id" : ObjectId("52fac254f40ff600c10e56d4"),
"value" : {
"n" : [
{
"f" : "list",
"v" : [
1,
2,
3,
4,
5
]
},
{
"f" : "views",
"v" : 5
}
]
}
Mapa se právě dívá na každou vlastnost a rozhoduje se, zda vypadá jako číslo... a pokud ano, přidává do pole, které bude uloženo jako objekt, aby se modul map-reduce neškrtil výstupem pole. V ukázkovém kódu jsem to ponechal jednoduché - určitě byste mohli zlepšit logiku kontroly čísel a polí. :)
Samozřejmě to není živé jako find
nebo agregace, ale protože MongoDB nebyl navržen s ohledem na toto, možná to bude stačit, pokud tuto funkci opravdu chcete.