MongoDB で最後の N レコードを取得する
このチュートリアルでは、MongoDB で最後の N レコードを取得する方法をいくつか説明します。ここで、N は正の数であり、ゼロより大きくなります。並べ替えの有無にかかわらず、ドキュメントの数を取得する方法を説明します。
MongoDB で最後の N レコードを取得する
実際の例を続けるには、ドキュメントを含むコレクションが必要です。それでは、先に進み、次のクエリを使用してコレクションを作成し、コレクションにいくつかのドキュメントを挿入しましょう。
サンプルコード:
> use get_n_records;
> db.createCollection('stock');
> db.stock.insertMany([
{"item": "abc", "quantity": 12},
{"item": "def", "quantity": 234},
{"item": "ghi", "quantity": 45},
{"item": "jkl", "quantity": 345},
{"item": "mno", "quantity": 243},
{"item": "pqr", "quantity": 345},
{"item": "stu", "quantity": 56},
{"item": "vwx", "quantity": 575},
{"item": "yzz", "quantity": 398}
]);
> db.stock.find();
出力:
{ "_id" : ObjectId("629ac651b7e637e64d8e75fb"), "item" : "abc", "quantity" : 12 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fc"), "item" : "def", "quantity" : 234 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fd"), "item" : "ghi", "quantity" : 45 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fe"), "item" : "jkl", "quantity" : 345 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75ff"), "item" : "mno", "quantity" : 243 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7600"), "item" : "pqr", "quantity" : 345 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7601"), "item" : "stu", "quantity" : 56 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7602"), "item" : "vwx", "quantity" : 575 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7603"), "item" : "yzz", "quantity" : 398 }
これで、コレクションの準備が整い、データが入力されました。重要なのは、挿入された最新のドキュメントから最近のドキュメントまで、またはその逆の最後の N レコードを取得するかどうかを検討することです。
以下に示す各シナリオを学びましょう。
最新の挿入されたドキュメントから最近の挿入されていないドキュメントまで、またはその逆の最後の N レコードを取得する
続行する前に、次の 2つの用語を見て、簡単に理解してください。
-
最新から最近ではない並べ替え
Last In First Out(降順)を意味します。最後に挿入されたドキュメントが最初に表示されます。
-
最近ではないものから最新のものへの並べ替え
ファーストインファーストアウト(昇順)を意味します。最初に挿入されたドキュメントが最初に表示されます。
最新の挿入されたドキュメントから最近の挿入されていないドキュメントまで cursor.sort()
メソッドを使用して、またはその逆の最後の N レコードを取得する
サンプルコード(ラストインファーストアウト):
> db.stock.find().sort({_id:-1}).limit(3);
出力:
{ "_id" : ObjectId("629ac651b7e637e64d8e7603"), "item" : "yzz", "quantity" : 398 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7602"), "item" : "vwx", "quantity" : 575 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7601"), "item" : "stu", "quantity" : 56 }
サンプルコード(First In First Out):
> db.stock.find().sort({_id:1}).limit(3);
出力:
{ "_id" : ObjectId("629ac651b7e637e64d8e75fb"), "item" : "abc", "quantity" : 12 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fc"), "item" : "def", "quantity" : 234 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fd"), "item" : "ghi", "quantity" : 45 }
ここでは、sort()
メソッドを使用して、ドキュメントを最新の挿入順序から新しい挿入順序(降順)に並べ替えます。そのため、データベースからドキュメント(レコード)を取得する前に、sort()
メソッドをカーソルに適用しています。
sort()
メソッドには、{field: value}
としてのフィールドと値のペアがあり、最大 32 個のキーでソートを実行できます。MongoDB の使用中、ドキュメントは指定された順序でコレクションに保存されません。
そのため、値が重複している特定のフィールドで並べ替えを実行すると、それらの値を持つドキュメントが任意の順序で返される場合があります。一貫性のある並べ替えを行うには、一意の値を含むフィールドを少なくとも 1つ含める必要があります。
これを確認する最も簡単な方法は、sort()
メソッドに _id
フィールドを含めることです。
limit(N)
は、指定された数のドキュメントを取得するために使用されます。ソートされたすべてのドキュメントを取得する場合は、この関数を省略できます。
または、特定のフィールドがなくても、次のようにクエリを使用することもできます。
サンプルコード:
> db.stock.find().sort({$natural:1}).limit(3);
出力:
{ "_id" : ObjectId("629ac651b7e637e64d8e75fb"), "item" : "abc", "quantity" : 12 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fc"), "item" : "def", "quantity" : 234 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fd"), "item" : "ghi", "quantity" : 45 }
$natural
は、値がそれぞれ 1
と -1
の場合、First InFirstOut と LastInFirstOut のように機能します。MongoDB バージョン 4.4 以降を使用している場合に使用できます。
最新の挿入されたドキュメントから最近の挿入されていないドキュメントまで $sort
および $limit
(集計)ステージを使用して、またはその逆の最後の N レコードを取得する
サンプルコード(ラストインファーストアウト):
> db.stock.aggregate([
{ $sort : { _id : -1 } },
{ $limit : 4 }
]);
出力:
{ "_id" : ObjectId("629ac651b7e637e64d8e7603"), "item" : "yzz", "quantity" : 398 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7602"), "item" : "vwx", "quantity" : 575 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7601"), "item" : "stu", "quantity" : 56 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7600"), "item" : "pqr", "quantity" : 345 }
サンプルコード(First In First Out):
> db.stock.aggregate([
{ $sort : { _id : 1 } },
{ $limit : 4 }
]);
出力:
{ "_id" : ObjectId("629ac651b7e637e64d8e75fb"), "item" : "abc", "quantity" : 12 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fc"), "item" : "def", "quantity" : 234 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fd"), "item" : "ghi", "quantity" : 45 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fe"), "item" : "jkl", "quantity" : 345 }
$sort
集約ステージは、cursor.sort()
メソッドに似ています。これは、すべてのドキュメントを並べ替えて、並べ替えられた順序でパイプラインに返すために使用されます。
フィールド名とそれぞれのソート順を持つドキュメントを取ります。1
と -1
は昇順と降順に使用されることに注意してください。
cursor.sort()
メソッドと同様に、$sort
集約ステージを使用して、最大 32 個のキーでソートし、一貫したソート順のために少なくとも 1つのフィールド(一意の値を含む)を持つことができます。
複数のフィールドで並べ替える必要がある場合は、並べ替え順序が左から右に評価されます。 $limit
は、画面に印刷する必要のあるドキュメントの数を示す数値を取ります。また、64 ビットの整数制限があります。
skip()
メソッドと count()
メソッドを一緒に使用して、MongoDB の最後の N レコードを取得する
プロジェクトの要件を考慮して、データを並べ替えるのではなく、ドキュメントのセクションを最初または最後から取得するため、このアプローチは魅力的です。
サンプルコード(ドキュメントを並べ替えずに最初の 3つのレコードを取得):
> db.stock.find().limit(3);
出力:
{ "_id" : ObjectId("629ac651b7e637e64d8e75fb"), "item" : "abc", "quantity" : 12 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fc"), "item" : "def", "quantity" : 234 }
{ "_id" : ObjectId("629ac651b7e637e64d8e75fd"), "item" : "ghi", "quantity" : 45 }
サンプルコード(ドキュメントを並べ替えずに最後の 3つのレコードを取得):
> db.stock.find().skip(db.stock.count() - 3)
出力:
{ "_id" : ObjectId("629ac651b7e637e64d8e7601"), "item" : "stu", "quantity" : 56 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7602"), "item" : "vwx", "quantity" : 575 }
{ "_id" : ObjectId("629ac651b7e637e64d8e7603"), "item" : "yzz", "quantity" : 398 }
この例では、db.stock.count()
を使用してドキュメントの総数をカウントし、それらから 3 を引いて、skip()
メソッドを使用してすべてをスキップします。
差し引いたドキュメントの数はスキップされないことを忘れないでください(この場合は 3 です)。結果として得られるこれらの 3つのドキュメント。