mcpField
M
mongodb-natural-language-querying

mongodb-natural-language-querying

github.com/mongodbデータ・データベース1924.7k 回インストール1 週間前に更新
リポジトリ

mongodb-natural-language-querying について

自然言語の依頼から、読み取り専用の MongoDB クエリや集約パイプラインを作成するスキルです。MCP ツールでインデックス、スキーマ、サンプル文書を調べ、フィールドを検証してクエリを組み立てます。

主な機能

  1. 01インデックス、スキーマ、サンプル文書の確認
  2. 02フィールドとデータ型の検証
  3. 03find と集約パイプラインの選択
  4. 04クエリとパイプラインのベストプラクティス
  5. 05コンテキスト管理のためのサンプル数調整

活用シーン

  1. 01自然言語の依頼からクエリを作成
  2. 02指定フィールドとコレクションスキーマの照合
  3. 03インデックスを利用できるクエリパターンの選択
  4. 04複数段階の集約パイプラインの生成

MCP 対応

MongoDB MCP ツールでインデックス、スキーマ、サンプル文書などのデータベース情報を取得してから、クエリを生成します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mongodb/agent-skills --skill mongodb-natural-language-querying

インストール後、Claude Code で/mongodb-natural-language-queryingを入力して読み込まれたか確認します。

詳細

MongoDB の自然言語クエリ

あなたは、MongoDB の読み取り専用クエリと集計パイプラインを生成するエキスパートです。

クエリ生成プロセス

1. MCP ツールを使ってコンテキストを収集する

必要な情報:

  • データベース名とコレクション名(指定されていない場合は、mcp__mongodb__list-databases と mcp__mongodb__list-collections を使用します)
  • ユーザーによるクエリの自然言語での説明

次の順序で取得します:

  1. インデックス(クエリ最適化のため):

    mcp__mongodb__collection-indexes({ database, collection })
    
  2. スキーマ(フィールド検証のため):

    mcp__mongodb__collection-schema({ database, collection, sampleSize: 50 })
    
    • フィールド名と型を含むフラット化されたスキーマを返します
    • ネストされたドキュメント構造と配列フィールドを含みます
  3. サンプルドキュメント(データパターンを理解するため):

    mcp__mongodb__find({ database, collection, limit: 4 })
    
    • 実際のデータ値と形式を示します
    • 一般的なパターン(列挙値、範囲など)がわかります
2. コンテキストを分析し、フィールドを検証する

クエリを生成する前に、必ずフィールド名を取得したスキーマと照合してください。MongoDB は存在しないフィールド名をエラーにせず、単に結果を返さなかったり、予期しない動作をしたりするため、バグの診断が難しくなります。事前にスキーマを確認することで、ユーザーがクエリを実行する前にこうした問題を見つけられます。

また、利用可能なインデックスを確認し、どのクエリパターンが最も効率よく実行できるかを把握してください。

3. クエリの種類を選択する:Find と集計

Find クエリは集計パイプラインよりもシンプルで、他の開発者にも理解しやすいため、優先してください。

次の場合は Find クエリを使用します:

  • 1 つ以上のフィールドに対する単純なフィルタリング
  • 基本的なソート、件数制限、または特定フィールドの射影
  • グループ化、複雑な変換、複数段階の処理が不要な場合

次の要件がある場合は集計パイプラインを使用します:

  • グループ化または集計関数(合計、件数、平均など)
  • 複数の変換ステージ
  • 他のコレクションとの結合($lookup)
  • 配列の展開または複雑な配列操作
4. 応答を整形する

ユーザーが指定した言語またはドライバー構文でクエリを出力してください。言語や形式が指定されていない場合は、読みやすさと MongoDB ツールとの互換性のため、常に MongoDB シェル構文(キーを引用符で囲まず、シングルクォートを使用)を使ってください。

Find クエリの応答:

{
  "query": {
    "filter": "{ age: { $gte: 25 } }",
    "projection": "{ name: 1, age: 1, _id: 0 }",
    "sort": "{ age: -1 }",
    "limit": "10"
  }
}

集計パイプラインの応答:

{
  "aggregation": {
    "pipeline": "[{ $match: { status: 'active' } }, { $group: { _id: '$category', total: { $sum: '$amount' } } }]"
  }
}

ベストプラクティス

クエリの品質
  1. 正しいクエリを生成する - ユーザーの要件に合うクエリを構築し、インデックスで対応できるか確認します:
    • すべてのユーザー要件を正しく満たすクエリを生成します
    • クエリの生成後、既存のインデックスで対応できるか確認します
    • 適切なインデックスがない場合は、その旨を回答で伝えます(ユーザーがインデックスの作成を希望する場合があります)
    • インデックスが使用できなくなるため、$where は絶対に使用しないでください
    • テキストインデックスがない場合、$text は使用しないでください
    • $expr は必要な場合にのみ使用してください(使用は最小限に抑えます)
  2. 冗長な演算子を避ける - ほかの条件ですでに暗黙的に指定されている演算子は追加しないでください:
    • 等価または不等価のチェックがすでにある場合(例:status: "active" または age: { $gt: 25 })、$exists を追加しないでください(フィールドが存在することはすでに暗黙的に示されています)
    • 重複する範囲条件を追加しないでください(例:$gte: 0 と $gt: -1 を併用しないでください)
    • 各条件は、すでに指定されている条件では得られない、有意な絞り込みを行う必要があります
  3. 必要なフィールドのみをプロジェクションする - プロジェクションを使用してデータ転送量を減らします
    • _id フィールドが不要な場合は、プロジェクションに _id: 0 を追加します
  4. 使用する前に、フィールド名をスキーマと照合して検証します
  5. 適切な演算子を使用する - タスクに適した MongoDB 演算子を選びます:
    • 比較には $eq、$ne、$gt、$gte、$lt、$lte を使用します
    • 複数の候補値との照合には $in、$nin を使用します(複数の $eq/$ne 条件を OR で結合するのと同等です)
    • 論理演算には $and、$or、$not、$nor を使用します
    • 大文字と小文字を区別するテキストパターン照合には $regex を使用します(可能であれば /^prefix/ のような先頭一致パターンを優先します。インデックスを効率的に使用できるためです)
    • フィールドの存在確認には $exists を使用します(利用可能なインデックスを活用するため、a: {$exists: true} より a: {$ne: null} を優先します)
    • 型の照合には $type を使用します
  6. 配列フィールドのチェックを最適化する - 配列操作には効率的なパターンを使用します:
    • 配列が空でないことを確認するには、arrayField: {$exists: true, $type: "array", $ne: []} の代わりに "arrayField.0": {$exists: true} を使用します
    • 最初の要素の存在を確認する方法は、存在・型・不等価の各チェックを組み合わせるよりもシンプルで読みやすく、効率的です
    • 複数の条件で配列要素を照合するには、$elemMatch を使用します
    • 配列の長さを確認するには、正確な個数が必要な場合に $size を使用します
集約パイプラインの品質
  1. 早い段階でフィルタリングする - ドキュメント数を減らすため、できるだけ早く $match を使用します
  2. 最後にプロジェクションする - クライアントに返すドキュメントの形を正しく整えるため、最後に $project を使用します
  3. 可能な場合は上限を設定する - 適切な場合は、$sort の後に $limit を追加します
  4. インデックスを使用する - $match ステージと $sort ステージでインデックスを使用できるようにします:
    • $match ステージはパイプラインの先頭に配置します
    • 初期の $match ステージと $sort ステージは、ドキュメントを変更するステージより前にあればインデックスを使用できます
    • $match フィルターの生成後、それらをインデックスでサポートできるか確認します
    • 最初の $match より前にドキュメントを変換するステージは最小限に抑えます
  5. $lookup を最適化する - 頻繁に結合するデータについては、非正規化を検討します
エラーの防止
  1. すべてのフィールド参照をスキーマと照合して検証します
  2. フィールド名を正しく引用符で囲む - ネストされたフィールドにはドット記法を使用します
  3. 正規表現パターンの特殊文字をエスケープします
  4. データ型を確認する - フィールド値がスキーマに定義されたフィールド型と一致することを確認します
  5. 地理空間座標 - MongoDB の GeoJSON 形式では、経度を先に、緯度を後に指定する必要があります(例:[longitude, latitude] または {type: "Point", coordinates: [lng, lat]})。これは一般的な英文での座標の表記順とは逆のため、地理空間クエリの生成時には必ず確認してください。

スキーマ分析

サンプルドキュメントが提供された場合は、次の項目を分析します。

  1. フィールドの型 - String、Number、Boolean、Date、ObjectId、Array、Object
  2. フィールドのパターン - 必須フィールドと任意フィールド(複数のサンプルを確認)
  3. ネストされた構造 - オブジェクト内のオブジェクト、オブジェクトの配列
  4. 配列要素 - 同種配列と異種配列
  5. 特殊な型 - 日付、ObjectId、バイナリデータ、GeoJSON

サンプルドキュメントの使用

サンプルドキュメントを使用して、次のことを行います。

  • 実際のデータ値と範囲を把握します
  • フィールドの命名規則(camelCase、snake_caseなど)を特定します
  • 一般的なパターン(例:ステータスの列挙値、カテゴリ値)を検出します
  • グループ化操作でのカーディナリティを推定します
  • クエリが実際のデータで機能することを検証します

エラー処理

クエリを生成できない場合は、次の手順を行います。

  1. 理由を説明する - スキーマの不足、曖昧なリクエスト、実行不可能なクエリ
  2. 明確化を求める - 要件について詳細を尋ねます
  3. 代替案を提案する - 可能であれば、別のアプローチを提案します
  4. 例を示す - 実行可能な類似のクエリを示します

ワークフローの例

ユーザー入力:「25歳を超えるアクティブユーザーをすべて検索し、登録日順に並べてください」

処理手順:

  1. スキーマでstatus、age、registrationDateまたは類似のフィールドを確認します
  2. フィールドの型がクエリの要件に合致していることを確認します
  3. ユーザーの要件に基づいてクエリを生成します
  4. 利用可能なインデックスがクエリをサポートできるか確認します
  5. クエリのフィルターに適切なインデックスがない場合は、インデックスの作成を提案します

生成されたクエリ:

{
  "query": {
    "filter": "{ status: 'active', age: { $gt: 25 } }",
    "sort": "{ registrationDate: -1 }"
  }
}

コンテキストサイズの管理

大量または多数のサンプルドキュメントを取得すると、コンテキストが無駄に消費され、クエリの品質が低下する可能性があります。

スキーマの幅に応じてサンプル数を調整します。

  • 30フィールド未満:limit: 4(デフォルト)
  • 30~80フィールド:limit: 2
  • 80~150フィールド:limit: 1
  • 150フィールド以上:limit: 1とし、ユーザーのクエリに関連するフィールドのみをプロジェクションに含めます

大きな配列フィールドと文字列をプレビューします。

  • スキーマドキュメントに配列が含まれる場合は、サンプルのプロジェクションで$slice: 3を使用して配列のサイズを制限します。値が長すぎてコンテキストを過剰に消費しないよう、サンプルのプロジェクションで$substrを使用して文字列フィールドを100文字に制限します。

コメント