Det finns några problem som gör detta inte praktiskt:
- Eftersom frågan är en särskiljande parameter från förmågan att göra en projektion, är detta inte möjligt från en enda fråga, eftersom projektionen inte kan påverkas av resultatet av frågan
- Eftersom det inte finns något sätt med aggregeringsramverket att iterera fält och kontrollera typ, är det inte heller ett alternativ
Med det sagt, det finns ett lite skumt sätt att använda en Map-Reduce som får liknande svar, om än i en Map-Reduce-stil som inte är fantastisk:
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;
};
Det är inte komplett, men resultaten liknar det du ville ha:
"_id" : ObjectId("52fac254f40ff600c10e56d4"),
"value" : {
"n" : [
{
"f" : "list",
"v" : [
1,
2,
3,
4,
5
]
},
{
"f" : "views",
"v" : 5
}
]
}
Kartan tittar bara på varje egenskap och bestämmer om det ser ut som ett nummer ... och i så fall läggas till en array som kommer att lagras som ett objekt så att kartreduceringsmotorn inte chokerar på arrayutdata. Jag har hållit det enkelt i exempelkoden -- du kan säkert förbättra logiken för numerisk och matriskontroll. :)
Naturligtvis är det inte live som ett find
eller aggregering, men eftersom MongoDB inte utformades med detta i åtanke, kan detta behöva göras om du verkligen vill ha den här funktionen.