MongoDB 쿼리에서 캐스팅(형 변환)이 가능할까요?
네, MongoDB 쿼리에서도 캐스팅(형 변환)이 가능합니다. 일반적으로 MongoDB는 저장된 데이터 타입을 그대로 유지하기 때문에 문자열로 저장된 숫자를 비교 연산에 사용하면 의도대로 동작하지 않을 수 있습니다. 하지만 $where 절과 함께 JavaScript 표현식을 사용하면 문자열 값을 자동으로 숫자로 변환하여 비교할 수 있습니다.
기본적인 사용 형식은 다음과 같습니다.
db.yourCollectionName.find("this.yourFieldName > yourValue");예제 컬렉션 생성하기
개념을 이해하기 위해 먼저 문서가 포함된 컬렉션을 생성해 보겠습니다. 아래 쿼리는 'castingDemo'라는 컬렉션에 문자열 타입의 Amount 필드를 가진 문서들을 삽입합니다.
> db.castingDemo.insertOne({"Amount":"200"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c947e874cf1f7a64fa4df42")
}
> db.castingDemo.insertOne({"Amount":"100"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c947e8e4cf1f7a64fa4df43")
}
> db.castingDemo.insertOne({"Amount":"110"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c947e944cf1f7a64fa4df44")
}
> db.castingDemo.insertOne({"Amount":"95"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c947e9d4cf1f7a64fa4df45")
}
> db.castingDemo.insertOne({"Amount":"85"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c947ea44cf1f7a64fa4df46")
}
> db.castingDemo.insertOne({"Amount":"75"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c947ebd4cf1f7a64fa4df47")
}위 결과를 보면 모든 문서가 정상적으로 삽입되었음을 확인할 수 있습니다. 주의할 점은 Amount 값이 따옴표로 묶여 있어 숫자가 아닌 문자열로 저장되었다는 것입니다.
저장된 문서 확인하기
find() 메서드를 사용해 컬렉션의 모든 문서를 조회해 보겠습니다.
> db.castingDemo.find().pretty();
실행 결과는 다음과 같습니다.
{ "_id" : ObjectId("5c947e874cf1f7a64fa4df42"), "Amount" : "200" }
{ "_id" : ObjectId("5c947e8e4cf1f7a64fa4df43"), "Amount" : "100" }
{ "_id" : ObjectId("5c947e944cf1f7a64fa4df44"), "Amount" : "110" }
{ "_id" : ObjectId("5c947e9d4cf1f7a64fa4df45"), "Amount" : "95" }
{ "_id" : ObjectId("5c947ea44cf1f7a64fa4df46"), "Amount" : "85" }
{ "_id" : ObjectId("5c947ebd4cf1f7a64fa4df47"), "Amount" : "75" }문자열을 숫자로 자동 변환하는 쿼리
이제 핵심 부분입니다. 아래 쿼리처럼 find() 메서드 안에 JavaScript 조건식을 문자열로 전달하면, MongoDB는 문자열로 저장된 Amount 값을 자동으로 숫자로 변환하여 비교합니다.
> db.castingDemo.find("this.Amount > 85");실행 결과는 다음과 같습니다.
{ "_id" : ObjectId("5c947e874cf1f7a64fa4df42"), "Amount" : "200" }
{ "_id" : ObjectId("5c947e8e4cf1f7a64fa4df43"), "Amount" : "100" }
{ "_id" : ObjectId("5c947e944cf1f7a64fa4df44"), "Amount" : "110" }
{ "_id" : ObjectId("5c947e9d4cf1f7a64fa4df45"), "Amount" : "95" }결과를 보면 Amount 값이 85보다 큰 문서 4개만 반환되었습니다. 만약 캐스팅 없이 단순 문자열 비교를 했다면 "95"는 "85"보다 사전순으로 크기 때문에 결과가 달라질 수 있습니다. 이처럼 JavaScript 표현식을 활용하면 문자열 타입의 숫자 데이터도 올바르게 비교할 수 있습니다.
참고 사항
$where 기반 쿼리는 각 문서마다 JavaScript를 실행하므로 대량의 데이터를 다룰 때는 성능 저하가 발생할 수 있습니다. 따라서 이 방법은 임시 해결책으로 사용하고, 근본적으로는 스키마 설계 단계에서 숫자 데이터를 NumberInt나 NumberDouble 등 올바른 숫자 타입으로 저장하는 것이 좋습니다. 필요하다면 집계 파이프라인의 $toInt, $toDouble 연산자를 사용해 기존 문자열 데이터를 숫자 타입으로 일괄 변환할 수도 있습니다.