Docs Menu

필드 유형

이 가이드 에서는 MongoDB 문서의 스키마 정의하는 데 사용할 수 있는 Mongoid에서 지원되는 필드 유형에 대해 학습 수 있습니다.

MongoDB BSON types를 사용하여 문서 필드에 저장된 데이터 유형을 나타냅니다. Mongoid 애플리케이션 에서 BSON 데이터를 사용하려면 Mongoid가 런타임에 BSON types를 Ruby 유형으로 변환해야 합니다. 예시 들어, 데이터베이스 에서 문서 검색할 때 Mongoid는 BSON double 유형을 Ruby Float 유형을 사용하도록 변환합니다. 문서 다시 저장하면 Mongoid가 필드 BSON double로 다시 변환합니다.

Mongoid의 문서 모델링에 대해 자세히 학습 모델에 문서 모듈 포함 가이드 를 참조하세요.

참고

모델 클래스에서 필드 정의를 수정해도 데이터베이스 에 저장된 데이터는 변경되지 않습니다. 데이터베이스 필드 의 데이터 유형 변경하려면 데이터를 다시 저장해야 합니다.

fieldtype 매크로를 사용하여 모델 클래스에서 필드 이름과 유형을 정의할 수 있습니다. 다음 예시 Person 클래스의 필드를 정의합니다.

class Person
include Mongoid::Document
field :name, type: String
field :date_of_birth, type: Date
field :weight, type: Float
end

다음 목록은 Mongoid에서 사용할 수 있는 필드 유형을 제공합니다.

  • Array

  • Bson::Binary

  • BigDecimal

  • Mongoid::Boolean 또는 Boolean

  • Date

  • DateTime

  • Float

  • Hash

  • Integer

  • Object

  • Bson::ObjectId

  • Range

  • Regexp

  • Set

  • String

  • Mongoid::StringifiedSymbol

  • Time

  • ActiveSupport::TimeWithZone

참고

Mongoid는 BSON::Int64 또는 BSON::Int32 필드 유형을 지원 하지 않습니다. Mongoid는 이러한 값을 데이터베이스 에 올바르게 저장하지만 문서를 조회 때 필드는 Integer 유형으로 반환됩니다.

마찬가지로 BSON::Decimal128 유형의 필드를 쿼리할 때 Mongoid는 필드를 BigDecimal 유형으로 반환합니다.

필드 의 유형을 지정하지 않으면 Mongoid는 이를 기본값 Object 유형으로 해석합니다. 유형이 지정되지 않은 필드 BSON 에 직접 직렬화할 수 있는 모든 유형의 값을 저장 수 있습니다. 필드 다른 유형의 데이터가 포함되어 있거나 필드 값의 유형을 알 수 없는 경우 필드 유형화하지 않은 상태로 둘 수 있습니다.

다음 예시 유형이 지정되지 않은 필드 있는 Product 클래스를 정의합니다.

class Product
include Mongoid::Document
field :name, type: String
field :properties
end

properties 필드 의 유형은 Object 이지만 해당 필드 에 저장된 데이터 유형에 따라 달라집니다. 다음 예시 두 가지 방법으로 properties 필드 에 데이터를 저장합니다.

product = Product.new(properties: "color=white,size=large")
# properties field saved as String: "color=white,size=large"
product = Product.new(properties: {color: "white", size: "large"})
# properties field saved as Object: {:color=>"white", :size=>"large"}

Mongoid는 데이터베이스 에서 읽을 때 유형이 지정되지 않은 필드에 대해 유형 변환을 수행하지 않기 때문에 특별한 처리가 필요한 값은 유형이 지정되지 않은 필드 의 값으로 올바르게 검색되지 않을 수 있습니다. 다음 BSON 데이터 유형은 유형이 지정되지 않은 필드에 저장 하지 마세요.

  • Date: 유형이 지정되지 않은 필드에서 Time(으)로 반환

  • DateTime: 유형이 지정되지 않은 필드에서 Time(으)로 반환

  • Range: 유형이 지정되지 않은 필드에서 Hash(으)로 반환

Hash 유형을 사용하여 필드 에 Hash 데이터를 저장 수 있습니다. 필드 를 Hash 로 지정하는 경우, 값이 데이터베이스 에 제대로 저장 되도록 MongoDB 이름 지정 제한 사항을 준수해야 합니다.

다음 예시 Person 클래스를 만들고 url 필드 Hash로 지정합니다.

class Person
include Mongoid::Document
field :first_name
field :url, type: Hash
end
person = Person.new(url: {'home_page' => 'http://www.homepage.com'})

Time 필드 값을 사용하여 값을 BSON Time 인스턴스로 저장 수 있습니다. Time 필드는 애플리케이션 에 구성된 구역 에 저장됩니다. 시간대 구성에 대해 자세히 학습 애플리케이션 구성 가이드 의 시간대 구성 섹션을 참조하세요.

다음 예시 Voter 클래스를 만들고 registered_at 필드 의 값이 Time 유형으로 지정합니다.

class Voter
include Mongoid::Document
field :registered_at, type: Time
end
Voter.new(registered_at: Date.today)

참고

Time(으)로 지정된 필드 에 Date 또는 DateTime 값을 저장하면 할당 시 해당 값이 Time(으)로 변환됩니다. Time 필드 에 문자열을 저장 하면 Mongoid가 Time.parse 메서드를 사용하여 문자열을 구문 분석합니다. Mongoid가 쿼리를 변환하는 방법에 대해 자세히 학습 쿼리 지정 가이드 의 필드 유형 쿼리 변환 섹션을 참조하세요.

Date로 지정된 필드 에 다음 값 유형을 저장 수 있습니다.

  • Date: 제공된 대로 값을 저장합니다.

  • Time: 값의 표준 구역 에 따라 값의 날짜 부분을 저장합니다.

  • DateTime: 값의 표준 구역 에 따라 값의 날짜 부분을 저장합니다.

  • ActiveSupport::TimeWithZone: 값의 표준 구역 에 따라 값의 날짜 부분을 저장합니다.

  • String: 문자열에 지정된 날짜를 저장합니다.

  • Integer: 값을 UTC 타임스탬프처럼 취하여 애플리케이션에 구성된 표준 구역 로 변환합니다. 그런 다음 Mongoid는 해당 타임스탬프에서 가져온 날짜를 저장합니다.

  • Float: 값을 UTC 타임스탬프처럼 취하여 애플리케이션에 구성된 표준 구역 로 변환합니다. 그런 다음 Mongoid는 해당 타임스탬프에서 가져온 날짜를 저장합니다.

Time 또는 DateTime 변환하면 시간 부분이 삭제되므로 String, TimeDateTime 객체를 필드 에 할당하기 전에 명시적으로 Date 로 변환하는 것이 좋습니다.

참고

데이터베이스 Date 필드 에 대한 문자열 값이 포함되어 있는 경우 운전자 Time.parse 메서드를 사용하여 값을 구문 분석한 다음 시간 부분을 삭제합니다. Time.parse 는 표준 시간대가 없는 값을 현지 시간으로 간주합니다. Mongoid가 쿼리를 변환하는 방법에 대해 자세히 학습 쿼리 지정 가이드 의 필드 유형 쿼리 변환 섹션을 참조하세요.

DateTime 로 정의된 필드 에 값을 할당하거나 이러한 필드에 쿼리 Mongoid는 해당 값을 MongoDB 서버 로 보내기 전에 UTC Time 값으로 변환합니다. Mongoid는 DateTime 객체 에 포함된 구역 와 함께 값을 저장합니다. 값을 조회 때 Mongoid는 UTC 시간을 애플리케이션 에 구성된 구역 로 변환합니다.

다음 예시 Ticket 클래스를 만들고 purchased_at 필드 DateTime 필드 로 지정합니다.

class Ticket
include Mongoid::Document
field :purchased_at, type: DateTime
end

DateTime 필드 에 정수 또는 부동 소수점 값을 저장하면 해당 값은 UTC에서 Unix 타임스탬프로 처리됩니다. 다음 예시 정수 값을 purchased_at 필드 에 저장합니다.

ticket.purchased_at = 1544803974
ticket.purchased_at
# Outputs: Fri, 14 Dec 2018 16:12:54 +0000

DateTime 필드 에 문자열 값을 저장하면 Mongoid는 지정된 시간대 구역 사용하여 티켓 저장합니다. 시간대 구역 지정되지 않은 경우, Mongoid는 애플리케이션 의 기본값 으로 구성된 시간대를 사용하여 값을 저장합니다.

ticket.purchased_at = 'Mar 4, 2018 10:00:00 +01:00'
ticket.purchased_at
# Outputs: Sun, 04 Mar 2018 09:00:00 +0000

시간대 구성에 대해 자세히 학습 애플리케이션 구성 가이드 의 시간대 구성 섹션을 참조하세요.

참고

Mongoid는 시간대가 없는 값을 현지 시간으로 간주하는 Time.parse 메서드를 사용하여 문자열 값을 DateTime(으)로 구문 분석합니다.

클래스를 만들 때 Mongoid::Timestamps 모듈을 포함하여 클래스에 타임스탬프 필드를 포함할 수 있습니다. Mongoid::Timestamps를 포함하면 Mongoid는 클래스에 다음 필드를 생성합니다.

  • created_at: 문서 가 생성된 시간을 저장합니다.

  • updated_at: 문서 마지막으로 업데이트된 시간을 저장합니다.

다음 예시 타임스탬프 필드가 있는 Post 클래스를 만듭니다.

class Post
include Mongoid::Document
include Mongoid::Timestamps
end

Created 또는 Updated 모듈만 포함하여 created_at 또는 updated_at 필드만 포함하도록 선택할 수도 있습니다. 다음 예시 created_at 필드 만 있는 Post 클래스와 updated_at 필드 만 있는 Post 클래스를 만듭니다.

class Post
include Mongoid::Document
include Mongoid::Timestamps::Created
end
class Post
include Mongoid::Document
include Mongoid::Timestamps::Updated
end

모듈을 포함할 때 ::Short 옵션을 설정하여 타임스탬프 필드 이름을 c_atu_at(으)로 줄일 수 있습니다.

class Post
include Mongoid::Document
include Mongoid::Timestamps::Short # For c_at and u_at.
end
class Post
include Mongoid::Document
include Mongoid::Timestamps::Created::Short # For c_at only.
end
class Post
include Mongoid::Document
include Mongoid::Timestamps::Updated::Short # For u_at only.
end

메서드 호출에서 timeless 메서드를 호출하여 특정 작업에 대한 타임스탬프 필드 생성을 비활성화할 수 있습니다. 다음 예시 save 작업에 대한 타임스탬프를 비활성화합니다.

post.timeless.save

Regexp 유형을 사용하여 필드 에 정규 표현식을 저장 수 있습니다.

MongoDB PCRE( 펄 (Perl) Compatible regular Expressions)를 구현하지만, Mongoid는 Ruby의 Onigmo 라이브러리를 사용합니다. PCRE와 Onigmo는 일반적으로 유사한 기능을 제공하지만, 몇 가지 구문 차이점이 있습니다. 예시 를 들어, Onigmo는 \A\z 를 사용하여 문자열의 시작과 끝을 일치시키는 반면, PCRE는 ^$를 사용합니다.

필드 를 Regexp로 선언하면 Mongoid는 결과를 데이터베이스 에 저장할 때 Ruby 정규 표현식을 BSON 정규 표현식으로 변환합니다. 데이터베이스 필드 Bson::Regexp::Raw 인스턴스 로 반환합니다. BSON::Regexp::Raw 인스턴스에서 compile 메서드를 사용하여 데이터를 Ruby 정규 표현식 으로 다시 변환할 수 있습니다.

다음 예시 Token 클래스를 만들고 pattern 필드 Regexp로 지정합니다.

class Token
include Mongoid::Document
field :pattern, type: Regexp
end
token = Token.create!(pattern: /hello.world/m)
token.pattern
# Outputs: /hello.world/m
# Reload the token from the database
token.reload
token.pattern
# Outputs: #<BSON::Regexp::Raw:0x0000555f505e4a20 @pattern="hello.world", @options="ms">

중요

BSON 정규 표현식 Ruby 정규 표현식 으로 변환하면 원본과 다른 정규 표현식 생성될 수 있습니다. 이 차이는 Onigmo 구문과 PCRE 구문 간의 차이 때문입니다. Mongoid의 정규 표현식에 대해 자세히 학습 쿼리 지정 가이드 의 정규 표현식 섹션을 참조하세요.

BigDecimal 유형을 사용하면 향상된 정밀도로 숫자를 저장 수 있습니다. Mongoid는 Mongoid.map_big_decimal_to_decimal128 구성 속성 에 설정하다 값에 따라 두 가지 방식으로 BigDecimal 값을 저장합니다.

  • true로 설정하다 하면 Mongoid는 BigDecimal 값을 BSON Decimal128 값으로 저장합니다.

  • false ( 기본값 )으로 설정하다 하면 Mongoid는 BigDecimal 값을 문자열로 저장합니다.

Mongoid.map_big_decimal_to_decimal128 옵션을 true로 설정할 때는 다음과 같은 제한 사항을 고려하세요.

  • Decimal128 범위 와 정밀도는 제한되어 있습니다. Decimal128 의 최대값은 약 10^6145 이고 최소값은 약 -10^6145이며 최대 정밀도는 34 비트입니다. 이러한 제한을 벗어난 값을 저장하는 경우 대신 문자열로 저장하는 것이 좋습니다.

  • Decimal128 은(는) 부호가 있는 NaN 값을 허용하지만 BigDecimal 는 허용하지 않습니다. 데이터베이스 에서 부호가 있는 NaN Decimal128 값을 BigDecimal 로 검색하면 부호가 없는 값이 반환됩니다.

  • Decimal128 은 후행 0을 유지하지만 BigDecimal 은(는) 유지하지 않습니다. 이 때문에 데이터베이스 에서 Decimal128 값을 BigDecimal(으)로 검색하면 정밀도가 손실될 수 있습니다.

참고

Mongoid.map_big_decimal_to_decimal128 옵션을 false 로 설정하다 하고 BigDecimal 를 유형이 지정되지 않은 필드 에 저장 하면 필드 BigDecimal로 쿼리 할 수 없습니다. 값은 문자열로 저장되므로 유형이 지정되지 않은 필드 에서 BigDecimal 값을 쿼리해도 데이터베이스 에서 값을 찾을 수 없습니다. 값을 찾으려면 먼저 쿼리 값을 문자열로 변환해야 합니다.

필드 유형이 지정되지 않은 대신 BigDecimal 유형으로 지정하면 이 문제를 방지할 수 있습니다.

StringifiedSymbol 필드 유형을 사용하여 Ruby 애플리케이션에 기호로 노출해야 하는 값을 저장 . StringifiedSymbol 를 사용하면 다른 드라이버와의 상호 운용성을 보장하면서 기호를 사용할 수 있습니다. 이 유형은 데이터베이스 의 모든 데이터를 문자열로 저장하고, 애플리케이션 에서 읽을 때 문자열을 기호로 변환합니다. 정수, 배열과 같이 기호로 직접 변환할 수 없는 값은 문자열로 변환한 다음 기호로 변환합니다.

다음 예시 status 필드 StringifiedSymbol 로 정의하고 필드 가 저장되고 반환되는 방법을 보여 줍니다.

class Post
include Mongoid::Document
field :status, type: StringifiedSymbol
end
# Save status as a symbol
post = Post.new(status: :hello)
# status is stored as "hello" on the database, but returned as a Symbol
post.status
# Outputs: :hello
# Save status as a string
post = Post.new(status: "hello")
# status is stored as "hello" in the database, but returned as a Symbol
post.status
# Outputs: :hello

Mongoid에서는 클래스 이름 대신 문자열이나 기호를 사용하여 특정 필드 유형을 지정할 수 있습니다. 다음 예시 클래스 이름, 문자열 및 기호를 사용하여 order_num 필드 지정합니다.

class Order
include Mongoid::Document
# Class Name
field :order_num, type: Integer
# Symbol
field :order_num, type: :integer
# String
field :order_num, type: "integer"
end

다음 표에는 문자열 또는 기호로 지정할 수 있는 필드 유형이 나와 있습니다.

클래스 이름
기호
문자열

Array

:array

"Array"

BigDecimal

:big_decimal

"BigDecimal"

BSON::Binary

:binary

"BSON::Binary"

Mongoid::Boolean

:boolean

"Mongoid::Boolean"

Date

:date

"Date"

DateTime

:date_time

"DateTime"

Float

:float

"Float"

Hash

:hash

"Hash"

Integer

:integer

"Integer"

BSON::ObjectId

:object_id

"BSON::ObjectId"

Range

:range

"Range"

Regexp

:regexp

"Regexp"

Set

:set

"Set"

String

:string

"String"

StringifiedSymbol

:stringified_symbol

"StringifiedSymbol"

Symbol

:symbol

"Symbol"

Time

:time

"Time"

사용자 정의 필드 유형을 생성하고 Mongoid가 이를 직렬화 및 역직렬화하는 방법을 정의할 수 있습니다. 사용자 지정 필드 유형을 생성하려면 다음 메서드를 구현하는 클래스를 정의하세요.

  • mongoize: 사용자 지정 유형의 인스턴스 가져와서 MongoDB 저장 수 있는 객체 로 변환합니다.

  • demongoize: MongoDB 에서 객체 가져와 사용자 지정 유형의 인스턴스 로 변환합니다.

  • evolve: 사용자 지정 유형의 인스턴스 가져와서 MongoDB 데이터베이스 쿼리 데 사용할 수 있는 기준으로 변환합니다.

다음 예시 Point(이)라는 사용자 지정 필드 유형을 만들고 앞의 메서드를 구현합니다.

class Point
attr_reader :x, :y
def initialize(x, y)
@x, @y = x, y
end
# Converts an object of this instance into an array
def mongoize
[ x, y ]
end
class << self
# Takes any possible object and converts it to how it is
# stored in the database.
def mongoize(object)
case object
when Point then object.mongoize
when Hash then Point.new(object[:x], object[:y]).mongoize
else object
end
end
# Gets the object as it's stored in the database and instantiates
# this custom class from it.
def demongoize(object)
if object.is_a?(Array) && object.length == 2
Point.new(object[0], object[1])
end
end
# Converts the object supplied to a criteria and converts it
# into a queryable form.
def evolve(object)
case object
when Point then object.mongoize
else object
end
end
end
end

앞의 예시 에서 mongoize 인스턴스 메서드는 사용자 지정 유형 객체 의 인스턴스 허용하고 이를 로 변환하여 Array 데이터베이스 에 저장 합니다. mongoize 클래스 메서드는 모든 유형의 객체를 허용하고 이를 데이터베이스 에 저장할 수 있는 유사한 유형으로 변환합니다. Mongoid는 getter 및 setter 메서드를 호출할 때 mongoize 클래스 메서드를 사용합니다.

demongoize 메서드는 저장된 Array 값을 사용자 지정 Point 유형으로 변환합니다. Mongoid는 게터를 호출할 때 이 메서드를 사용합니다.

evolve 메서드는 사용자 지정 Point 유형을 쿼리 가능한 Array 유형으로 변환하고 다른 모든 유형을 object로 변환합니다. Mongoid는 데이터베이스 를 쿼리하는 메서드를 호출할 때 이 메서드를 사용합니다.

애플리케이션 에 할당된 값과 다른 값을 데이터베이스 에 저장하는 사용자 지정 필드 유형을 만들 수 있습니다. 이 기능은 애플리케이션 에 설명이 포함된 값을 사용하면서 데이터베이스 에 보다 간결한 값을 저장하는 데 유용할 수 있습니다.

다음 예시 애플리케이션 에서 색상 이름을 사용하지만 데이터베이스 에 색상을 정수로 저장하는 ColorMapping 유형을 만듭니다.

class ColorMapping
MAPPING = {
'black' => 0,
'white' => 1,
}.freeze
INVERSE_MAPPING = MAPPING.invert.freeze
class << self
def mongoize(object)
MAPPING[object]
end
def demongoize(object)
INVERSE_MAPPING[object]
end
def evolve(object)
MAPPING.fetch(object, object)
end
end
end
class Profile
include Mongoid::Document
field :color, type: ColorMapping
end
profile = Profile.new(color: 'white')
profile.color
# Outputs: "white"
# Sets "color" field to 0 in MongoDB
profile.save!

모델에 Mongoid::Attributes::Dynamic 모듈을 포함하여 Mongoid가 필드를 동적으로 생성하도록 지시할 수 있습니다. 이를 통해 Mongoid는 임의의 해시 또는 데이터베이스 에 이미 저장된 문서를 기반으로 필드를 생성할 수 있습니다.

다음 예시 동적 필드가 있는 Person 클래스를 만듭니다.

class Person
include Mongoid::Document
include Mongoid::Attributes::Dynamic
end

동일한 클래스 내에서 고정 필드와 동적 필드를 모두 지정할 수 있습니다. 이 경우 Mongoid는 필드 유형에 따라 필드 정의가 있는 속성의 모든 속성을 동적으로 처리하고 다른 모든 속성은 동적으로 처리합니다.

애플리케이션 에서 동적 필드를 사용할 때는 처음에 다음 방법 중 하나로 값을 설정하다 해야 합니다.

  • 속성 해시를 생성자에 전달합니다.

  • attributes= 메서드를 사용하여 값을 할당합니다.

  • []= 메서드를 사용하여 값을 할당합니다.

  • write_attribute 메서드를 사용하여 값을 할당합니다.

  • 데이터베이스 에 이미 있는 값으로 작업합니다.

앞의 옵션 중 하나를 사용하여 처음에 값을 설정하다 하지 않은 경우 속성을 호출하면 NoMethodError이(가) 반환됩니다.

Mongoid와 MongoDB 쿼리 API 모두 중첩된 문서에서 필드 이름을 구분하기 위해 . 문자를 사용하고, 쿼리 연산자 나타내기 위해 문자열 시작 부분에 $ 문자를 사용합니다. 따라서 필드 이름에 이러한 문자를 사용하지 않아야 합니다.

애플리케이션 이러한 문자를 사용해야 하는 경우 send 메서드를 호출하여 필드에 액세스 할 수 있습니다. 다음 예시 예약 문자가 포함된 필드가 있는 User 클래스를 만듭니다. 그런 다음 send 메서드를 사용하여 필드에 액세스합니다.

class User
include Mongoid::Document
field :"first.last", type: String
field :"$_amount", type: Integer
end
user = User.first
user.send(:"first.last")
# Outputs: Mike.Trout
user.send(:"$_amount")
# Outputs: 42650000

read_attribute 메서드를 호출하여 이러한 필드 액세스 할 수도 있습니다.

중요

이러한 예약 문자가 포함된 필드를 업데이트하고 바꾸려면 특수 연산자가 필요하므로 이러한 필드에서 게터 및 세터를 호출하면 InvalidDotDollarAssignment 예외가 발생합니다.