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

MongoDBで「work」を含むログだけを抽出する方法|aggregate()と$filterの使い方

MongoDBで、配列内の要素から特定のキーワード(この例では「work」)を含むログだけを抽出したい場合、aggregate()メソッドと$filter演算子を組み合わせるのが効果的です。この記事では、実際のコード例を通じて、その手順をわかりやすく解説します。

サンプルコレクションの作成

まず、insertOne()メソッドを使って、サーバーログの配列を持つドキュメントを含むコレクションを作成しましょう。

> db.demo383.insertOne(
...     {
...        "ServerName":"Jboss",
...        "ServerLogs": [
...           {
...              "status":"Working"
...           },
...           {
...              "status":"Stop"
...           },
...           {
...              "status":"Worked"
...           }
...        ]
...     }
... );
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5e5b635422064be7ab44e7f1")
}

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

find()メソッドを使えば、コレクション内のすべてのドキュメントを表示できます。

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

上記のコマンドを実行すると、次のような出力が得られます。

{
    "_id" : ObjectId("5e5b635422064be7ab44e7f1"),
    "ServerName" : "Jboss",
    "ServerLogs" : [
       {
          "status" : "Working"
       },
       {
          "status" : "Stop"
       },
       {
          "status" : "Worked"
       }
    ]
}

$filterを使ったフィルタリングクエリ

ここからが本題です。aggregate()パイプラインの中で$addFields$filterを組み合わせ、ServerLogs配列から「work」という文字列を含むステータスのみを残すクエリは以下の通りです。

> db.demo383.aggregate([
...    { "$addFields": {
...       "ServerLogs": {
...          "$filter": {
...             "input": "$ServerLogs",
...             "cond": {
...                "$ne": [
...                   { "$indexOfBytes": [
...                      { "$toUpper": "$$this.status" },
...                      { "$toUpper": "work" }
...                   ]},
...                   -1
...                ]
...             }
...          }
...       }
...    }}
... ])

このクエリのポイントは、$toUpperでドキュメント側の値と検索キーワードの両方を大文字に揃えてから比較している点です。これにより、大文字・小文字の違いを意識せずに部分一致の判定ができます。$indexOfBytesの戻り値が-1以外(=該当する文字列が見つかった)の場合のみ、その要素が結果に残ります。

実行結果

クエリを実行すると、以下のように「work」を含むステータスだけが抽出されます。「Stop」は条件に合致しないため除外されていることがわかります。

{
    "_id" : ObjectId("5e5b635422064be7ab44e7f1"), "ServerName" : "Jboss", "ServerLogs" : [
       { "status" : "Working" }, { "status" : "Worked" }
    ] 
}

まとめ

aggregate()$filter、さらに$indexOfBytesを組み合わせることで、MongoDBでも柔軟な部分一致による配列フィルタリングが可能になります。大文字・小文字を区別したくない場合は、$toUpper(または$toLower)で値を正規化してから比較するのがポイントです。サーバーログやアクセスログなど、大量の配列データから特定のキーワードを含むレコードだけを取り出したい場面で、ぜひ活用してみてください。

  1. 【MongoDB】ロールに基づいて「名前」フィールドのみを取得するaggregate()クエリの実装方法

    ロールに基づいて「Name」フィールドのみを抽出するにはMongoDBで特定のロール(Admin・Guest・Userなど)の条件に基づいて「Name」フィールドのみを取得したい場合は、aggregate()メソッドを使用します。この記事では、3つのロール(Admin、Guest、User)を持つサンプルデータを用いて、その具体的な手順を解説します。1. サンプルコレクションの作成まず、insertOne()を使ってドキュメントを含むコレクションを作成します。> db.demo532.insertOne({Name:Chris,Type:Admin}); { acknowledge

  2. 【MongoDB】ネストされた(入れ子構造の)ドキュメントを更新するクエリの書き方

    MongoDBでは、入れ子(ネスト)になったサブドキュメントのフィールドを更新する際、update()メソッドとドット表記(dot notation)を組み合わせて使用します。ドット表記を使うことで、深い階層にあるフィールドを直接指定して値を変更できます。1. サンプルコレクションの作成まず、ネストされたドキュメントを含むコレクションを作成しましょう。以下のコマンドでdemo607というコレクションにドキュメントを挿入します。> db.demo607.insertOne( ... { ... id: 1, ... Info1 : { ...