MongoDB에서 연도와 상관없이 월(month)과 일(day)만 기준으로 날짜 데이터를 검색해야 하는 경우가 있습니다. 이럴 때는 $where 연산자를 사용하면 됩니다. 이번 글에서는 예제 컬렉션을 만들고, 월과 일 조건에 맞는 문서를 조회하는 방법을 단계별로 살펴보겠습니다.
1. 샘플 컬렉션 생성하기
먼저 demo181 컬렉션에 배송 날짜(ShippingDate) 필드를 가진 문서들을 삽입합니다.
> db.demo181.insertOne({"ShippingDate":new ISODate("2020-01-10")});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e398a699e4f06af551997fe")
}
> db.demo181.insertOne({"ShippingDate":new ISODate("2019-12-11")});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e398a729e4f06af551997ff")
}
> db.demo181.insertOne({"ShippingDate":new ISODate("2018-01-10")});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e398a7d9e4f06af55199800")
}
> db.demo181.insertOne({"ShippingDate":new ISODate("2020-10-12")});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e398a879e4f06af55199801")
}2. 저장된 문서 확인하기
find() 메서드를 사용하면 컬렉션의 모든 문서를 조회할 수 있습니다.
> db.demo181.find();
위 명령을 실행하면 다음과 같은 결과가 출력됩니다.
{ "_id" : ObjectId("5e398a699e4f06af551997fe"), "ShippingDate" : ISODate("2020-01-10T00:00:00Z") }
{ "_id" : ObjectId("5e398a729e4f06af551997ff"), "ShippingDate" : ISODate("2019-12-11T00:00:00Z") }
{ "_id" : ObjectId("5e398a7d9e4f06af55199800"), "ShippingDate" : ISODate("2018-01-10T00:00:00Z") }
{ "_id" : ObjectId("5e398a879e4f06af55199801"), "ShippingDate" : ISODate("2020-10-12T00:00:00Z") }3. 월과 일로 검색하는 쿼리 작성하기
다음은 월이 1이거나 일이 10인 문서를 검색하는 쿼리입니다. $where 안에서 JavaScript 함수를 정의하고, getMonth()와 getDate() 메서드로 각 문서의 날짜 값을 비교합니다.
> db.demo181.find({$where : function() { return this.ShippingDate.getMonth() == 1 || this.ShippingDate.getDate() == 10} })쿼리를 실행하면 일(day)이 10일인 두 건의 문서가 반환됩니다.
{ "_id" : ObjectId("5e398a699e4f06af551997fe"), "ShippingDate" : ISODate("2020-01-10T00:00:00Z") }
{ "_id" : ObjectId("5e398a7d9e4f06af55199800"), "ShippingDate" : ISODate("2018-01-10T00:00:00Z") }알아두면 좋은 점
JavaScript의 getMonth()는 0부터 시작합니다(1월 = 0, 2월 = 1). 따라서 getMonth() == 1은 실제로 2월을 의미하며, 위 예제에서 결과가 반환된 것은 getDate() == 10 조건에 해당했기 때문입니다. 원하는 월을 지정할 때는 이 인덱스 차이를 반드시 고려해야 합니다.
또한 $where는 컬렉션의 모든 문서에 대해 JavaScript를 실행하므로 인덱스를 활용할 수 없고, 대량의 데이터에서는 성능 저하가 발생할 수 있습니다. 데이터 규모가 크다면 MongoDB 3.6 이상에서 지원하는 $expr과 집계 연산자($month, $dayOfMonth)를 조합한 방식을 함께 검토해 보는 것이 좋습니다.