MongoDB에서 사용자 정의 필드로 인덱싱·정렬·페이지네이션 구현하기
MongoDB에서 특정 필드를 기준으로 데이터를 정렬하면서 페이지네이션을 적용하려면, 해당 필드에 인덱스를 미리 생성해 두는 것이 성능 면에서 매우 중요합니다. 이 글에서는 복합 인덱스(compound index)를 생성한 뒤, sort(), limit(), skip() 메서드를 조합해 페이지네이션을 구현하는 전체 과정을 단계별로 살펴봅니다.
1단계: 컬렉션 생성과 인덱스 설정
먼저 createIndex() 메서드를 사용해 Name 필드와 CountryName 필드를 오름차순(1)으로 정렬하는 복합 인덱스를 생성합니다. demo373 컬렉션이 아직 존재하지 않으면 자동으로 생성됩니다.
> db.demo373.createIndex({"Name":1,"CountryName":1});
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}2단계: 샘플 문서 삽입
insertOne() 메서드로 Name, Age, CountryName 필드를 포함한 문서 다섯 개를 차례대로 추가합니다.
> db.demo373.insertOne({"Name":"Chris","Age":22,"CountryName":"US"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e59ffde2ae06a1609a00aff")
}
> db.demo373.insertOne({"Name":"David","Age":21,"CountryName":"AUS"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e59ffe82ae06a1609a00b00")
}
> db.demo373.insertOne({"Name":"Bob","Age":23,"CountryName":"UK"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e59fff42ae06a1609a00b01")
}
> db.demo373.insertOne({"Name":"John","Age":21,"CountryName":"US"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e59ffff2ae06a1609a00b02")
}
> db.demo373.insertOne({"Name":"Carol","Age":23,"CountryName":"AUS"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e5a00082ae06a1609a00b03")
}3단계: 전체 문서 조회
find() 메서드를 호출하면 컬렉션에 저장된 모든 문서를 확인할 수 있습니다.
> db.demo373.find();
위 명령을 실행하면 다음과 같은 결과가 출력됩니다.
{ "_id" : ObjectId("5e59ffde2ae06a1609a00aff"), "Name" : "Chris", "Age" : 22, "CountryName" : "US" }
{ "_id" : ObjectId("5e59ffe82ae06a1609a00b00"), "Name" : "David", "Age" : 21, "CountryName" : "AUS" }
{ "_id" : ObjectId("5e59fff42ae06a1609a00b01"), "Name" : "Bob", "Age" : 23, "CountryName" : "UK" }
{ "_id" : ObjectId("5e59ffff2ae06a1609a00b02"), "Name" : "John", "Age" : 21, "CountryName" : "US" }
{ "_id" : ObjectId("5e5a00082ae06a1609a00b03"), "Name" : "Carol", "Age" : 23, "CountryName" : "AUS" }4단계: 정렬과 페이지네이션 쿼리 실행
sort()로 정렬 기준을 지정하고 limit()과 skip()을 조합하면 손쉽게 페이지네이션을 구현할 수 있습니다. 아래 쿼리는 Name 필드와 Age 필드를 오름차순으로 정렬한 뒤, 앞의 2개 문서를 건너뛰고(skip) 최대 4개(limit)의 문서를 반환합니다.
> db.demo373.find().sort({"Name":1, "Age":1}).limit(4).skip(2);이 쿼리는 다음과 같은 출력을 생성합니다. 전체 문서가 5개이므로 2개를 건너뛴 후 남은 3개가 반환됩니다.
{ "_id" : ObjectId("5e59ffde2ae06a1609a00aff"), "Name" : "Chris", "Age" : 22, "CountryName" : "US" }
{ "_id" : ObjectId("5e59ffe82ae06a1609a00b00"), "Name" : "David", "Age" : 21, "CountryName" : "AUS" }
{ "_id" : ObjectId("5e59ffff2ae06a1609a00b02"), "Name" : "John", "Age" : 21, "CountryName" : "US" }정리
MongoDB에서는 createIndex()로 자주 사용하는 정렬 기준 필드에 인덱스를 생성한 후, sort(), limit(), skip()을 조합하면 효율적으로 페이지네이션을 구현할 수 있습니다. 다만 skip()은 건너뛰는 문서 수가 많아질수록 성능이 저하될 수 있으므로, 데이터 규모가 큰 서비스에서는 마지막으로 조회한 값을 기준으로 다음 페이지를 가져오는 범위(range) 기반 페이지네이션을 함께 고려하는 것이 좋습니다.