Docs Menu
Docs Home
/ / /
Ruby MongoDB Driver
/

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와 호환됩니다.

TimeWithZone과 같은 ActiveSupport에서 정의된 클래스에 대한 직렬화는 ActiveSupport에 대한 BSON의 엄격한 종속성을 피하기 위해 기본적으로 로드되지 않습니다. ActiveSupport를 사용하는 애플리케이션에서 BSON을 사용할 때는 ActiveSupport 관련 코드가 명시적으로 필요합니다.

require 'bson'
require 'bson/active_support'

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_byteput_bytes 메서드를 사용합니다. 바이트 문자열을 인수로 사용하여 이 문자열을 버퍼에 복사합니다. put_byte 는 인수가 길이가 1인 문자열을 강제합니다. put_bytes 은 모든 길이의 문자열을 허용합니다. 문자열에는 null 바이트가 포함될 수 있습니다.

buffer.put_byte("\x00")
buffer.put_bytes("\xff\xfe\x00\xfd")

참고

put_byteput_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_int32put_int64 메서드를 각각 사용합니다. Ruby 정수는 임의로 커질 수 있습니다. 기록 중인 값이 32비트 또는 64비트 정수 범위를 초과하면 put_int32put_int64RangeError 를 발생시킵니다.

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 객체를 사용하여 임의의 바이너리 데이터를 저장합니다. 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 입니다.

데이터와 하위 유형은 다음과 같이 datatype 속성을 사용하여 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>

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_uuidto_uuid 메서드를 모두 호출할 때 명시적으로 지정할 수 있습니다.

binary = BSON::Binary.from_uuid(uuid_str, :standard)
binary.to_uuid(:standard)

:standard 표현은 하위 유형 :uuid ( :uuid_old 제외)의 바이너리에서만 사용할 수 있습니다.

하위 유형 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"

JavaScript 코드의 문자열을 나타냅니다.

BSON::Code.new("this.value = 5;")

참고

CodeWithScope 유형은 MongoDB 4.2.1부터 더 이상 사용되지 않습니다. MongoDB 4.4부터 CodeWithScope 의 지원이 $where 과 같은 다양한 서버 명령 및 연산자에서 제거됩니다. MongoDB 4.4 이상으로 작업할 때는 다른 BSON types 및 연산자를 사용하세요.

값 해시가 있는 JavaScript 코드 문자열을 나타냅니다.

BSON::CodeWithScope.new("this.value = age;", age: 5)

이는 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_objHash.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")

이는 모든 키를 문자열로 저장하지만 기호 키를 사용하여 액세스를 허용하는 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의 값을 나타냅니다.

BSON::MaxKey.new

항상 다른 값과 비교하여 더 낮은 값으로 비교되는 BSON의 값을 나타냅니다.

BSON::MinKey.new

지정된 컴퓨터의 객체에 대한 12바이트 고유 식별자를 나타냅니다.

BSON::ObjectId.new

시작 및 증분 값이 있는 특수 시간을 나타냅니다.

BSON::Timestamp.new(5, 30)

제공되지 않은 값에 대한 자리 표시자를 나타냅니다.

BSON::Undefined.new

정확한 정밀도로 소수점 반올림을 에뮬레이션할 수 있는 128비트 소수점 기반 부동 소수점 값을 나타냅니다.

# Instantiate with a String
BSON::Decimal128.new("1.28")
# Instantiate with a BigDecimal
d = BigDecimal(1.28, 3)
BSON::Decimal128.new(d)

BigDecimal from_bsonto_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에서는 기본적으로 decimal128BigDecimal 로 역직렬화됩니다. decimal128 BSON 문서의 값을 로 역직렬화하려면 BSON::Decimal128mode: :bson 옵션을 설정할 수 from_bson 있습니다.

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"

일부 BSON types는 JSON으로 특수 표현됩니다. 이는 다음과 같으며 to_json 을 호출할 때 양식으로 자동으로 직렬화됩니다.

객체
JSON
BSON::Binary
{ "$binary" : "\x01", "$type" : "md5" }
BSON::Code
{ "$code" : "this.v = 5" }
BSON::CodeWithScope
{ "$code" : "this.v = value", "$scope" : { v => 5 }}
BSON::DBRef
{ "$ref" : "collection", "$id" : { "$oid" : "id" }, "$db" : "database" }
BSON::MaxKey
{ "$maxKey" : 1 }
BSON::MinKey
{ "$minKey" : 1 }
BSON::ObjectId
{ "$oid" : "4e4d66343b39b68407000001" }
BSON::Timestamp
{ "t" : 5, "i" : 30 }
Regexp
{ "$regex" : "[abc]", "$options" : "i" }

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 정규 표현식의 차이점과 두 가지를 모두 사용하는 방법을 설명합니다.

MongoDB 서버는 PCRE 라이브러리를 사용하여 구현된 펄(Perl) 호환 정규 표현식을 사용합니다. 및 Ruby 정규 표현식 Onigmo 정규 표현식 엔진 을 사용하여 구현됩니다. 은 Oniguruma 의 포크입니다. . 두 정규 표현식 구현은 일반적으로 동일한 기능을 제공하지만 아래에 설명된 대로 몇 가지 중요한 구문 차이점이 있습니다.

안타깝게도 프로그래밍 방식으로 PCRE 정규 표현식을 동등한 Ruby 정규 표현식으로 변환하는 간단한 방법이 없으며, 현재 PCRE에 대한 Ruby 바인딩도 없습니다.

Ruby와 PCRE 정규 표현식은 모두 수정자를 지원합니다. 이는 Ruby 용어로는 '옵션', PCRE 용어로는 '플래그'라고도 합니다. sm 수정자의 의미는 Ruby와 PCRE에서 다릅니다.

  • Ruby에는 s 수정자가 없지만 대신 Ruby m 수정자는 PCRE s 수정자와 동일한 기능을 수행하여 마침표(.)가 개행을 포함한 모든 문자와 일치하도록 합니다. 하지만, Ruby 문서에서는 m 수정자를 '다중 라인 모드 활성화'라고 명시하고 있습니다.

  • Ruby는 항상 PCRE 정규 표현식의 m 수정자로 활성화되는 PCRE의 다중 라인 모드와 동일한 방식으로 작동합니다. Ruby에서 ^ 앵커는 항상 줄의 시작을 나타내고 $ 앵커는 항상 줄의 끝을 나타냅니다.

Ruby와 PCRE 환경(MongoDB Server 및 대부분의 다른 MongoDB 드라이버 포함)에서 모두 사용되는 표현식(이하 '이식용 표현식')을 작성할 때는 ^$ 앵커 사용을 피해야 합니다. 다음 섹션에서는 이식 가능한 정규 표현식을 작성하기 위한 해결 방법과 권장 사항을 제공합니다.

Ruby 정규 표현식에서 ^ 앵커는 항상 줄의 시작을 참조합니다. PCRE 정규 표현식에서 ^ 앵커는 기본적으로 입력의 시작 부분을 참조하고, m 플래그는 의미를 줄의 시작으로 변경합니다.

Ruby와 PCRE 정규 표현식은 모두 수정자와 관계없이 입력의 시작을 참조하기 위해 \A 앵커를 지원합니다.

이식 가능한 정규 표현식을 작성할 때:

  • \A 앵커를 사용하여 입력의 시작 부분을 참조합니다.

  • ^ 앵커를 사용하여 줄의 시작을 참조합니다(이를 위해서는 PCRE 정규 표현식에서 m 플래그를 설정해야 함). 또는 수정자와 관계없이 작동하는 다음 구성 중 하나를 사용하세요: - (?:\A|(?<=\n)) (LF 및 CR+LF 줄 끝 처리) - (?:\A|(?<=[\r\n])) (CR, LF 및 CR+LF 줄 끝 처리)

Ruby 정규 표현식에서 $ 앵커는 항상 줄의 끝을 나타냅니다. PCRE 정규 표현식에서 $ 앵커는 기본적으로 입력의 끝을 참조하고, m 플래그는 의미를 줄의 끝으로 변경합니다.

Ruby와 PCRE 정규 표현식은 모두 수정자와 관계없이 입력의 끝을 참조하기 위해 \z 앵커를 지원합니다.

이식 가능한 정규 표현식을 작성할 때:

  • \z 앵커를 사용하여 입력의 끝을 참조합니다.

  • $ 앵커를 사용하여 줄의 시작을 참조합니다(이를 위해서는 PCRE 정규 표현식에서 m 플래그를 설정해야 함). 또는 수정자와 관계없이 작동하는 다음 구성 중 하나를 사용하세요: - (?:\z|(?=\n)) (LF 및 CR+LF 줄 끝 처리) - (?:\z|(?=[\n\n])) (CR, LF 및 CR+LF 줄 끝 처리)

프로그래밍 방식으로 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"

RegexpBSON::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 문서를 로드할 때 중복 키의 마지막 값이 동일한 키의 이전 값을 덮어씁니다.

돌아가기

일반적인 오류