Posts 몽고DB (MongoDB) - value type 변경
Post
Cancel

몽고DB (MongoDB) - value type 변경

Preview Image

뭐지 이거?

몽고DB를 사용하여 운영하는 중 쿼리를 사용해 데이터를 집어넣는 경우가 있었는데, 이후로 type casting 문제로 앱이 잘 안도는 것이었다. 황급히 find 쿼리로 보면 그냥 숫자값인데 왜? 앱에서는 double로 인식하고 있었다.

logstash로 수집 데이터를 MongoDB로 넣어준 뒤 그걸 꺼내 확인하는 앱인데 logstash로 넣은 데이터와 직접 수작업 쿼리로 넣은 게 타입이 다른가?

라는 의문은 잠시 뒤로하고, 결과가 그러하니 그렇게 이해하는 것으로 넘어가기로 하고 (다음에 알아볼수 있으면 알아봐야지..) 우선은 문제부터 해결해야 할 것이야.


필드 value의 타입 확인하기

우선 몽고 shell로 접속.

자바스크립트처럼 간단히 타입을 확인할 수 있다고 한다.

1
> typeof db.collection.findOne().field

허나 이것은 Object라던지, number라던지, 자바스크립트 답게 리턴값이 그런식으로 날라온다. (…) 내가 원하는 게 아니야!

aggregate를 쓰는 방법도 있었지만, 뭐.. 얼추 넣은 값을 알고 있었는데다가 모든 필드를 확인할 필요도 없으니, 하나하나 대입하여 맞추는게 가장 빠르겠더라.

  • 아래 몽고DB의 데이터 타입 표를 참고하자. 어차피 숫자인걸 알고있으니, 1, 16, 18 세번만 하면 때려맞출 수 있지
TypeNumberAlias
Double1“double”
String2“string”
Object3“object”
Array4“array”
Binary data5“binData”
ObjectId7“objectId”
Boolean8“bool”
Date9“date”
Null10“null”
Regular Expression11“regex”
JavaScript13“javascript”
32-bit integer16“int”
Timestamp17“timestamp”
64-bit integer18“long”
Decimal12819“decimal”
Min key-1“minKey”
Max key127“maxKey”

https://www.mongodb.com/docs/manual/reference/operator/query/type/

사용법은 그저..마구 검색해버리면 되는것이다. 아래는 field라는 필드(컬럼) 의 value 값이 double인지 확인하는 쿼리이다.

1
> db.collection.find({field:{$type:1}})

depth가 있는 필드를 알아보려면 따옴표를 붙이고 "field.depth1" 같은 방식으로 비교하면 된다. 내 문제에서는 Double이었으므로 1을 넣었을 때 값이 출력되었다. 숫자를 쓰고 싶지 않다면 "double" 과 같은 Alias를 이용하면 된다.


필드 value 타입 변경

이제 들어간 값을 바꿔버릴 차례다.

1
2
3
4
> db.collection.updateMany(
  { field : { $type: 1 } },
  [{ $set: { field: { $toInt: "$field" } } }]
)

MongoDB는 각 document 녀석들이 자유분방하기 때문에 들어가 있는 값들을 updateMany로 통으로 바꿔줄 필요가 있다. 그리하여 updateMany의 첫 parameter는 filter(condition이라고 하는게 더 좋을거 같은데..)를, 두번째 parameter에 $set으로 field의 값을 바꿔주는 형태를 취하는 것이다.

String으로 바꾸고 싶으면 $toString을 사용한다. 이 역시 depth가 있는 필드의 type을 변경하려면 "$field.depth"와 같이 사용할 수 있으니 적절히 사용해보자. 날짜같은 걸 바꾸려면 다소 고생하겠지만.. 언젠가 해볼 기회가 있겠지?

아래 레퍼런스를 참고해보자.

https://www.mongodb.com/docs/manual/reference/operator/aggregation/


아무튼 해프닝은 해결되었다. 그래도 앱의 로직에서 타입을 검사해서 수정하는 편이 좀더 좋은 방법일 거야.

This post is licensed under CC BY 4.0 by the author.

카프카 클러스터 (Kafka Cluster) - failover

정규표현식 삽질 - asterisk(*) vs plus(+)