MongoDB
 Computer >> コンピューター >  >> プログラミング >> MongoDB

MongoDBの集計処理中に文字列を分割する方法

MongoDBで集計処理を行いながら文字列を分割したい場合、mapReduce()メソッドを活用する方法があります。この記事では、実際のコード例を使いながら、コレクション内のドキュメントから氏名を取得し、名前を空白で分割して姓だけを抽出する手順を詳しく解説します。

1. コレクションの作成とドキュメントの挿入

まずは、サンプル用のコレクションを作成し、ドキュメントを挿入します。ここではinsertOne()メソッドを使用して、学生の氏名を含むドキュメントを登録します。

> db.splitString.insertOne({"StudentName":"John Smith"});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e0849d925ddae1f53b62206")
}

これでsplitStringコレクションに「John Smith」という氏名を持つドキュメントが1件登録されました。

2. 登録したドキュメントの確認

次に、find()メソッドを使って、コレクション内のすべてのドキュメントを表示して確認します。

> db.splitString.find().pretty();

実行すると、以下のような出力が得られます。

{
   "_id" : ObjectId("5e0849d925ddae1f53b62206"),
   "StudentName" : "John Smith"
}

3. mapReduce()を使って文字列を分割する

それでは本題の、文字列を分割するクエリを見ていきましょう。map関数の中でJavaScriptのsplit()メソッドを使い、氏名を空白文字(正規表現 /\s/)で分割します。さらにreverse()[0]で配列の最後の要素(つまり姓)を取り出し、toUpperCase()で大文字に変換しています。

> db.splitString.mapReduce(
...     function() {
...        var StudentLastName = this.StudentName.split(/\s/).reverse()[0].toUpperCase();
...
...        emit({ "StudentLastName": StudentLastName, "FirstObjectId": this._id },this);
...     },
...     function(){},
...     { "out": { "inline": 1 } }
... );

このクエリのポイントは以下の通りです。

  • map関数:各ドキュメントに対してthis.StudentNameを空白で分割し、末尾の要素(姓)を大文字化して変数に格納します。
  • emit()関数:分割・変換した「姓」と元のドキュメントの_idをキーとして結果を出力します。
  • reduce関数:今回は単純な分割処理のみのため、空の関数を指定しています。
  • outオプション{ "inline": 1 }を指定することで、結果を新しいコレクションに保存せず、その場でインライン表示します。

4. 実行結果の確認

上記のmapReduceを実行すると、以下のような出力が得られます。

{
   "results" : [
      {
         "_id" : {
            "StudentLastName" : "SMITH",
            "FirstObjectId" : ObjectId("5e0849d925ddae1f53b62206")
         },
         "value" : {
            "_id" : ObjectId("5e0849d925ddae1f53b62206"),
            "StudentName" : "John Smith"
         }
      }
   ],
   "timeMillis" : 32,
   "counts" : {
      "input" : 1,
      "emit" : 1,
      "reduce" : 0,
      "output" : 1
   },
   "ok" : 1
}

結果を見ると、_idフィールドにStudentLastNameとして「SMITH」が出力されていることがわかります。元の氏名「John Smith」から姓だけが正しく抽出され、大文字に変換されています。また、countsには入力ドキュメント数(input: 1)、emit回数(emit: 1)、出力数(output: 1)といった統計情報も含まれており、処理の状況を確認できます。

補足:アグリゲーションフレームワークでの代替手段

なお、MongoDB 4.2以降ではmapReduce()は非推奨となっており、最新バージョンでは削除されています。現在の開発では、アグリゲーションパイプラインの$split演算子や$arrayElemAt$toUpperなどを組み合わせることで、同様の文字列分割処理をより効率的に実現できます。新規プロジェクトでは、アグリゲーションフレームワークの利用を検討することをおすすめします。

  1. MongoDBのaggregateで$groupを使って複数の集計結果を一度に取得する方法

    MongoDBでは、$facetと$groupを組み合わせることで、1回のaggregateクエリで複数の集計結果を同時に取得できます。この記事では、実際のコード例を通じてその方法を解説します。サンプルコレクションの作成まず、ドキュメントを含むコレクションを作成しましょう。以下のようにinsertOne()メソッドを使ってデータを挿入します。> db.demo765.insertOne( ... { ... Name:John, ... Category:ComputerScience, ... SubjectName:MongoDB,

  2. Pythonで文字列を指定サイズ(N文字)ごとに分割する方法

    問題の概要 文字列 s と整数 n が与えられたとき、s を n 文字ずつの部分文字列に分割することを考えます。 例えば、入力が s = abcdefghijklmn、n = 4 の場合、出力は [abcd, efgh, ijkl, mn] となります。最後の断片が n 文字に満たない場合でも、残りの文字列がそのまま出力される点に注意してください。 解決のアプローチ この問題は、以下の手順で解くことができます。 インデックス i を 0 で初期化します。 結果を格納するための空のリスト f を用意します。 i が文字列の長さ未満である間、次の処理を繰り返します。 s[i : i+n](イ