Има няколко проблема, които правят това непрактично:
- Тъй като заявката е отличителен параметър от възможността за извършване на проекция, това не е възможно само от една заявка, тъй като проекцията не може да бъде повлияна от резултатите на заявката
- Тъй като няма начин с рамката за агрегиране да се повтарят полетата и да се проверява типът, това също не е опция
Като се има предвид това, има малко шантав начин за използване на Map-Reduce, който получава подобни отговори, макар и в изход в стил Map-Reduce, който не е страхотен:
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;
};
Не е пълно, но резултатите са подобни на тези, които искахте:
"_id" : ObjectId("52fac254f40ff600c10e56d4"),
"value" : {
"n" : [
{
"f" : "list",
"v" : [
1,
2,
3,
4,
5
]
},
{
"f" : "views",
"v" : 5
}
]
}
Картата просто разглежда всяко свойство и решава дали изглежда като число ... и ако е така, добавя към масив, който ще бъде съхранен като обект, така че машината за намаляване на картата да не се задуши в изхода на масива. Опростих го в примерния код - със сигурност бихте могли да подобрите логиката на проверката на числата и масивите. :)
Разбира се, не е на живо като find
или агрегиране, но тъй като MongoDB не е проектиран с това предвид, това може да се наложи, ако наистина искате тази функционалност.