Antwort

5

Es war geschlossen vor kurzem ein JIRA issue über einen $split Operator in der $project Stufe des Aggregations Framework verwendet werden.
Mit dem im Ort, den Sie eine Pipeline wie diese

db.yourColl.aggregate([ 
    { 
     $project: { 
      words: { $split: ["$foo", " "] } 
     } 
    }, 
    { 
     $unwind: { 
      path: "$words" 
     } 
    }, 
    { 
     $group: { 
      _id: "$words", 
      count: { $sum: 1 } 
     } 
    } 
]) 

Ergebnis wie so

/* 1 */ 
{ 
    "_id" : "baz", 
    "count" : 3.0 
} 

/* 2 */ 
{ 
    "_id" : "boo", 
    "count" : 2.0 
} 

/* 3 */ 
{ 
    "_id" : "bar", 
    "count" : 2.0 
} 
+0

Das sieht buchstäblich perfekt aus, danke. Ich werde es so schnell wie möglich testen und den Accept Button drücken, sollte es wie erwartet funktionieren. – user1381745

+0

Nur getestet mit Version 3.3.10 und funktioniert :) – DAXaholic

+0

@DAXaholic Wie kann ich das gleiche Problem behandeln, aber es sind Artikel, die andere Trennzeichen wie ein Komma enthalten? Vielen Dank – galgo

0

Der beste Weg, dies in MongoDB 3.4 $split Operator zu tun in aussehen würde schaffen könnte Ihre String aufgeteilt in ein Array von Teilstring wie erwähnt here und weil wir $unwind das Array in der Pipeline brauchen, müssen wir dies in einer Sub-Pipeline mit dem $facet Operator für maximale Effizienz tun.

db.collection.aggregate([ 
    { "$facet": { 
     "results": [ 
      { "$project": { 
       "values": { "$split": [ "$foo", " " ] } 
      }}, 
      { "$unwind": "$values" }, 
      { "$group": { 
       "_id": "$values", 
       "count": { "$sum": 1 } 
      }} 
     ] 
    }} 
]) 

, die produziert:

{ 
    "results" : [ 
     { 
      "_id" : "boo", 
      "count" : 2 
     }, 
     { 
      "_id" : "baz", 
      "count" : 3 
     }, 
     { 
      "_id" : "bar", 
      "count" : 2 
     } 
    ] 
} 

Von MongoDB 3.2 rückwärts, der einzige Weg, dies zu tun ist mit mapReduce.

var reduceFunction = function(key, value) { 
    var results = {}; 
    for (var items of Array.concat(value)) { 
     for (var item of items) { 
      results[item] = results[item] ? results[item] + 1 : 1; 
     } 
    }; 
    return results; 
} 

db.collection.mapReduce(
    function() { emit(null, this.foo.split(" ")); }, 
    reduceFunction, 
    { "out": { "inline": 1 } } 
) 

, die zurückgibt:

{ 
    "results" : [ 
     { 
      "_id" : null, 
      "value" : { 
       "bar" : 2, 
       "baz" : 3, 
       "boo" : 2 
      } 
     } 
    ], 
    "timeMillis" : 30, 
    "counts" : { 
     "input" : 3, 
     "emit" : 3, 
     "reduce" : 1, 
     "output" : 1 
    }, 
    "ok" : 1 
} 

Sie sollten eine .forEach() Methode in der reduzieren Funktion zu verwenden, prüfen, ob Ihre MongoDB-Version nicht die for...of Anweisung nicht unterstützt.