var map = function(){
var name = this.op.includes("android") ? "Android" : ""; // could be a regexp
if(name === ""){
name = this.op.includes("windows") ? "Windows" : "";
}
emit(name, 1);
}
var reduce = function(key, values){
return Array.sum(values)
}
db.operating.mapReduce(map, reduce, {out: "total"})
コンテンツ、その後、再構築する前に、配列から最後の要素を削除します。
を考えると、データのように:
{ "name" : "Android 6.0" }
{ "name" : "Android 7.0" }
{ "name" : "Windows Phone 10" }
あなたは試すことができます。すべてのことが可能です
db.getCollection('phones').aggregate([
{ "$group": {
"_id": {
"$let": {
"vars": { "split": { "$split": [ "$name", " " ] } },
"in": {
"$reduce": {
"input": { "$slice": [ "$$split", 0, { "$subtract": [ { "$size": "$$split" }, 1 ] } ] },
"initialValue": "",
"in": {
"$cond": {
"if": { "$eq": [ "$$value", "" ] },
"then": "$$this",
"else": { "$concat": [ "$$value", " ", "$$this" ] }
}
}
}
}
}
},
"count": { "$sum": 1 }
}},
{ "$replaceRoot": {
"newRoot": {
"$arrayToObject": [[{ "k": "$_id", "v": "$count" }]]
}
}}
])
をあなたのMongoDBは$split
と$reduce
の両方をサポートするために、少なくともMongoDBは3.4である場合。 $replaceRoot
は本当にキーの名前をつけることであり、実際には必要ありません。
代わりに、あなたはmapReduce
を使用することができます:それは簡単だ
db.getCollection('phones').mapReduce(
function() {
var re = /\d+/g;
emit(this.name.substr(0,this.name.search(re)-1),1);
},
function(key,values) { return Array.sum(values) },
{ "out": { "inline": 1 } }
)
を数値が発生したインデックスで文字列を打破します。いずれの場合でも、何も "ハードコード"する必要はなく、キーの値は文脈の中の文字列に完全に依存しています。
可能な値が非常に多い場合を除き、カーソルの数を返すので集計されたエントリを実際にカウントするよりも速く処理する必要があります。
この場合、アグリゲーションフレームワークは最適なソリューションではありません。 –