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 直列化
- 時間インスタンス
- DateTime インスタンス
- 日付インスタンス
- 正規表現
- Ruby と MongoDB の正規表現
BSON::Regexp::Raw
クラス- 正規表現の変換
- 読み取りと書込み
- キーの順序
- 重複キー
このチュートリアルでは、Ruby BSON ライブラリの使用について説明します。
インストール
BSON ライブラリは Rubygems からインストールできます 手動または バンドラーを使用して。
gem を手動でインストールするには次の手順に従います。
gem install bson
バンドラーで gem をインストールするには、 Gemfile
に次の内容を含めます。
gem 'bson'
BSON ライブラリは、MRI >= 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 のネイティブ バイト バッファを使用することが導入されています。
書込み
書込み (write) 用のByteBuffer
を作成するには(つまり BSON に直列化するなど)、引数なしでBSON::ByteBuffer
をインスタンス化します。
buffer = BSON::ByteBuffer.new
変換されない未加工バイトをバイトバッファに書込むには、 メソッドとput_byte
put_bytes
メソッドを使用します。バイト string を引数として受け取り、この string をバッファにコピーします。 put_byte
では、引数が長さ 1 のstringであることが強制されます。 put_bytes
は任意の長さの文字列を受け入れます。 string には null バイトを含めることができます。
buffer.put_byte("\x00") buffer.put_bytes("\xff\xfe\x00\xfd")
注意
put_byte
およびput_bytes
は、バイト バッファに引数を書込む前に、BSON 型のバイトを書込みません。
後続の書込みメソッドは、 BSON 仕様 の特定のタイプのオブジェクトを書込みます 。メソッド名で示される型は引数の型よりも優先されることに注意してください。たとえば、浮動小数点値がput_int32
に与えられている場合、その値は強制的に整数に変換され、結果の整数はバイト バッファに書き込まれます。 。
UTF-8 string(BSON 型 0x02)をバイト バッファに書込むには、 put_string
を使用します。
buffer.put_string("hello, world")
BSON string は常に UTF-8 でエンコードされることに注意してください。 したがって、引数は UTF-8 または UTF-8 に変換可能なエンコーディング のいずれかである必要があります( バイナリではありません)。 引数が UTF-8 以外のエンコードにある場合、string はまず UTF-8 に変換され、UTF-8 でエンコードされたバージョンがバッファに書き込まれます。 string は、エンコーディングが UTF-8 の場合は有効な UTF-8 であるなど、要求されるエンコーディングが有効である必要があります。 string には null バイトが含まれる場合があります。
BSON 仕様 では、ドキュメント キーの例として使用される CString 型 も定義されています。 CString をバッファに書き込むには、 put_cstring
を使用します。
buffer.put_cstring("hello, world")
通常の文字列と同様に、BSON の CString は UTF-8 でエンコードされる必要があります。 引数が UTF-8 にない場合は、UTF-8 に変換され、結果のstringがバッファに書き込まれます。 put_string
とは異なり、 put_cstring
に付与される引数の UTF-8 エンコーディングには、null バイトを含めることはできません。BSON の CString 直列化形式は 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)
シリアル化されたデータをバイトstringとして取得するには(ソケット経由でデータを送信する場合など)、バッファで to_s
を呼び出します。
buffer = BSON::ByteBuffer.new buffer.put_string('testing') socket.write(buffer.to_s)
注意
ByteBuffer
は、読み取り位置と書込み位置を個別に追跡します。 書き込み用のバッファを巻き戻す方法はありませんrewind
は読み取り位置のみに影響します。
読み取り
読み取り用のByteBuffer
を作成するには(つまり BSONからの逆直列化)、バイトstringを引数として 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
メソッドが定義される Core 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
オブジェクトは、コンストラクターに渡された string が次のエンコーディングであったが、常に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 準拠の string から 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 オブジェクトに保存されているデータは、データを作成したドライバーに応じて 3 つの異なるバイト順のいずれかで保存される場合があります。 バイト順は、 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 は、表現を指定せずに string 化できないことに注意してください。
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 のstring表現からレガシー 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 コードの string を表します。
BSON::Code.new("this.value = 5;")
BSON::CodeWithScope
注意
MongoDB 4.2.1 以降、 CodeWithScope
型は非推奨です。 MongoDB 4.4 以降、 CodeWithScope
のサポートは、 $where
などのさまざまなサーバーコマンドと演算子から削除されます。 4.4 以降を使用する場合は、他のBSON types と演算子を使用してください。MongoDB
stringJavaScript値のハッシュを持つ コードの を表します。
BSON::CodeWithScope.new("this.value = age;", age: 5)
BSON::DBRef
これは、DBRef のコレクション、ID、データベースへのアクセスを提供するBSON::Document
のサブクラスです。
BSON::DBRef.new({"$ref" => "collection", "$id" => "id"}) BSON::DBRef.new({"$ref" => "collection", "$id" => "id", "database" => "db"})
注意
BSON::DBRef コンストラクターは指定されたハッシュを検証し、有効な DBRef でない場合は ArgmentError を発生させます。 BSON::ExtJSON.parse_obj
およびHash.from_bson
は無効な DBRef を指定してもエラーを生成せず、代わりに BSON::Document をハッシュまたは逆シリアル化します。
注意
すべての BSON ドキュメントは、有効な DBRef である場合は BSON::DBRef のインスタンスに逆シリアル化されます。そうでない場合は、BSON::Document のインスタンスに逆シリアル化されます。 これは、呼び出しが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
これは、すべてのキーを string として保存しますが、シンボルキーによるアクセスは許可するHash
のサブクラスです。
BSON::Document[:key, "value"] BSON::Document.new
注意
すべての BSON ドキュメントは、呼び出しがHash
クラスから行われる場合でも、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 ビットの 10 進数ベースの浮動小数点値を表します。
# Instantiate with a String BSON::Decimal128.new("1.28") # Instantiate with a BigDecimal d = BigDecimal(1.28, 3) BSON::Decimal128.new(d)
BSON::Decimal128 と GeoDecimal128
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 からの逆直列化時に後続のゼロを保持します。 ただし、BigDecimal
では後続のゼロが維持されないため、BigDecimal
を使用すると精度が低下する可能性があります。
注意
In BSON 5.0, decimal128
is deserialized into BigDecimal
by default. BSON ドキュメントのdecimal128
値を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 シンボル型を非推奨にし、代わりに string を使用することを推奨しています。
注意
BSON では、ハッシュキーは常に string です。 非文字列値は、ハッシュ キーとして使用する場合、string 化されます。
Hash.from_bson({foo: 'bar'}.to_bson) # => {"foo"=>"bar"} Hash.from_bson({1 => 2}.to_bson) # => {"1"=>2}
デフォルトでは、BSON ライブラリはSymbol
ハッシュ値を string としてエンコードし、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 に直列化される場合、時間はミリ秒単位で丸められます。
注意
常に切り捨てられた時間。 時間が UNIXエポック (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 で直列化するときに時間を正しく使用します。
この API により、浮動小数点の計算が不正確になると予期しない結果が発生する可能性があるため、アプリケーションではすべての時間の計算を実行することが 強く推奨されます 。
DateTime インスタンス
BSON では、UNIX エポックからの秒数として時間の保存のみがサポートされています。 Ruby のDateTime
インスタンスは BSON にシリアル化できますが、BSON が逆シリアル化されると、回数はTime
インスタンスとして返されます。
DateTime
Ruby の クラスは非グレゴリオ暦をサポートします。 非グレゴリオのDateTime
インスタンスが直列化されると、まずグレゴリオ暦に変換され、グレゴリオ暦のそれぞれの日付が データベースに保存されます。
日付インスタンス
BSON では、UNIX エポックからの秒数として時間の保存のみがサポートされています。 Ruby のDate
インスタンスは BSON にシリアル化できますが、BSON が逆シリアル化されると、回数はTime
インスタンスとして返されます。
Date
インスタンスがシリアル化されている場合、使用される時間値はDate
が UTC で参照する日の午前 0 時です。
正規表現
MongoDB と Ruby はどちらも正規表現を操作するための機能を提供していますが、正規表現エンジンを使用します。 次のサブセクションでは、Ruby 正規表現と MongoDB 正規表現の違いを詳細に説明し、両方を使用する方法について説明します。
Ruby と MongoDB の正規表現
MongoDB サーバーは 、PCRE ライブラリを使用して実装された Perl 互換正規表現を使用します および Ruby 正規表現 は、 Onigmo 正規表現エンジン を使用して実装されています は、 Atlas のノードであり、 。これらの 2 つの正規表現の実装は通常同等の機能を提供しますが、以下に説明するようにいくつかの重要な構文の違いがあります。
残念ながら、PCRE 正規表現をプログラムで同等の Ruby 正規表現に変換する簡単な方法はなく、PCRE の Ruby バインディングは現在存在しません。
Options / Flags / Modifiers
Ruby と PCRE の正規表現はどちらも修飾子をサポートしています。 これらは、Ruby 用語では「オプション」と呼ばれ、PCRE 用語では「フラグ」と呼ばれます。 修飾子とs
m
修飾子の意味は、Ruby と PCRE で異なります。
Ruby には
s
修飾子はありません。代わりに Rubym
修飾子が PCREs
修飾子と同じ機能を実行し、ピリオド(.
)が改行を含む任意の文字と一致するようにします。 混乱が生じます。Ruby のドキュメントでは、m
修飾子を「複数行モードの有効化」として参照しています。Ruby は常に、PCRE 正規表現の
m
修飾子によって有効になる、PCRE のマルチライン モードと同等の動作をします。 Ruby では、^
アンカーは常に行先頭を参照し、$
アンカーは常に行末を参照します。
Ruby と PCRE の両方の環境(MongoDB サーバーや他のほとんどの 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 行の末尾を処理)
BSON::Regexp::Raw
クラス
PCRE 正規表現をプログラムで同等の Ruby 正規表現に変換する簡単な方法がないため、bson- Ruby は MongoDB / PCRE 正規表現を保持するためのBSON::Regexp::Raw
クラスを提供します。 このドキュメントでは、このクラスのインスタンスは「BSON 正規表現」と呼ばれています。
このクラスのインスタンスは、正規表現テキストを string と任意の 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 修飾子に変換され、最後の 2 つの例では、元の BSON 正規表現の意味が異なる場合でも、同じ正規表現に変換されていることに注意してください。
BSON 正規表現で移植性のない^
と$
アンカーが使用される場合、Ruby 正規表現への変換でその意味が変わる可能性があります。
BSON::Regexp::Raw.new("^hello.world", "").compile =~ "42\nhello world" # => 3
Ruby 正規表現が BSON 正規表現に変換される場合(たとえば、クエリの一部としてサーバーに送信する場合など)、BSON 正規表現には常に^
と$
の動作を反映するm
修飾子が設定されます。 Ruby 正規表現のアンカー。
読み取りと書込み
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
クラス メソッドを実装しています。 両方のクラスのメソッドはBSON::Regexp::Raw
インスタンスを返します。これは、上記で説明したようにcompile
メソッドを使用して Ruby 正規表現に変換する必要があります。
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 サーバーの動作は未定義であるため、アプリケーションはこのようなドキュメントの生成を行わない必要があります。
Ruby ではハッシュに重複キーを含めることができないため、Ruby ハッシュを BSON ドキュメントに直列化する場合、重複キーは生成されません。 (Ruby では重複キーを持つ BSON ドキュメントを手動で作成することも可能です。また、他の MongoDB BSON ライブラリの一部では、重複キーを持つ BSON ドキュメントの作成が許可されている場合があります)。
BSON ドキュメント内のキーは常に string として保存されるため、string とシンボルと同じキーを Ruby で指定しても最新の仕様のみが保持されます。
BSON::Document.new(test: 1, 'test' => 2) => {"test"=>2}
重複キーを含む BSON ドキュメントをロードすると、重複キーの最後の値が同じキーの前の値を上書きします。