MongoDB에서 마지막 N개의 레코드 가져오기
이 튜토리얼은 MongoDB에서 마지막 N개의 레코드를 얻는 방법의 수를 탐구할 것입니다. 여기서 N은 양수이고 0보다 큽니다. 정렬을 사용하거나 사용하지 않고 문서 수를 검색하는 방법을 살펴보겠습니다.
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 레코드 가져오기
계속하기 전에 다음 두 용어를 살펴보고 쉽게 이해할 수 있습니다.
-
가장 최근에서 덜 최근 정렬
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 }
예제 코드(선입 선출):
> 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를 사용하는 동안 문서는 컬렉션에 지정된 순서로 저장되지 않습니다.
그렇기 때문에 중복 값이 있는 특정 필드에 대해 정렬을 수행할 때 해당 값이 있는 문서가 임의의 순서로 반환될 수 있습니다. 일관된 정렬을 얻으려면 고유한 값이 포함된 필드를 하나 이상 포함해야 합니다.
이를 확인하는 가장 쉬운 방법은 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
인 경우 선입선출 및 후입선출과 같이 작동합니다. 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 }
예제 코드(선입 선출):
> 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개의 키를 정렬하고 일관된 정렬 순서를 위해 최소한 하나의 필드(고유 값 포함)를 가질 수 있습니다.
여러 필드를 정렬해야 하는 경우 정렬 순서는 왼쪽에서 오른쪽으로 평가됩니다. $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가지 문서를 받게 됩니다.