基本を超えて:データ分析のための高度なMongoDBクエリコマンド

高度なMongoDBフィルター、プロジェクション、集約ステージを使用して、データをデータベースから移動せずに分析します。

基本を超えて:データ分析のための高度なMongoDBクエリコマンド

MongoDBクエリは、単純なfind()呼び出しを超えるとさらに有用になります。ネストされたドキュメントをフィルタリングしたり、出力を再形成したり、グループ化された結果を計算する必要がある場合、高度なクエリ演算子と集約ステージを使用すると、データに近い場所でその作業を行うことができます。

以下の例は、レポート作成、トラブルシューティング、および一回限りの分析のためにmongoshで実行できる実用的なコマンドに焦点を当てています。

クエリ演算子による複雑なフィルタリングの習得

基本的なfind()メソッドは単純な等価チェックを処理しますが、高度な分析では、複数の条件を組み合わせたり、特定のフィールド構造をクエリしたりする必要がよくあります。MongoDBは、詳細なフィルターを構築するための豊富なクエリ演算子セットを提供します。

複合クエリのための論理演算子

論理演算子を使用すると、複数のクエリ条件を組み合わせることができ、どのドキュメントが返されるかを細かく制御できます。これらは複雑な分析質問を構造化するために不可欠です。

  • $and / 暗黙の$and:すべてが真でなければならない複数の基準を指定するために使用されます。多くの場合暗黙的ですが(クエリオブジェクト内で条件を順にリストする)、同じフィールドを複数回クエリする場合には$andが必要です。
    // 暗黙の$and:25歳以上でニューヨークに住むユーザーを検索
    db.users.find({ age: { $gt: 25 }, city: "New York" });
    
    // 明示的な$and:'score'が90より大きいか、'level'が5であるドキュメントを検索
    db.results.find({ $and: [ { score: { $gt: 90 } }, { level: 5 } ] });
    
  • $or:指定された式の配列のいずれかに一致するドキュメントを選択します。
    db.products.find({ $or: [ { category: "Electronics" }, { price: { $lt: 100 } } ] });
    
  • $not:指定された式の結果を否定します。

地理空間演算子と配列演算子

位置ベースのデータや複雑な配列の場合、特殊な演算子が分析力を提供します:

  • $geoWithin / $near:特定の地理的領域または近接範囲内のデータを見つけるために不可欠です。
  • $elemMatch:埋め込みドキュメントの配列をクエリするために重要であり、配列内の1つの要素が$elemMatch内で指定されたすべての基準に一致することを保証します。
    // 'items'配列内の少なくとも1つのアイテムが500を超える価格で、数量が1より大きい注文を検索
    db.orders.find({ items: { $elemMatch: { price: { $gt: 500 }, qty: { $gt: 1 } } } });
    

高度なプロジェクション:出力の整形

find()メソッドの2番目の引数で管理されるプロジェクションは、どのフィールドが返されるかを決定します。高度なプロジェクションは、単純な包含/除外を超えて、返されるデータを変換または整形します。

フィールドの除外と包含

  • 1はフィールドを含め、0はフィールドを除外します。
  • 重要な注意_idフィールドを除き、包含(1)と除外(0)を混在させることはできません(_idはデフォルトで含まれ、0に設定することで明示的に除外できます)。
// 'name'と'email'のみを含め、'_id'を除外
    db.users.find({}, { name: 1, email: 1, _id: 0 });

配列のスライスと操作

プロジェクションは、$sliceを使用して返される配列要素の数を制限できます:

  • $slice: N:最初のN個の要素を返します。
  • $slice: -N:最後のN個の要素を返します。
  • $slice: [M, N]:インデックスMから始まるN個の要素を返します。
// 'history'配列から最後の3つのエントリのみを返す
    db.logs.find({}, { history: { $slice: -3 } });

集約フレームワークによるデータ分析

MongoDB集約フレームワークは、複雑なデータ分析のための最も強力なツールであり、パイプラインのステージを通じてデータレコードを処理できます。各ステージは、前のステージから渡されたデータに対して特定の変換または操作を実行します。

主要な集約ステージ

基本構造はdb.collection.aggregate([...pipeline])を使用します。

1. $match(フィルタリング)

find()と同様に機能しますが、後続のステージのに適用されるため、データセットを早期に削減してパフォーマンスを最適化します。

2. $group(グループ化と計算)

このステージは、指定された識別子(_id)でドキュメントをグループ化し、アキュムレータ演算子を適用して要約統計を計算します。

一般的なアキュムレータ:

  • $sum
  • $avg
  • $min$max
  • $push(グループから配列データを収集するため)
// 部門ごとの平均スコアを計算
    db.scores.aggregate([
      { $group: { 
        _id: "$department", 
        averageScore: { $avg: "$score" },
        totalStudents: { $sum: 1 }
      } }
    ]);

3. $project(ドキュメントの再形成)

集約内で出力ドキュメントを再形成するために使用され、find()プロジェクションと似ていますが、新しい計算フィールドを作成するためによく使用されます。

  • 計算フィールド:既存のフィールドを使用して、プロジェクションステージ内で計算を実行できます。
// パイプライン内で利益率を計算
    db.sales.aggregate([
      { $project: { 
        _id: 0, 
        productName: 1,
        profit: { $subtract: ["$salePrice", "$cost"] }
      } }
    ]);

4. $lookup(データの結合)

$lookupステージは、別のコレクションから一致するドキュメントを追加します。これは左外部結合に似ています。アプリケーションコードで結合を行わずに、レポート作成のためにドキュメントを強化する必要がある場合に便利です。

// 'orders'コレクションと'customers'コレクションを結合
    db.orders.aggregate([
      { $match: { status: "Pending" } },
      { $lookup: {
          from: "customers",         // 結合するコレクション
          localField: "customerId",  // 入力ドキュメント(orders)からのフィールド
          foreignField: "_id",       // "from"コレクション(customers)のドキュメントからのフィールド
          as: "customerDetails"      // 出力配列フィールド名
      } }
    ]);

5. $unwind(配列の分解)

配列フィールドに複数の要素が含まれている場合、$unwindは配列内の要素に対して個別の出力ドキュメントを作成し、データを効果的に非正規化して、配列コンテンツのグループ化やフィルタリングを容易にします。

警告$unwindはドキュメント数を大幅に増やす可能性があります。通常は$matchの後に使用して、初期セットを削減してから慎重に使用してください。

分析クエリのベストプラクティス

  1. エントリポイントにインデックスを付ける:初期の$matchステージで使用されるフィールドと、インデックスバックアップされた$sortステージにインデックスを付けます。$groupは入力ドキュメントが少ないとメリットがありますが、グループ化されたフィールドにインデックスがあるからといって自動的に高速になるわけではありません。
  2. 早期にフィルタリングする:集約パイプライン内で$matchステージをできるだけ早く配置します。ドキュメント数を早期に削減すると、$lookup$groupなどの後続のより高価なステージの処理能力を大幅に節約できます。
  3. 適切なデータ型を使用する:比較フィールド(日付や数値など)が一貫して保存されていることを確認します。型の不一致は、$match演算子がサイレントにまたは非効率的に失敗する原因になります。

単純なデータ取得では不十分な場合にこれらのコマンドを使用してください。選択的なフィルターから始め、必要なフィールドのみをプロジェクトし、グループ化、再形成、またはコレクション間のエンリッチメントが必要な場合は集約に移行してください。