MongoDB: cursor not found
MongoDBでカーソルがタイムアウトまたは無効化された場合のエラー原因と解決策
概要
MongoDBのカーソルがサーバー側でタイムアウトまたは削除された後にアクセスしようとした際に発生するエラーです。
エラーメッセージ
``` CursorNotFound: cursor id 1234567890 not found ```
原因
- カーソルタイムアウト: デフォルト10分で自動削除
- 大量データの反復処理: 処理時間がタイムアウトを超過
- レプリカセットのフェイルオーバー: プライマリ切り替えでカーソル喪失
- サーバー再起動: 全カーソルが無効化
解決策
1. noCursorTimeoutオプションを使用
```javascript // Node.js const cursor = collection.find({}).noCursorTimeout(); try { for await (const doc of cursor) { await processDocument(doc); } } finally { await cursor.close(); // 必ずクローズ } ```
```python
Python
cursor = collection.find({}, no_cursor_timeout=True) try: for doc in cursor: process_document(doc) finally: cursor.close() # 必ずクローズ ```
2. バッチサイズを調整
```javascript const cursor = collection.find({}).batchSize(1000); ```
3. ページネーションを使用
```javascript let lastId = null; const pageSize = 1000;
while (true) { const query = lastId ? { _id: { $gt: lastId } } : {}; const docs = await collection.find(query).limit(pageSize).toArray();
if (docs.length === 0) break;
for (const doc of docs) { await processDocument(doc); }
lastId = docs[docs.length - 1]._id; } ```
4. Aggregationでストリーム処理
```javascript const stream = collection.aggregate([ { $match: { status: ‘pending’ } } ], { allowDiskUse: true }).stream();
stream.on(‘data’, (doc) => processDocument(doc)); stream.on(’end’, () => console.log(‘Done’)); ```
よくある間違い
- noCursorTimeoutを使ってクローズを忘れる(メモリリーク)
- 処理中にカーソル位置を保存しない
- エラー発生時のリトライロジックがない
関連エラー
関連エラー
MongoDB の他のエラー
この記事は役に立ちましたか?