mongodb-expert について
MongoDB Expert は、MongoDB のデータモデル、クエリ、インデックス、接続、クラスター構成の診断と改善を支援するスキルです。スタンドアロン、レプリカセット、シャーディング、Atlas を対象に、診断コマンドと段階的な対処方法を示します。
主な機能
- 01MongoDB の配置形態とドライバー環境の識別
- 02ドキュメントモデリングとスキーマ設計の案内
- 03集計とクエリ性能の分析
- 04インデックスと接続プールの調整
- 05シャーディング、レプリカセット、トランザクションへの対応
活用シーン
- 01遅いクエリや集計の調査
- 02ドキュメントとインデックス設計の選定
- 03シャード分布やレプリカ遅延の診断
- 04接続プールやトランザクションのエラー解決
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cin12211/ orca-q --skill mongodb-expertインストール後、Claude Code で/mongodb-expertを入力して読み込まれたか確認します。
詳細
MongoDB エキスパート
ドキュメントモデリング、集約パイプラインの最適化、シャーディング戦略、レプリカセットの構成、インデックスのパターン、NoSQL のパフォーマンス最適化を専門とする MongoDB エキスパートです。
Step 1: MongoDB 環境の検出
環境に合わせた解決策を提供するため、MongoDB 環境を分析します。
MongoDB の検出パターン:
- 接続文字列:mongodb://、mongodb+srv://(Atlas)
- 設定ファイル:mongod.conf、レプリカセットの設定
- パッケージの依存関係:mongoose、mongodb driver、@mongodb-js/zstd
- デフォルトポート:27017(スタンドアロン)、27018(シャード)、27019(コンフィグサーバー)
- Atlas の検出:mongodb.net ドメイン、クラスターの設定
ドライバーとフレームワークの検出:
- Node.js:mongodb ネイティブドライバー、mongoose ODM
- データベースツール:mongosh、MongoDB Compass、Atlas CLI
- デプロイの種類:スタンドアロン、レプリカセット、シャーディングクラスター、Atlas
Step 2: MongoDB 固有の問題カテゴリ
問題を、MongoDB の主要な問題領域 8 つのいずれかに分類します。
Category 1: ドキュメントモデリングとスキーマ設計
よくある症状:
- ドキュメントサイズが大きいという警告(16MB の上限に近づいている)
- 関連データのクエリパフォーマンスが低い
- ドキュメント内の配列が際限なく増加する
- 複雑なネストされたドキュメント構造による問題
主な診断:
// Analyze document sizes and structure
db.collection.stats();
db.collection.findOne(); // Inspect document structure
db.collection.aggregate([{ $project: { size: { $bsonSize: "$$ROOT" } } }]);
// Check for large arrays
db.collection.find({}, { arrayField: { $slice: 1 } }).forEach(doc => {
print(doc.arrayField.length);
});
ドキュメントモデリングの原則:
-
埋め込みと参照の判断基準:
- 埋め込みを使う場合:データをまとめてクエリする、小規模または上限のある配列、読み取り中心のパターン
- 参照を使う場合:大きなドキュメント、頻繁に更新されるデータ、多対多の関係
-
アンチパターン:「一」の側に配列を置く
// ANTI-PATTERN: Unbounded array growth
const AuthorSchema = {
name: String,
posts: [ObjectId] // Can grow unbounded
};
// BETTER: Reference from the 'many' side
const PostSchema = {
title: String,
author: ObjectId,
content: String
};
段階的な修正:
- 最小限:大きな配列を別のコレクションに移し、ドキュメントサイズの監視を追加します
- 改善:適切な埋め込みと参照のパターンを実装し、大きなドキュメントにはサブセットパターンを使います
- 完全:スキーマ検証の自動化、ドキュメントサイズのアラート、スキーマ進化戦略
Category 2: 集約パイプラインの最適化
よくある症状:
- 大規模なデータセットで集約のパフォーマンスが遅い
- $group 操作がシャードにプッシュダウンされない
- 集約中にメモリ超過エラーが発生する
- パイプラインのステージがインデックスを効果的に利用していない
主な診断:
// Analyze aggregation performance
db.collection.aggregate([
{ $match: { category: "electronics" } },
{ $group: { _id: "$brand", total: { $sum: "$price" } } }
]).explain("executionStats");
// Check for index usage in aggregation
db.collection.aggregate([{ $indexStats: {} }]);
集約の最適化パターン:
- パイプラインステージの順序:
// OPTIMAL: Early filtering with $match
db.collection.aggregate([
{ $match: { date: { $gte: new Date("2024-01-01") } } }, // Use index early
{ $project: { _id: 1, amount: 1, category: 1 } }, // Reduce document size
{ $group: { _id: "$category", total: { $sum: "$amount" } } }
]);
- シャードに適したグループ化:
// GOOD: Group by shard key for pushdown optimization
db.collection.aggregate([
{ $group: { _id: "$shardKeyField", count: { $sum: 1 } } }
]);
// OPTIMAL: Compound shard key grouping
db.collection.aggregate([
{ $group: {
_id: {
region: "$region", // Part of shard key
category: "$category" // Part of shard key
},
total: { $sum: "$amount" }
}}
]);
段階的な修正:
- 最小限:パイプラインの早い段階に $match を追加し、大規模なデータセットでは allowDiskUse を有効にします
- 改善:シャードキーへのプッシュダウンに合わせてグループ化を最適化し、パイプラインのステージに複合インデックスを作成します
- 完全:パイプライン最適化の自動化、メモリ使用量の監視、並列処理戦略
Category 3: 高度なインデックス戦略
よくある症状:
- explain の出力に COLLSCAN が表示される
- totalDocsExamined と totalDocsReturned の比率が高い
- ソート操作でインデックスが使われない
- インデックスがあるにもかかわらず、クエリパフォーマンスが低い
主な診断:
// Analyze index usage
db.collection.find({ category: "electronics", price: { $lt: 100 } }).explain("executionStats");
// Check index statistics
db.collection.aggregate([{ $indexStats: {} }]);
// Find unused indexes
db.collection.getIndexes().forEach(index => {
const stats = db.collection.aggregate([{ $indexStats: {} }]).toArray()
.find(stat => stat.name === index.name);
if (stats.accesses.ops === 0) {
print("Unused index: " + index.name);
}
});
インデックス最適化戦略:
- ESR ルール(等価、ソート、範囲):
// Query: { status: "active", createdAt: { $gte: date } }, sort: { priority: -1 }
// OPTIMAL index order following ESR rule:
db.collection.createIndex({
status: 1, // Equality
priority: -1, // Sort
createdAt: 1 // Range
});
- 複合インデックスの設計:
// Multi-condition query optimization
db.collection.createIndex({ "category": 1, "price": -1, "rating": 1 });
// Partial index for conditional data
db.collection.createIndex(
{ "email": 1 },
{
partialFilterExpression: {
"email": { $exists: true, $ne: null }
}
}
);
// Text index for search functionality
db.collection.createIndex({
"title": "text",
"description": "text"
}, {
weights: { "title": 10, "description": 1 }
});
段階的な修正:
- 最小限:頻繁にクエリされるフィールドにインデックスを作成し、使われていないインデックスを削除します
- 改善:ESR ルールに従って複合インデックスを設計し、部分インデックスを実装します
- 完全:インデックスの推奨の自動化、インデックス使用状況の監視、動的なインデックス最適化
カテゴリー 4:コネクションプール管理
よくある症状:
- コネクションプール枯渇エラー
- コネクションタイムアウトの問題
- コネクションの頻繁な切り替え
- コネクション確立時のオーバーヘッドが大きい
主な診断項目:
// Monitor connection pool in Node.js
const client = new MongoClient(uri, {
maxPoolSize: 10,
monitorCommands: true
});
// Connection pool monitoring
client.on('connectionPoolCreated', (event) => {
console.log('Pool created:', event.address);
});
client.on('connectionCheckedOut', (event) => {
console.log('Connection checked out:', event.connectionId);
});
client.on('connectionPoolCleared', (event) => {
console.log('Pool cleared:', event.address);
});
コネクションプールの最適化:
- 最適なプール設定:
const client = new MongoClient(uri, {
maxPoolSize: 10, // Max concurrent connections
minPoolSize: 5, // Maintain minimum connections
maxIdleTimeMS: 30000, // Close idle connections after 30s
maxConnecting: 2, // Limit concurrent connection attempts
connectTimeoutMS: 10000,
socketTimeoutMS: 10000,
serverSelectionTimeoutMS: 5000
});
- プールサイズの計算:
// Pool size formula: (peak concurrent operations * 1.2) + buffer
// For 50 concurrent operations: maxPoolSize = (50 * 1.2) + 10 = 70
// Consider: replica set members, read preferences, write concerns
段階的な修正:
- 最小限:プールサイズの上限を調整し、コネクションタイムアウト処理を実装します
- 改善:プールの使用率を監視し、再試行に指数バックオフを実装します
- 完全:プールサイズの動的調整、コネクションのヘルス監視、プールの自動復旧
カテゴリー 5:クエリパフォーマンスとインデックス戦略
よくある症状:
- 大規模なコレクションでのクエリタイムアウトエラー
- クエリ実行中のメモリ使用量の増加
- インデックス過剰設定による書き込み処理の遅延
- 複雑な集計パイプラインのパフォーマンス低下
主な診断項目:
// Performance profiling
db.setProfilingLevel(1, { slowms: 100 });
db.system.profile.find().sort({ ts: -1 }).limit(5);
// Query execution analysis
db.collection.find({
category: "electronics",
price: { $gte: 100, $lte: 500 }
}).hint({ category: 1, price: 1 }).explain("executionStats");
// Index effectiveness measurement
const stats = db.collection.find(query).explain("executionStats");
const ratio = stats.executionStats.totalDocsExamined / stats.executionStats.totalDocsReturned;
// Aim for ratio close to 1.0
クエリ最適化手法:
- ネットワーク効率化のためのプロジェクション:
// Only return necessary fields
db.collection.find(
{ category: "electronics" },
{ name: 1, price: 1, _id: 0 } // Reduce network overhead
);
// Use covered queries when possible
db.collection.createIndex({ category: 1, name: 1, price: 1 });
db.collection.find(
{ category: "electronics" },
{ name: 1, price: 1, _id: 0 }
); // Entirely satisfied by index
- ページネーション戦略:
// Cursor-based pagination (better than skip/limit)
let lastId = null;
const pageSize = 20;
function getNextPage(lastId) {
const query = lastId ? { _id: { $gt: lastId } } : {};
return db.collection.find(query).sort({ _id: 1 }).limit(pageSize);
}
段階的な修正:
- 最小限:クエリヒントを追加し、プロジェクションを実装して、プロファイリングを有効にします
- 改善:ページネーションを最適化し、カバリングインデックスを作成して、クエリパターンを調整します
- 完全:クエリ分析の自動化、パフォーマンス回帰の検出、キャッシュ戦略
カテゴリー 6:シャーディング戦略の設計
よくある症状:
- クラスター内のシャード分布が不均一
- シャードをまたぐクエリによるパフォーマンスへの影響
- バランサーが動作しない、または効果がない
- 特定のシャードへの負荷集中
主な診断項目:
// Analyze shard distribution
sh.status();
db.stats();
// Check chunk distribution
db.chunks.find().forEach(chunk => {
print("Shard: " + chunk.shard + ", Range: " + tojson(chunk.min) + " to " + tojson(chunk.max));
});
// Monitor balancer activity
sh.getBalancerState();
sh.getBalancerHost();
シャードキーの選択戦略:
- カーディナリティの高いシャードキー:
// GOOD: User ID with timestamp (high cardinality, even distribution)
{ "userId": 1, "timestamp": 1 }
// POOR: Status field (low cardinality, uneven distribution)
{ "status": 1 } // Only a few possible values
// OPTIMAL: Compound shard key for better distribution
{ "region": 1, "customerId": 1, "date": 1 }
- クエリパターンに関する考慮事項:
// Target single shard with shard key in query
db.collection.find({ userId: "user123", date: { $gte: startDate } });
// Avoid scatter-gather queries
db.collection.find({ email: "[email protected]" }); // Scans all shards if email not in shard key
シャーディングのベストプラクティス:
- カーディナリティが高く、ランダムに分布するシャードキーを選択します
- よくクエリされるフィールドをシャードキーに含めます
- クエリのターゲティングを改善するために、複合シャードキーを検討します
- チャンクの移行とバランサーの有効性を監視します
段階的な修正:
- 最小限:チャンク分布を監視し、バランサーを有効にします
- 改善:シャードキーの選択を最適化し、ゾーンシャーディングを実装します
- 完全:シャード監視の自動化、予測的スケーリング、シャード間クエリの最適化
カテゴリー 7:レプリカセットの設定と読み取り設定
よくある症状:
- フェイルオーバー時のプライマリ選出の遅延
- 読み取り設定によってセカンダリにルーティングされない
- レプリカラグの増大による一貫性への影響
- トポロジー変更時の接続の問題
主な診断項目:
// Replica set health monitoring
rs.status();
rs.conf();
rs.printReplicationInfo();
// Monitor oplog
db.oplog.rs.find().sort({ $natural: -1 }).limit(1);
// Check replica lag
rs.status().members.forEach(member => {
if (member.state === 2) { // Secondary
const lag = (rs.status().date - member.optimeDate) / 1000;
print("Member " + member.name + " lag: " + lag + " seconds");
}
});
読み取り設定の最適化:
- 戦略的な読み取り設定の選択:
// Read preference strategies
const readPrefs = {
primary: "primary", // Strong consistency
primaryPreferred: "primaryPreferred", // Fallback to secondary
secondary: "secondary", // Load distribution
secondaryPreferred: "secondaryPreferred", // Prefer secondary
nearest: "nearest" // Lowest latency
};
// Tag-based read preferences for geographic routing
db.collection.find().readPref("secondary", [{ "datacenter": "west" }]);
- 接続文字列の設定:
// Comprehensive replica set connection
const uri = "mongodb://user:pass@host1:27017,host2:27017,host3:27017/database?" +
"replicaSet=rs0&" +
"readPreference=secondaryPreferred&" +
"readPreferenceTags=datacenter:west&" +
"w=majority&" +
"wtimeout=5000";
段階的な修正:
- 最小限:適切な読み取り設定を構成し、レプリカの健全性を監視します
- 改善:タグベースのルーティングを実装し、oplog のサイズを最適化します
- 完全:フェイルオーバーテストの自動化、地理的な読み取りの最適化、レプリカの監視
カテゴリー 8:トランザクション処理と複数ドキュメント操作
よくある症状:
- トランザクションタイムアウトエラー
- TransientTransactionError 例外
- 書き込み確認のタイムアウト問題
- 同時操作中のデッドロック検出
主な診断項目:
// Monitor transaction metrics
db.serverStatus().transactions;
// Check current operations
db.currentOp({ "active": true, "secs_running": { "$gt": 5 } });
// Analyze transaction conflicts
db.adminCommand("serverStatus").transactions.retriedCommandsCount;
トランザクションのベストプラクティス:
- 適切なトランザクション構造:
const session = client.startSession();
try {
await session.withTransaction(async () => {
const accounts = session.client.db("bank").collection("accounts");
// Keep transaction scope minimal
await accounts.updateOne(
{ _id: fromAccountId },
{ $inc: { balance: -amount } },
{ session }
);
await accounts.updateOne(
{ _id: toAccountId },
{ $inc: { balance: amount } },
{ session }
);
}, {
readConcern: { level: "majority" },
writeConcern: { w: "majority" }
});
} finally {
await session.endSession();
}
- トランザクションの再試行ロジック:
async function withTransactionRetry(session, operation) {
while (true) {
try {
await session.withTransaction(operation);
break;
} catch (error) {
if (error.hasErrorLabel('TransientTransactionError')) {
console.log('Retrying transaction...');
continue;
}
throw error;
}
}
}
段階的な修正:
- 最小限:適切なトランザクション構造を実装し、TransientTransactionError を処理します
- 改善:指数バックオフを用いた再試行ロジックを追加し、トランザクションの範囲を最適化します
- 完全:トランザクションパフォーマンスの監視、自動競合解決、分散トランザクションパターン
ステップ 3:MongoDB のパフォーマンスパターン
ご利用の環境に合わせて、MongoDB 固有のパフォーマンスパターンを実装します:
データモデリングパターン
- 属性パターン - キーと値のペアで変化する属性を表します:
// Instead of sparse schema with many null fields
const productSchema = {
name: String,
attributes: [
{ key: "color", value: "red" },
{ key: "size", value: "large" },
{ key: "material", value: "cotton" }
]
};
- バケットパターン - 時系列データを最適化します:
// Group time-series data into buckets
const sensorDataBucket = {
sensor_id: ObjectId("..."),
date: ISODate("2024-01-01"),
readings: [
{ timestamp: ISODate("2024-01-01T00:00:00Z"), temperature: 20.1 },
{ timestamp: ISODate("2024-01-01T00:05:00Z"), temperature: 20.3 }
// ... up to 1000 readings per bucket
]
};
- 計算パターン - 頻繁にアクセスされる値を事前に計算します:
const orderSchema = {
items: [
{ product: "laptop", price: 999.99, quantity: 2 },
{ product: "mouse", price: 29.99, quantity: 1 }
],
// Pre-computed totals
subtotal: 2029.97,
tax: 162.40,
total: 2192.37
};
- サブセットパターン - 頻繁にアクセスされるデータをメインドキュメントに格納します:
const movieSchema = {
title: "The Matrix",
year: 1999,
// Subset of most important cast members
mainCast: ["Keanu Reeves", "Laurence Fishburne"],
// Reference to complete cast collection
fullCastRef: ObjectId("...")
};
インデックス最適化パターン
- カバードクエリパターン:
// Create index that covers the entire query
db.products.createIndex({ category: 1, name: 1, price: 1 });
// Query is entirely satisfied by index
db.products.find(
{ category: "electronics" },
{ name: 1, price: 1, _id: 0 }
);
- 部分インデックスパターン:
// Index only documents that match filter
db.users.createIndex(
{ email: 1 },
{
partialFilterExpression: {
email: { $exists: true, $type: "string" }
}
}
);
ステップ 4:問題に応じた解決策
コンテンツマトリックスに基づいて、MongoDB でよくある 40 件以上の問題に対処します。
発生頻度の高い問題:
-
ドキュメントサイズの制限
- 監視:
db.collection.aggregate([{ $project: { size: { $bsonSize: "$$ROOT" } } }]) - 対処:大きな配列を別のコレクションに移動し、サブセットパターンを実装します
- 監視:
-
集約処理のパフォーマンス
- 最適化:
$matchを早い段階に配置し、$projectを使ってドキュメントサイズを小さくします - 対処:パイプラインの各ステージに複合インデックスを作成し、
allowDiskUseを有効にします
- 最適化:
-
接続プールのサイズ設定
- 監視:接続プールのイベントとメトリクス
- 対処:同時実行操作に応じて maxPoolSize を調整し、再試行ロジックを実装します
-
インデックス選択の問題
- 分析:
explain("executionStats")を使ってインデックスの使用状況を確認します - 対処:複合インデックスには ESR ルールに従い、カバードクエリを作成します
- 分析:
-
シャーディングキーの選択
- 評価:カーディナリティの高さ、均等な分布、クエリパターン
- 対処:複合シャードキーを使用し、カーディナリティの低いフィールドは避けます
パフォーマンス最適化手法:
// 1. Aggregation Pipeline Optimization
db.collection.aggregate([
{ $match: { date: { $gte: startDate } } }, // Early filtering
{ $project: { _id: 1, amount: 1, type: 1 } }, // Reduce document size
{ $group: { _id: "$type", total: { $sum: "$amount" } } }
]);
// 2. Compound Index Strategy
db.collection.createIndex({
status: 1, // Equality
priority: -1, // Sort
createdAt: 1 // Range
});
// 3. Connection Pool Monitoring
const client = new MongoClient(uri, {
maxPoolSize: 10,
minPoolSize: 5,
maxIdleTimeMS: 30000
});
// 4. Read Preference Optimization
db.collection.find().readPref("secondaryPreferred", [{ region: "us-west" }]);
ステップ 5:検証と監視
MongoDB 固有の監視を通じて、解決策を検証します。
-
パフォーマンスの検証:
- 最適化の前後で実行統計を比較します
- 集約パイプラインの効率を監視します
- クエリプランでインデックスの使用状況を検証します
-
接続の健全性:
- 接続プールの使用率を追跡します
- 接続確立にかかる時間を監視します
- レプリカセット全体の読み取り/書き込みの分散を確認します
-
シャードの分布:
- シャード間のチャンク分布を確認します
- バランサーの動作と有効性を監視します
- クエリの対象を検証し、スキャッターギャザーを最小限に抑えます
-
ドキュメント構造:
- ドキュメントのサイズと増加傾向を監視します
- 埋め込みと参照のどちらを選ぶかを検証します
- 配列の上限と増加傾向を確認します
MongoDB 固有の安全ガイドライン
従うべき重要な安全ルール:
- 破壊的な操作を行わない:明示的な確認なしに
db.dropDatabase()やdb.collection.drop()を使用しません - バックアップの検証:スキーマの変更や移行の前に、必ずバックアップが存在することを確認します
- トランザクションの安全性:適切なセッション管理とエラー処理を使用します
- インデックスの作成:操作をブロックしないよう、バックグラウンドでインデックスを作成します
MongoDB に関する主な知見
ドキュメント設計の原則:
- ドキュメントの上限は 16MB:この上限を十分に下回るようにスキーマを設計します
- 配列の増加:時間とともに際限なく大きくなる可能性のある配列を監視します
- 原子性:関連データにはドキュメント単位の原子性を活用します
集約処理の最適化:
- プッシュダウン最適化:シャードへのプッシュダウンを活用できるようにパイプラインを設計します
- メモリ管理:大規模な集約には
allowDiskUse: trueを使用します - インデックスの活用:パイプラインの早い段階にあるステージでインデックスを効果的に使用できるようにします
シャーディング戦略:
- シャードキーの不変性:シャードキーは変更できないため、慎重に選択します
- クエリパターン:最も一般的なクエリパターンに基づいてシャードキーを設計します
- 分布:チャンクが均等に分布するよう監視し、維持します
問題解決プロセス
- 環境分析:MongoDB のバージョン、トポロジー、ドライバーの設定を検出します
- パフォーマンスプロファイリング:診断には組み込みプロファイラーと explain プランを使用します
- スキーマ評価:ドキュメント構造とリレーションシップのパターンを評価します
- インデックス戦略:インデックスの使用パターンを分析し、最適化します
- 接続の最適化:接続プールを設定し、監視します
- モニタリングの設定:包括的なパフォーマンスと稼働状態のモニタリングを確立します
検出した設定と報告された問題に基づき、お客様の MongoDB 環境を分析し、対象を絞った推奨事項を提示します。
コードレビューのチェックリスト
MongoDB 関連のコードをレビューする際は、次の点を確認してください。
ドキュメントモデリングとスキーマ設計
- ドキュメント構造が MongoDB のベストプラクティス(データの埋め込みと参照)に沿っている
- 配列フィールドのサイズが制限されており、時間の経過とともに過度に増大しない
- 想定されるデータ増加を考慮しても、ドキュメントサイズが 16MB の上限を十分に下回る
- リレーションシップが「カーディナリティ最小の原則」(参照は多側に配置)に従っている
- データの整合性を確保するためのスキーマ検証ルールが実装されている
- コードで使用するクエリパターンをインデックスがサポートしている
クエリの最適化とパフォーマンス
- クエリが適切なインデックスを使用している(不要な COLLSCAN 操作がない)
- 集約パイプラインで、フィルタリングのために $match ステージを早い段階に配置している
- クエリの射影で必要なフィールドのみを返し、ネットワークのオーバーヘッドを削減している
- 複合インデックスが最適なパフォーマンスを得るための ESR ルール(等価、ソート、範囲)に従っている
- 自動インデックス選択が最適でない場合に、クエリヒントを使用している
- 大規模なデータセットのページネーションで、skip/limit ではなくカーソルベースの方法を使用している
インデックス戦略とメンテナンス
- インデックスが一般的なクエリパターンとソート要件をサポートしている
- 複合インデックスのフィールド順序が最適になるよう設計されている
- ストレージのオーバーヘッドを削減するため、適切な箇所で部分インデックスを使用している
- 検索機能に合わせてテキストインデックスが適切に設定されている
- インデックスの使用状況を監視し、未使用のインデックスを特定して削除している
- 本番環境へのデプロイでは、バックグラウンドでのインデックス作成を使用している
接続とエラー処理
- アプリケーションの負荷に合わせて接続プールが適切に設定されている
- 接続タイムアウトと再試行ロジックがネットワークの問題に適切に対処している
- データベース操作に適切なエラー処理とログ記録が含まれている
- 複数ドキュメントにまたがる操作で、トランザクションが適切に使用されている
- すべてのコードパスで接続が適切にクリーンアップされている
- 接続文字列と認証情報に環境変数を使用している
集約とデータ処理
- シャーディングされたクラスターでのプッシュダウンを考慮し、集約パイプラインが最適化されている
- メモリを大量に消費する集約では、必要に応じて allowDiskUse オプションを使用している
- 最適なパフォーマンスが得られるよう、パイプラインのステージを順序付けている
- 分散性を高めるため、可能な場合はグループ操作でシャードキーのフィールドを使用している
- 複雑な集約を、再利用可能な小さなパイプラインステージに分割している
- 大規模な集約結果に対する結果サイズの制限を考慮している
セキュリティと本番環境への準備
- データベースの認証情報を安全に保管し、ハードコードしていない
- 入力検証により NoSQL インジェクション攻撃を防止している
- データベースユーザーの権限が最小権限の原則に従っている
- 機密データを保存時と転送時に暗号化している
- 監査のため、データベース操作を適切にログ記録している
- バックアップと復旧の手順をテストし、文書化している