BSON 튜토리얼
이 페이지의 내용
- 설치
- ActiveSupport와 함께 사용
- BSON 직렬화
- 바이트 버퍼
- 쓰기
- 읽기
- 지원되는 클래스
BSON::Binary
BSON::Code
BSON::CodeWithScope
BSON::DBRef
BSON::Document
BSON::MaxKey
BSON::MinKey
BSON::ObjectId
BSON::Timestamp
BSON::Undefined
BSON::Decimal128
Symbol
- JSON 직렬화
- 시간 인스턴스
- 날짜/시간 인스턴스
- 날짜 인스턴스
- 정규 표현식
- Ruby 대 MongoDB 정규 표현식
BSON::Regexp::Raw
클래스- 정규 표현식 변환
- 읽기 및 쓰기
- 키 순서
- 중복 키
이 튜토리얼에서는 Ruby BSON 라이브러리 사용에 대해 설명합니다.
설치
BSON 라이브러리는 Rubygems 에서 설치할 수 있습니다. 수동으로 또는 번들러를 사용하여 생성할 수 있습니다.
gem을 수동으로 설치하려면,
gem install bson
번들러를 사용하여 gem을 설치하려면 Gemfile
에 다음을 포함하세요.
gem 'bson'
BSON 라이브러리는 >= 2.5 및 JRuby >= 9.2와 호환됩니다.
ActiveSupport와 함께 사용
TimeWithZone과 같은 ActiveSupport에서 정의된 클래스에 대한 직렬화는 ActiveSupport에 대한 BSON의 엄격한 종속성을 피하기 위해 기본적으로 로드되지 않습니다. ActiveSupport를 사용하는 애플리케이션에서 BSON을 사용할 때는 ActiveSupport 관련 코드가 명시적으로 필요합니다.
require 'bson' require 'bson/active_support'
BSON 직렬화
Ruby 객체의 원시 BSON 표현을 얻으려면 Ruby 객체에서 to_bson
을(를) 호출하면 BSON::ByteBuffer
이(가) 반환됩니다. 예를 들면 다음과 같습니다.
"Shall I compare thee to a summer's day".to_bson 1024.to_bson
BSON에서 객체를 생성하는 것은 인스턴스화하려는 클래스에서 from_bson
를 호출하고 BSON::ByteBuffer
인스턴스를 전달하여 수행됩니다.
String.from_bson(byte_buffer) BSON::Int32.from_bson(byte_buffer)
바이트 버퍼
BSON 라이브러리 4.0에서는 성능 개선을 위해 StringIO
을(를) 사용하는 대신 자기공명(MRI) 및 JRuby에서 네이티브 바이트 버퍼를 사용하는 기능을 도입했습니다.
쓰기
쓰기 위해 ByteBuffer
을 만들려면(예: BSON으로 직렬화), 인수 없이 BSON::ByteBuffer
을 인스턴스화합니다:
buffer = BSON::ByteBuffer.new
변환 없이 바이트 버퍼에 원시 바이트를 쓰려면 put_byte
및 put_bytes
메서드를 사용합니다. 바이트 문자열을 인수로 사용하여 이 문자열을 버퍼에 복사합니다. put_byte
는 인수가 길이가 1인 문자열을 강제합니다. put_bytes
은 모든 길이의 문자열을 허용합니다. 문자열에는 null 바이트가 포함될 수 있습니다.
buffer.put_byte("\x00") buffer.put_bytes("\xff\xfe\x00\xfd")
참고
put_byte
및 put_bytes
은(는) 바이트 버퍼에 인수를 쓰기 전에 BSON type 바이트를 쓰지 않습니다.
후속 쓰기 메서드는 BSON 사양 에서 특정 유형의 객체를 씁니다. . 메서드 이름에 put_int32
유형은 인수의 유형보다 우선합니다. .
UTF-8 문자열(BSON type 0x02)을 바이트 버퍼에 쓰려면 put_string
을 사용합니다.
buffer.put_string("hello, world")
BSON 문자열은 항상 UTF-8로 인코딩됩니다. 따라서 인수는 UTF-8 또는 UTF-8로 변환 가능한 인코딩(예: 바이너리가 아님). 인수가 UTF-8 이외의 인코딩으로 된 경우 문자열이 먼저 UTF-8로 변환되고 UTF-8로 인코딩된 버전이 버퍼에 기록됩니다. 문자열은 청구된 인코딩으로 유효해야 하며, 인코딩이 UTF-8인 경우 유효한 UTF-8이어야 합니다. 문자열에 null 바이트가 포함될 수 있습니다.
BSON 사양은 예를 들어 문서 키에 사용되는 CString 형식도 정의합니다. 버퍼에 CString을 쓰려면 put_cstring
을 사용합니다.
buffer.put_cstring("hello, world")
일반 문자열과 마찬가지로 BSON의 CStrings는 UTF-8로 인코딩되어야 합니다. 인수가 UTF-8이 아닌 경우 UTF-8로 변환되고 결과 문자열이 버퍼에 기록됩니다. 와 달리 put_string
에 제공된 인수의 UTF-8 인코딩은 put_cstring
BSON의 CString 직렬화 형식이 null로 종료되므로 null 바이트를 가질 수 없습니다.
과 put_string
put_cstring
달리 는 기호와 정수도 허용합니다. 모든 경우에 인수는 작성되기 전에 문자열화됩니다.
buffer.put_cstring(:hello) buffer.put_cstring(42)
32비트 또는 64비트 정수를 바이트 버퍼에 쓰려면 put_int32
및 put_int64
메서드를 각각 사용합니다. Ruby 정수는 임의로 커질 수 있습니다. 기록 중인 값이 32비트 또는 64비트 정수 범위를 초과하면 put_int32
및 put_int64
는 RangeError
를 발생시킵니다.
buffer.put_int32(12345) buffer.put_int64(123456789012345)
참고
put_int32
또는 put_int64
에 부동 소수점 인수가 제공되면 인수가 먼저 정수로 강제 변환되고 정수가 바이트 버퍼에 기록됩니다.
64비트 부동 소수점 값을 바이트 버퍼에 쓰려면 put_double
을 사용합니다.
buffer.put_double(3.14159)
직렬화된 데이터를 바이트 문자열로 가져오려면(예: 소켓을 통해 데이터를 보내려면) 버퍼에서 to_s
를 호출합니다.
buffer = BSON::ByteBuffer.new buffer.put_string('testing') socket.write(buffer.to_s)
참고
ByteBuffer
읽기 및 쓰기 위치를 별도로 추적합니다. 쓰기를 위해 버퍼를 되돌릴 수 있는 방법은 없습니다 - rewind
은 읽기 위치에만 영향을 미칩니다.
읽기
읽기용 ByteBuffer
을(를) 만들려면(예: BSON에서 역직렬화), 바이트 문자열을 인수로 사용하여 BSON::ByteBuffer
을 인스턴스화합니다.
buffer = BSON::ByteBuffer.new(string) # a read mode buffer.
버퍼에서 읽기는 다음 API를 통해 수행됩니다.
buffer.get_byte # Pulls a single byte from the buffer. buffer.get_bytes(value) # Pulls n number of bytes from the buffer. buffer.get_cstring # Pulls a null-terminated string from the buffer. buffer.get_double # Pulls a 64-bit floating point from the buffer. buffer.get_int32 # Pulls a 32-bit integer (4 bytes) from the buffer. buffer.get_int64 # Pulls a 64-bit integer (8 bytes) from the buffer. buffer.get_string # Pulls a UTF-8 string from the buffer.
버퍼의 처음부터 읽기를 다시 시작하려면 rewind
을 사용합니다.
buffer.rewind
참고
ByteBuffer
읽기 및 쓰기 위치를 별도로 추적합니다. rewind
은 읽기 위치에만 영향을 미칩니다.
지원되는 클래스
BSON 사양에 표현이 있고 이에 대해 to_bson
메서드가 정의될 핵심 Ruby 클래스는 다음과 같습니다: Object
, Array
, FalseClass
, Float
, Hash
, Integer
, BigDecimal
, NilClass
, Regexp
, String
, Symbol
(사용 중단됨), Time
, TrueClass
.
핵심 Ruby 객체 외에도 BSON은 사양에 특정한 몇 가지 특수 유형을 제공합니다.
BSON::Binary
BSON::Binary
객체를 사용하여 임의의 바이너리 데이터를 저장합니다. Binary
객체는 다음과 같이 바이너리 문자열로 구성할 수 있습니다.
BSON::Binary.new("binary_string") # => <BSON::Binary:0x47113101192900 type=generic data=0x62696e6172795f73...>
기본적으로 Binary
객체는 BSON 바이너리 하위 유형 0(:generic
)으로 생성됩니다. 하위 유형을 명시적으로 지정하여 바이트가 특정 유형의 데이터를 인코딩함을 나타낼 수 있습니다.
BSON::Binary.new("binary_string", :user) # => <BSON::Binary:0x47113101225420 type=user data=0x62696e6172795f73...>
유효한 하위 유형은 :generic
, :function
, :old
, :uuid_old
, :uuid
, :md5
및 :user
입니다.
데이터와 하위 유형은 다음과 같이 data
및 type
속성을 사용하여 Binary
인스턴스에서 검색할 수 있습니다.
binary = BSON::Binary.new("binary_string", :user) binary.data => "binary_string" binary.type => :user
참고
BSON::Binary
즉, 객체는 생성자에 전달된 문자열의 인코딩에 관계없이 항상 BINARY
인코딩으로 데이터를 저장합니다.
str = "binary_string" str.encoding # => #<Encoding:US-ASCII> binary = BSON::Binary.new(str) binary.data # => "binary_string" binary.data.encoding # => #<Encoding:ASCII-8BIT>
UUID 메서드
RFC 4122 호환 문자열 표현에서 UUID BSON::Binary(바이너리 하위 유형 4)를 생성하려면 from_uuid
메서드를 사용합니다.
uuid_str = "00112233-4455-6677-8899-aabbccddeeff" BSON::Binary.from_uuid(uuid_str) # => <BSON::Binary:0x46986653612880 type=uuid data=0x0011223344556677...>
UUID BSON::Binary를 RFC 4122 호환 표현으로 문자열화하려면 to_uuid
메서드를 사용합니다.
binary = BSON::Binary.new("\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF".force_encoding('BINARY'), :uuid) => <BSON::Binary:0x46942046606480 type=uuid data=0x0011223344556677...> binary.to_uuid => "00112233-4455-6677-8899aabbccddeeff"
표준 표현은 from_uuid
및 to_uuid
메서드를 모두 호출할 때 명시적으로 지정할 수 있습니다.
binary = BSON::Binary.from_uuid(uuid_str, :standard) binary.to_uuid(:standard)
:standard
표현은 하위 유형 :uuid
( :uuid_old
제외)의 바이너리에서만 사용할 수 있습니다.
레거시 UUID
하위 유형 3(:uuid_old
)의 BSON::Binary 객체에 저장된 데이터는 데이터를 생성한 드라이버에 따라 세 가지 바이트 순서 중 하나로 유지될 수 있습니다. 바이트 순서는 C# 레거시, Java 레거시 및 Python 레거시입니다. Python 레거시 바이트 순서는 표준 RFC 4122 바이트 순서와 동일합니다. C# 레거시 및 Java 레거시 바이트 주문에서는 일부 바이트가 교환되었습니다.
레거시 UUID를 포함하는 바이너리 객체는 UUID가 저장 되는 형식을 인코딩하지 않습니다. 따라서 레거시 UUID 형식으로 변환하거나 그 반대로 변환하는 메서드는 원하는 형식 또는 표현을 인수로 사용합니다. 애플리케이션은 데이터가 저장되는 바이트 순서를 알지 못한 채 레거시 UUID 바이너리 객체를 복사할 수 있습니다.
레거시 UUID 형식으로 데이터를 저장하는 기존 배포와의 상호 운용성을 위해 다음과 같은 레거시 UUID 작업 방법을 제공합니다. 새 애플리케이션은 RFC 4122를 준수하는 :uuid
(하위 유형 4) 형식만 사용하는 것이 좋습니다.
레거시 UUID BSON::Binary를 문자열화하려면 원하는 표현을 지정하는 to_uuid
메서드를 사용합니다. 허용되는 표현은 :csharp_legacy
, :java_legacy
및 :python_legacy
입니다. 레거시 UUID BSON::Binary는 표현을 지정하지 않고는 문자열화할 수 없습니다.
binary = BSON::Binary.new("\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF".force_encoding('BINARY'), :uuid_old) => <BSON::Binary:0x46942046606480 type=uuid data=0x0011223344556677...> binary.to_uuid # => ArgumentError (Representation must be specified for BSON::Binary objects of type :uuid_old) binary.to_uuid(:csharp_legacy) # => "33221100-5544-7766-8899aabbccddeeff" binary.to_uuid(:java_legacy) # => "77665544-3322-1100-ffeeddccbbaa9988" binary.to_uuid(:python_legacy) # => "00112233-4455-6677-8899aabbccddeeff"
UUID의 문자열 표현에서 레거시 UUID BSON::Binary를 만들려면 원하는 표현을 지정하는 from_uuid
메서드를 사용합니다.
uuid_str = "00112233-4455-6677-8899-aabbccddeeff" BSON::Binary.from_uuid(uuid_str, :csharp_legacy) # => <BSON::Binary:0x46986653650480 type=uuid_old data=0x3322110055447766...> BSON::Binary.from_uuid(uuid_str, :java_legacy) # => <BSON::Binary:0x46986653663960 type=uuid_old data=0x7766554433221100...> BSON::Binary.from_uuid(uuid_str, :python_legacy) # => <BSON::Binary:0x46986653686300 type=uuid_old data=0x0011223344556677...>
다음 메서드를 사용하여 한 표현에서 다른 표현으로 변환할 수 있습니다.
BSON::Binary.from_uuid('77665544-3322-1100-ffeeddccbbaa9988',:java_legacy).to_uuid(:csharp_legacy) # => "33221100-5544-7766-8899aabbccddeeff"
BSON::Code
JavaScript 코드의 문자열을 나타냅니다.
BSON::Code.new("this.value = 5;")
BSON::CodeWithScope
참고
CodeWithScope
유형은 MongoDB 4.2.1부터 더 이상 사용되지 않습니다. MongoDB 4.4부터 CodeWithScope
의 지원이 $where
과 같은 다양한 서버 명령 및 연산자에서 제거됩니다. MongoDB 4.4 이상으로 작업할 때는 다른 BSON types 및 연산자를 사용하세요.
값 해시가 있는 JavaScript 코드 문자열을 나타냅니다.
BSON::CodeWithScope.new("this.value = age;", age: 5)
BSON::DBRef
이는 DBRef의 collection, ID 및 데이터베이스에 대한 접근자를 제공하는 BSON::Document
의 하위 클래스입니다.
BSON::DBRef.new({"$ref" => "collection", "$id" => "id"}) BSON::DBRef.new({"$ref" => "collection", "$id" => "id", "database" => "db"})
참고
BSON::DBRef 생성자는 지정된 해시의 유효성을 검사하고 유효한 DBRef가 아닌 경우 ArgumentError를 발생시킵니다. BSON::ExtJSON.parse_obj
및 Hash.from_bson
은 유효하지 않은 DBRef가 주어질 경우 오류를 발생시키지 않고, 대신 해시를 구문 분석하거나 BSON::문서를 역직렬화합니다.
참고
모든 BSON 문서는 유효한 DBRef인 경우 BSON::DBRef 인스턴스로 역직렬화되고, 그렇지 않으면 BSON::문서 인스턴스로 역직렬화됩니다. 이는 Hash
클래스에서 호출이 이루어진 경우에도 마찬가지입니다.
bson = {"$ref" => "collection", "$id" => "id"}.to_bson.to_s loaded = Hash.from_bson(BSON::ByteBuffer.new(bson)) => {"$ref"=>"collection", "$id"=>"id"} loaded.class => BSON::DBRef
MongoDB Ruby 드라이버 버전 2.17 및 이전 버전과의 호환성을 위해 레거시 드라이버 API를 사용하여 BSON::DBRef
를 구성할 수도 있습니다. 이 API는 더 이상 사용되지 않으며 이후 bson-ruby
버전에서 제거될 예정입니다.
BSON::DBRef.new("collection", BSON::ObjectId('61eeb760a15d5d0f9f1e401d')) BSON::DBRef.new("collection", BSON::ObjectId('61eeb760a15d5d0f9f1e401d'), "db")
BSON::Document
이는 모든 키를 문자열로 저장하지만 기호 키를 사용하여 액세스를 허용하는 Hash
의 하위 클래스입니다.
BSON::Document[:key, "value"] BSON::Document.new
참고
Hash
클래스에서 호출이 이루어진 경우에도 모든 BSON 문서는 BSON::Document(또는 유효한 DBRef인 경우 BSON::DBRef)의 인스턴스로 역직렬화됩니다.
bson = {test: 1}.to_bson.to_s loaded = Hash.from_bson(BSON::ByteBuffer.new(bson)) => {"test"=>1} loaded.class => BSON::Document
BSON::MaxKey
항상 다른 값과 더 높게 비교되는 BSON의 값을 나타냅니다.
BSON::MaxKey.new
BSON::MinKey
항상 다른 값과 비교하여 더 낮은 값으로 비교되는 BSON의 값을 나타냅니다.
BSON::MinKey.new
BSON::ObjectId
지정된 컴퓨터의 객체에 대한 12바이트 고유 식별자를 나타냅니다.
BSON::ObjectId.new
BSON::Timestamp
시작 및 증분 값이 있는 특수 시간을 나타냅니다.
BSON::Timestamp.new(5, 30)
BSON::Undefined
제공되지 않은 값에 대한 자리 표시자를 나타냅니다.
BSON::Undefined.new
BSON::Decimal128
정확한 정밀도로 소수점 반올림을 에뮬레이션할 수 있는 128비트 소수점 기반 부동 소수점 값을 나타냅니다.
# Instantiate with a String BSON::Decimal128.new("1.28") # Instantiate with a BigDecimal d = BigDecimal(1.28, 3) BSON::Decimal128.new(d)
BSON::Decimal128 대 BigDecimal
BigDecimal
from_bson
및 to_bson
메서드는 내부에서 동일한 BSON::Decimal128
메서드를 사용합니다. 이로 인해 BSON으로 직렬화할 수 있는 BigDecimal
값과 기존 decimal128
BSON 값에서 역직렬화할 수 있는 값에 적용되는 몇 가지 제한 사항이 있습니다. 이렇게 변경한 이유는 BigDecimal
인스턴스를 BSON::Decimal128
인스턴스로 직렬화하면 MongoDB에서 쿼리 및 애그리게이션 측면에서 더 많은 유연성을 확보할 수 있기 때문입니다. BigDecimal
에 부과된 제한 사항은 다음과 같습니다:
decimal128
범위와 정밀도에서 제한이 있으나BigDecimal
는 범위와 정밀도 측면에서 제한이 없습니다.decimal128
의 최대값은 약10^6145
이고 최소값은 약-10^6145
이며 최대 정밀도는 34비트입니다.decimal128
기호가 있는NaN
값을 받아들일 수 있는 반면,BigDecimal
은 허용하지 않습니다.BigDecimal
인스턴스로 역직렬화된 기호가 있는 모든NaN
값은 서명되지 않습니다.decimal128
BSON으로 직렬화하거나 BSON에서 역직렬화할 때 후행 0을 유지합니다. 그러나BigDecimal
은 후행 0을 유지하지 않으므로BigDecimal
를 사용하면 정밀도가 떨어질 수 있습니다.
참고
BSON 5.0에서는 기본적으로 decimal128
가 BigDecimal
로 역직렬화됩니다. decimal128
BSON 문서의 값을 로 역직렬화하려면 BSON::Decimal128
에 mode: :bson
옵션을 설정할 수 from_bson
있습니다.
Symbol
BSON 사양은 Ruby Symbol
값(즉, Ruby Symbol``is encoded into a BSON symbol
and a BSON symbol is decoded into a Ruby ``Symbol
) 왕복을 허용하는 기호 유형을 정의합니다. 그러나 대부분의 프로그래밍 언어에는 네이티브 기호 유형이 없기 때문에 MongoDB는 상호 운용성을 높이기 위해 BSON 기호 유형을 더 이상 사용하지 않고 대신 문자열을 사용하도록 권장합니다.
참고
BSON에서 해시 키 는 항상 문자열입니다. 문자열이 아닌 값은 해시 키로 사용될 때 문자열화됩니다:
Hash.from_bson({foo: 'bar'}.to_bson) # => {"foo"=>"bar"} Hash.from_bson({1 => 2}.to_bson) # => {"1"=>2}
기본적으로 BSON 라이브러리는 Symbol
해시 값을 문자열로 인코딩하고, BSON 기호를 Ruby Symbol
값으로 디코딩합니다.
{foo: :bar}.to_bson.to_s # => "\x12\x00\x00\x00\x02foo\x00\x04\x00\x00\x00bar\x00\x00" # 0x02 is the string type Hash.from_bson(BSON::ByteBuffer.new("\x12\x00\x00\x00\x02foo\x00\x04\x00\x00\x00bar\x00\x00".force_encoding('BINARY'))) # => {"foo"=>"bar"} # 0x0E is the symbol type Hash.from_bson(BSON::ByteBuffer.new("\x12\x00\x00\x00\x0Efoo\x00\x04\x00\x00\x00bar\x00\x00".force_encoding('BINARY'))) # => {"foo"=>:bar}
Ruby 기호를 BSON 기호로 강제 인코딩하려면 Ruby 기호를 BSON::Symbol::Raw
으로 래핑합니다.
{foo: BSON::Symbol::Raw.new(:bar)}.to_bson.to_s # => "\x12\x00\x00\x00\x0Efoo\x00\x04\x00\x00\x00bar\x00\x00"
JSON 직렬화
일부 BSON types는 JSON으로 특수 표현됩니다. 이는 다음과 같으며 to_json
을 호출할 때 양식으로 자동으로 직렬화됩니다.
객체 | JSON |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
시간 인스턴스
Ruby의 시간은 나노초의 정밀도를 가질 수 있습니다. BSON(및 MongoDB)의 시간은 밀리초의 정밀도만 가질 수 있습니다. Ruby Time
인스턴스가 BSON 또는 확장 JSON으로 직렬화될 때 시간은 가장 가까운 밀리초 단위로 내림차순입니다.
참고
항상 반올림된 시간입니다. 시간이 유닉스 시간(1970년 1월 1일 00:00:00 UTC) 이전이면 시간의 절대값이 증가합니다.
time = Time.utc(1960, 1, 1, 0, 0, 0, 999_999) time.to_f # => -315619199.000001 time.floor(3).to_f # => -315619199.001
참고
버전 9.2.11.0 기준의 JRuby Unix 이전 에포크 시간을 반올림합니다. . bson- Ruby는 이 문제를 해결하여 JRuby에서 직렬화할 때 시간을 올바르게 바닥으로 표시합니다.
부동 소수점 계산이 정확하지 않으면 예기치 않은 결과가 발생할 수 있으므로, 이러한 플로어링 때문에 애플리케이션에서는 정수 수학을 사용하여 모든 시간 계산을 수행할 것을 강력히 권장합니다.
날짜/시간 인스턴스
BSON은 유닉스 시간 이후의 시간(초)으로만 시간 저장을 지원합니다. Ruby의 DateTime
인스턴스는 BSON으로 직렬화할 수 있지만 BSON이 역직렬화되면 시간이 Time
인스턴스로 반환됩니다.
DateTime
Ruby의 클래스는 그레고리력이 아닌 캘린더를 지원합니다. 그레고리력이 아닌 DateTime
인스턴스가 직렬화되면 먼저 그레고리력으로 변환되고 그레고리력의 해당 날짜가 데이터베이스에 저장됩니다.
날짜 인스턴스
BSON은 유닉스 시간 이후의 시간(초)으로만 시간 저장을 지원합니다. Ruby의 Date
인스턴스는 BSON으로 직렬화할 수 있지만 BSON이 역직렬화되면 시간이 Time
인스턴스로 반환됩니다.
Date
인스턴스가 직렬화될 때 사용되는 시간 값은 Date
이 UTC로 참조하는 날의 자정입니다.
정규 표현식
MongoDB와 Ruby 모두 정규 표현식으로 작업할 수 있는 기능을 제공하지만, 정규 표현식 엔진을 사용합니다. 다음 하위 섹션에서는 Ruby 정규 표현식과 MongoDB 정규 표현식의 차이점과 두 가지를 모두 사용하는 방법을 설명합니다.
Ruby 대 MongoDB 정규 표현식
MongoDB 서버는 PCRE 라이브러리를 사용하여 구현된 펄(Perl) 호환 정규 표현식을 사용합니다. 및 Ruby 정규 표현식 Onigmo 정규 표현식 엔진 을 사용하여 구현됩니다. 은 Oniguruma 의 포크입니다. . 두 정규 표현식 구현은 일반적으로 동일한 기능을 제공하지만 아래에 설명된 대로 몇 가지 중요한 구문 차이점이 있습니다.
안타깝게도 프로그래밍 방식으로 PCRE 정규 표현식을 동등한 Ruby 정규 표현식으로 변환하는 간단한 방법이 없으며, 현재 PCRE에 대한 Ruby 바인딩도 없습니다.
옵션 / 플래그 / 수정자
Ruby와 PCRE 정규 표현식은 모두 수정자를 지원합니다. 이는 Ruby 용어로는 '옵션', PCRE 용어로는 '플래그'라고도 합니다. s
및 m
수정자의 의미는 Ruby와 PCRE에서 다릅니다.
Ruby에는
s
수정자가 없지만 대신 Rubym
수정자는 PCREs
수정자와 동일한 기능을 수행하여 마침표(.
)가 개행을 포함한 모든 문자와 일치하도록 합니다. 하지만, Ruby 문서에서는m
수정자를 '다중 라인 모드 활성화'라고 명시하고 있습니다.Ruby는 항상 PCRE 정규 표현식의
m
수정자로 활성화되는 PCRE의 다중 라인 모드와 동일한 방식으로 작동합니다. Ruby에서^
앵커는 항상 줄의 시작을 나타내고$
앵커는 항상 줄의 끝을 나타냅니다.
Ruby와 PCRE 환경(MongoDB Server 및 대부분의 다른 MongoDB 드라이버 포함)에서 모두 사용되는 표현식(이하 '이식용 표현식')을 작성할 때는 ^
및 $
앵커 사용을 피해야 합니다. 다음 섹션에서는 이식 가능한 정규 표현식을 작성하기 위한 해결 방법과 권장 사항을 제공합니다.
^
Anchor
Ruby 정규 표현식에서 ^
앵커는 항상 줄의 시작을 참조합니다. PCRE 정규 표현식에서 ^
앵커는 기본적으로 입력의 시작 부분을 참조하고, m
플래그는 의미를 줄의 시작으로 변경합니다.
Ruby와 PCRE 정규 표현식은 모두 수정자와 관계없이 입력의 시작을 참조하기 위해 \A
앵커를 지원합니다.
이식 가능한 정규 표현식을 작성할 때:
\A
앵커를 사용하여 입력의 시작 부분을 참조합니다.^
앵커를 사용하여 줄의 시작을 참조합니다(이를 위해서는 PCRE 정규 표현식에서m
플래그를 설정해야 함). 또는 수정자와 관계없이 작동하는 다음 구성 중 하나를 사용하세요: -(?:\A|(?<=\n))
(LF 및 CR+LF 줄 끝 처리) -(?:\A|(?<=[\r\n]))
(CR, LF 및 CR+LF 줄 끝 처리)
$
Anchor
Ruby 정규 표현식에서 $
앵커는 항상 줄의 끝을 나타냅니다. PCRE 정규 표현식에서 $
앵커는 기본적으로 입력의 끝을 참조하고, m
플래그는 의미를 줄의 끝으로 변경합니다.
Ruby와 PCRE 정규 표현식은 모두 수정자와 관계없이 입력의 끝을 참조하기 위해 \z
앵커를 지원합니다.
이식 가능한 정규 표현식을 작성할 때:
\z
앵커를 사용하여 입력의 끝을 참조합니다.$
앵커를 사용하여 줄의 시작을 참조합니다(이를 위해서는 PCRE 정규 표현식에서m
플래그를 설정해야 함). 또는 수정자와 관계없이 작동하는 다음 구성 중 하나를 사용하세요: -(?:\z|(?=\n))
(LF 및 CR+LF 줄 끝 처리) -(?:\z|(?=[\n\n]))
(CR, LF 및 CR+LF 줄 끝 처리)
BSON::Regexp::Raw
클래스
프로그래밍 방식으로 PCRE 정규 표현식을 동등한 Ruby 정규 표현식으로 변환하는 간단한 방법이 없으므로, bson- Ruby는 MongoDB/PCRE 정규 표현식을 보관하기 위한 BSON::Regexp::Raw
클래스를 제공합니다. 이 문서에서는 이 클래스의 인스턴스를 "BSON 정규 표현식"이라고 합니다.
이 클래스의 인스턴스는 정규 표현식 텍스트를 문자열로 사용하고 선택적 PCRE 수정자를 사용하여 만들 수 있습니다.
BSON::Regexp::Raw.new("^b403158") # => #<BSON::Regexp::Raw:0x000055df63186d78 @pattern="^b403158", @options=""> BSON::Regexp::Raw.new("^Hello.world$", "s") # => #<BSON::Regexp::Raw:0x000055df6317f028 @pattern="^Hello.world$", @options="s">
BSON::Regexp
모듈은 Ruby Regexp
클래스에 포함되어 있으므로 BSON::
접두사를 생략할 수 있습니다.
Regexp::Raw.new("^b403158") # => #<BSON::Regexp::Raw:0x000055df63186d78 @pattern="^b403158", @options=""> Regexp::Raw.new("^Hello.world$", "s") # => #<BSON::Regexp::Raw:0x000055df6317f028 @pattern="^Hello.world$", @options="s">
정규 표현식 변환
Ruby 정규 표현식을 BSON 정규 표현식으로 변환하려면 다음과 같이 BSON::Regexp::Raw
객체를 인스턴스화합니다.
regexp = /^Hello.world/ bson_regexp = BSON::Regexp::Raw.new(regexp.source, regexp.options) # => #<BSON::Regexp::Raw:0x000055df62e42d60 @pattern="^Hello.world", @options=0>
BSON::Regexp::Raw
생성자는 Ruby 숫자 옵션과 PCRE 수정자 문자열을 모두 허용합니다.
BSON 정규 표현식을 Ruby 정규 표현식으로 변환하려면 BSON 정규 표현식에서 compile
메서드를 호출하세요.
bson_regexp = BSON::Regexp::Raw.new("^hello.world", "s") bson_regexp.compile # => /^hello.world/m bson_regexp = BSON::Regexp::Raw.new("^hello", "") bson_regexp.compile # => /^hello.world/ bson_regexp = BSON::Regexp::Raw.new("^hello.world", "m") bson_regexp.compile # => /^hello.world/
첫 번째 예제에서는 s
PCRE 수정자가 m
Ruby 수정자로 변환되었으며, 마지막 두 예제는 원래의 BSON 정규 표현식이 서로 다른 의미를 가졌음에도 불구하고 동일한 정규 표현식으로 변환되었다는 점에 유의하세요.
BSON 정규 표현식이 이식성이 없는 ^
및 $
앵커를 사용하는 경우, Ruby 정규 표현식으로 변환하면 의미가 변경될 수 있습니다.
BSON::Regexp::Raw.new("^hello.world", "").compile =~ "42\nhello world" # => 3
Ruby 정규 표현식이 BSON 정규 표현식으로 변환되는 경우(예: 쿼리의 일부로 서버에 전송) BSON 정규 표현식에는 항상 ^
및 의 동작을 반영하는 m
수정자 세트가 있습니다. $
앵커를 사용합니다.
읽기 및 쓰기
Ruby와 BSON 정규 표현식은 모두 BSON으로의 직렬화를 위해 to_bson
메서드를 구현합니다.
regexp_ruby = /^b403158/ # => /^b403158/ regexp_ruby.to_bson # => #<BSON::ByteBuffer:0x007fcf20ab8028> _.to_s # => "^b403158\x00m\x00" regexp_raw = Regexp::Raw.new("^b403158") # => #<BSON::Regexp::Raw:0x007fcf21808f98 @pattern="^b403158", @options=""> regexp_raw.to_bson # => #<BSON::ByteBuffer:0x007fcf213622f0> _.to_s # => "^b403158\x00\x00"
Regexp
및 BSON::Regexp::Raw
클래스는 모두 BSON 바이트 버퍼에서 정규 표현식을 역직렬화하는 from_bson
클래스 메서드를 구현합니다. 두 클래스의 메서드는 모두 위에서 설명한 대로 compile
메서드를 사용하여 Ruby 정규 표현식으로 변환해야 하는 BSON::Regexp::Raw
인스턴스를 반환합니다.
byte_buffer = BSON::ByteBuffer.new("^b403158\x00\x00") regex = Regexp.from_bson(byte_buffer) # => #<BSON::Regexp::Raw:0x000055df63100d40 @pattern="^b403158", @options=""> regex.pattern # => "^b403158" regex.options # => "" regex.compile # => /^b403158/
키 순서
BSON 문서는 문서가 키-값 쌍의 목록으로 저장되므로 키 순서를 유지합니다. Ruby의 해시는 키 순서도 보존합니다. 따라서 해시를 BSON 문서로 직렬화할 때 Ruby에 지정된 키 순서가 존중되고, BSON 문서를 해시로 역직렬화할 때 문서의 키 순서가 해시의 키 순서와 일치합니다.
중복 키
BSON 사양은 문서가 키-값 쌍의 목록으로 저장되기 때문에 BSON 문서에 중복 키를 가질 수 있도록 허용합니다. BSON 문서에 중복 키가 포함된 경우 MongoDB Server 동작이 정의되지 않으므로 애플리케이션은 이러한 문서를 생성하지 않아야 합니다.
Ruby에서 해시는 중복 키를 가질 수 없으므로, Ruby 해시를 BSON 문서로 직렬화할 때 중복 키가 생성되지 않습니다. (Ruby에서 중복 키가 있는 BSON 문서를 직접 만드는 것은 여전히 가능하며, 다른 MongoDB BSON 라이브러리 중 일부는 중복 키가 있는 BSON 문서 생성을 허용할 수 있습니다.)
BSON 문서의 키는 항상 문자열로 저장되므로 Ruby에서 문자열 및 기호와 동일한 키를 지정하면 가장 최근의 사양만 유지됩니다.
BSON::Document.new(test: 1, 'test' => 2) => {"test"=>2}
중복 키가 있는 BSON 문서를 로드할 때 중복 키의 마지막 값이 동일한 키의 이전 값을 덮어씁니다.