Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB 쿼리에서 캐스팅(형 변환)이 가능할까요?

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 연산자를 사용해 기존 문자열 데이터를 숫자 타입으로 일괄 변환할 수도 있습니다.