これを実用的でないものにするいくつかの問題があります:
- クエリはプロジェクションを実行する機能とは異なるパラメータであるため、プロジェクションはクエリの結果に影響されないため、単一のクエリだけではこれは不可能です。
- 集計フレームワークではフィールドを反復処理してタイプをチェックする方法がないため、これもオプションではありません
そうは言っても、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
}
]
}
マップは各プロパティを調べて、それが数字のように見えるかどうかを判断しています...そうであれば、オブジェクトとして格納される配列に追加して、map-reduceエンジンが配列の出力を妨げないようにします。サンプルコードでは単純にしています。数値と配列のチェックのロジックを確実に改善できます。 :)
もちろん、find
のように生きているわけではありません または集約ですが、MongoDBはこれを念頭に置いて設計されていないため、この機能が本当に必要な場合は、これを行う必要があるかもしれません。