2016-05-12 9 views
0

Ich bin sehr neu in MongoDB und ich möchte Aggregation verwenden, um das folgende Problem zu lösen. Ich habe eine Sammlung so.MongoDB: Zählen von Werten aus Feld, deren Werte ein Array ist

{ 
"_id" : ObjectId("5732fa438acef72abc442ac8"), 
"publisherId" : NumberInt(1), 
"type" : NumberInt(3), 
"qualityInfo" : [ 
    "FilterOne", 
    "FilterTwo", 
    "FilterThree" 
], 
"date" : "2016-05-11 11:24:19" 
} 
{ 
    "_id" : ObjectId("5732fa438acef72abc442ac9"), 
    "publisherId" : NumberInt(3), 
    "type" : NumberInt(1), 
    "qualityInfo" : [ 
     "FilterOne", 
     "FilterFour" 
    ], 
    "date" : "2016-05-11 11:24:19" 
} 

Ich mag das Auftreten jeden Wertes in qualityInfo Feld und das Ergebnis auszugeben etwas wie die folgenden zählen.

{ 
"_id" : "FilterOne", 
"count" : "42" 
} 
{ 
    "_id" : "FilterTwo", 
    "count" : "30" 
} 
{ 
    "_id" : "FilterThree", 
    "count" : "12" 
} 
{ 
    "_id" : "FilterFour", 
    "count" : "43" 
} 

Ich würde es vorziehen, dies durch Aggregation zu erreichen, wie ich bemerkt habe, dass Aggregation Operationen sind viel schneller als MapReduce. Bitte korrigieren Sie mich, wenn ich sonst falsch liege. Also ist es möglich, es durch Aggregation zu machen? Falls nicht, habe ich bereits eine MapReduce-Abfrage wie folgt versucht.

db.myCollection.mapReduce(
function(){ 
    for(i = 0; i < this.qualityInfo.length; i++ ){ 
     emit(this.qualityInfo[i], null); 
    } 
}, 
function(names, vals){ 
    return Array.sum(names); 
}, 
{ query: { publisherId: 2 }, out: "qualityResult" } 

);

Aber das gibt mir keinen Zählwert. Gibt einfach die Namenszeichenfolge in _id und value im MapReduce-Ergebnis zurück.

Antwort

1

Verwenden Sie Mongodb-Aggregation ist es eine einfache Zeile Befehl.

db.collection.aggregate([ 
    { $unwind:"$qualityInfo"}, 
    { $project: {"qualityInfo":1} }, 
    { $group:{ 
      _id:"$qualityInfo", 
      count: {$sum:1}}´ 
    } 
]); 
+0

Diese Abfrage gibt mir ein leeres Ergebnis. Gar nichts. –

+0

Ok, ich habe das Problem. '$ project' sollte vor' $ unwind' kommen. Und ich habe auch eine '$ match 'in meiner Anfrage, die ich am Anfang gestellt habe. So funktioniert es. Vielen Dank! –

+0

froh, dass es funktioniert. Meiner Meinung nach sollte die $ -Projektion kein Problem verursachen, da es nur eine Option ist, um zur nächsten Stufe zu gehen, ich denke, Sie haben $ match von etwas, was hier nicht sichtbar ist und das Problem verursacht hat. – AMITAVA

1

Sie sind fast da, indem Sie Map reduzieren. Verwenden Sie die folgenden Karten reduzieren Funktionen:

db.myCollection.mapReduce(
function(){ 
    for(i = 0; i < this.qualityInfo.length; i++ ){ 
     emit(this.qualityInfo[i], 1); 
    } 
}, 
function(names, vals){ 
    return Array.sum(vals); 
}, 
{ query: { publisherId: 2 }, out: "qualityResult" } 
); 

von „1“ emittiert, wie Sie pro filter schätzen, erhalten Sie Ergebnisse wie

{_id: "filterOne", values[1,1,1]}, 
{_id: "filterTwo", values[1,1]} 

Durch die Array.sum mit den Werten zu tun, erhalten Sie die Anzahl der Vorkommen jedes Filters.

+0

Dies funktionierte. Vielen Dank. Allerdings habe ich mehr als 8 Millionen Dokumente und diese Lösung ist sehr langsam. Ich habe die Aggregationsabfrage von AMITAVA verwendet, die für mich besser funktioniert hat. Nochmals vielen Dank. :) –