Ci sono alcuni problemi che rendono questo non pratico:
- Poiché la query è un parametro distintivo dalla capacità di eseguire una proiezione, ciò non è possibile da una singola query, poiché la proiezione non può essere influenzata dai risultati della query
- Dato che non c'è modo con il framework di aggregazione di iterare i campi e controllare il tipo, anche questa non è un'opzione
Detto questo, c'è un modo un po' strano di usare un Map-Reduce che ottiene risposte simili, anche se in un output in stile Map-Reduce che non è eccezionale:
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;
};
Non è completo, ma i risultati sono simili a quelli che volevi:
"_id" : ObjectId("52fac254f40ff600c10e56d4"),
"value" : {
"n" : [
{
"f" : "list",
"v" : [
1,
2,
3,
4,
5
]
},
{
"f" : "views",
"v" : 5
}
]
}
La mappa sta solo esaminando ogni proprietà e decidendo se assomiglia a un numero ... e in tal caso, aggiungendo a un array che verrà archiviato come oggetto in modo che il motore di riduzione della mappa non si strozzi sull'output dell'array. L'ho mantenuto semplice nel codice di esempio:potresti sicuramente migliorare la logica del controllo numerico e degli array. :)
Ovviamente, non è live come un find
o aggregazione, ma poiché MongoDB non è stato progettato con questo in mente, potrebbe essere necessario se volevi davvero questa funzionalità.