필드 유형
이 페이지의 내용
개요
이 가이드 에서는 MongoDB 문서의 스키마 정의하는 데 사용할 수 있는 Mongoid에서 지원되는 필드 유형에 대해 학습 수 있습니다.
MongoDB BSON types를 사용하여 문서 필드에 저장된 데이터 유형을 나타냅니다. Mongoid 애플리케이션 에서 BSON 데이터를 사용하려면 Mongoid가 런타임에 BSON types를 Ruby 유형으로 변환해야 합니다. 예시 들어, 데이터베이스 에서 문서 검색할 때 Mongoid는 BSON double
유형을 Ruby Float
유형을 사용하도록 변환합니다. 문서 다시 저장하면 Mongoid가 필드 BSON double
로 다시 변환합니다.
Mongoid의 문서 모델링에 대해 자세히 학습 모델에문서 모듈 포함 가이드 참조하세요.
참고
모델 클래스에서 필드 정의를 수정해도 데이터베이스 에 저장된 데이터는 변경되지 않습니다. 데이터베이스 필드 의 데이터 유형 변경하려면 데이터를 다시 저장해야 합니다.
필드 유형
field
및 type
매크로를 사용하여 모델 클래스에서 필드 이름과 유형을 정의할 수 있습니다. 다음 예시 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
orBoolean
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
, Time
및 DateTime
객체를 필드 에 할당하기 전에 명시적으로 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_at
및 u_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
BigDecimal
유형을 사용하면 향상된 정밀도로 숫자를 저장 수 있습니다. Mongoid는 Mongoid.map_big_decimal_to_decimal128
구성 속성 에 설정하다 값에 따라 두 가지 방식으로 BigDecimal
값을 저장합니다.
true
로 설정하다 하면 Mongoid는BigDecimal
값을 BSONDecimal128
값으로 저장합니다.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
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
다음 표에는 문자열 또는 기호로 지정할 수 있는 필드 유형이 나와 있습니다.
클래스 이름 | 기호 | 문자열 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
사용자 정의 필드 유형
사용자 정의 필드 유형을 생성하고 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
예외가 발생합니다.