SQL LIMITとOFFSETをMongoDBのlimit()とskip()に変換する

ページネーション用のSQL LIMITとOFFSETがMongoDBのlimit()とskip()カーソルメソッドまたは$limitと$skipパイプラインステージに変換される方法を学びます。

Migration

詳細な説明

LIMIT / OFFSETからlimit() / skip()へ

SQLはページネーションにLIMITOFFSETを使用します。MongoDBはlimit()skip()カーソルメソッド、または$limit$skip集計ステージを提供します。

SQLの例

SELECT * FROM articles
ORDER BY created_at DESC
LIMIT 20 OFFSET 40

生成されるMongoDBクエリ(find)

db.articles.find({}).sort({
  created_at: -1
}).skip(40).limit(20)

生成されるMongoDBクエリ(aggregate)

db.articles.aggregate([
  { $sort: { created_at: -1 } },
  { $skip: 40 },
  { $limit: 20 }
])

ページネーションパターン

標準的なオフセットベースのページネーションは直接マッピングされます:

  • ページ1: LIMIT 20 OFFSET 0 = .skip(0).limit(20)
  • ページ2: LIMIT 20 OFFSET 20 = .skip(20).limit(20)
  • ページ3: LIMIT 20 OFFSET 40 = .skip(40).limit(20)

OFFSETなしのLIMIT

OFFSETなしのシンプルなLIMIT(先頭から)は.limit()のみが必要です:

SELECT * FROM users LIMIT 10
db.users.find({}).limit(10)

大きなオフセットのパフォーマンス警告

MongoDBのskip()はスキップされたドキュメントを依然としてスキャンして破棄するため、オフセット値に比例してパフォーマンスが低下します。大規模なコレクションでは、カーソルベース(キーセット)ページネーションが推奨されます:

// skip(10000).limit(20)の代わりに:
db.articles.find({
  created_at: { $lt: lastSeenDate }
}).sort({ created_at: -1 }).limit(20)

このアプローチはインデックス付きフィールドを使用して正しい位置に効率的にシークします。

メソッドチェーンの順序

find()クエリでは、.sort().skip().limit()は任意の順序で連鎖できます — MongoDBは常にソート、スキップ、リミットの順で適用します。ただし、集計パイプラインではステージの順序が重要であり、明示的に指定する必要があります。

ユースケース

ページネーション付きリストビュー(ブログ投稿、検索結果、管理テーブル)を持つすべてのWebアプリケーションはLIMIT/OFFSETページネーションに依存します。MongoDBの同等物とそのパフォーマンス特性を理解することは、移行後のレスポンシブなAPIの維持に不可欠です。

試してみる — SQL to MongoDB Query

フルツールを開く