4

全体の文字列フィールドの中で最も一般的に使用される単語を見つけることの私は、次のようなMongoのコレクションを持っているとしましょう:コレクション

[ 
    { "foo": "bar baz boo" }, 
    { "foo": "bar baz" }, 
    { "foo": "boo baz" } 
] 

は(理想的には、ほとんどの場合、fooフィールド内に表示された単語を決定することが可能ですカウントあり)?例えば

、私のような何かの結果セットをみたい:

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

答えて

5

あり、最近集約フレームワークの$project段階で使用する$splitオペレータについてJIRA issueを閉じました。あなたの文字列を分割する$split演算子を使用してそう

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

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

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

それは文字通り完璧に見える、ありがとう。私はできるだけ早くそれをテストに入れ、期待通りに動作するかどうか受け入れボタンを押します。 – user1381745

+0

ちょうどバージョン3.3.10とそれをテストして働いた:) – DAXaholic

+0

@DAXaholicどのように私は同じ問題を処理できますか?カンマのような他の区切り文字を含む記事ですか?ありがとう – galgo

0

ようにMongoDB 3.4でこれをで行うための最善の方法を見てしまう。この

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

結果のようなパイプラインを作成することができる場所にそれと
前述のように配列の配列にhere$unwindパイプラインで配列をダウンする必要があるので、最大効率のために$facet演算子を使ってサブパイプラインでこれを行う必要があります。生成

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

:後方のMongoDB 3.2から

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

は、これを行うための唯一の方法は、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 } } 
) 

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

をあなたのMongoDBのバージョンがfor...of文をサポートしていない場合機能を減らす.forEach()方法を使用することを検討すべきです。

関連する問題