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 or 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, PCRE) 을 구현하지만, 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 예외가 발생합니다.