Docs Menu
Docs Home
/ / /
Ruby MongoDB ドライバー
/

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 と互換性があります。

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 のネイティブ バイト バッファを使用することが導入されています。

書込み (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_int32put_int64RangeErrorを発生させます。

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 クラスは、 ObjectArrayFalseClassFloatHashIntegerBigDecimalNilClassRegexpStringSymbol (非推奨)、 TimeTrueClass

コア 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 オブジェクトは、コンストラクターに渡された 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>

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ではない)。

サブタイプ 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"

JavaScript コードの string を表します。

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

注意

MongoDB 4.2.1 以降、 CodeWithScope型は非推奨です。 MongoDB 4.4 以降、 CodeWithScopeのサポートは、 $whereなどのさまざまなサーバーコマンドと演算子から削除されます。 4.4 以降を使用する場合は、他のBSON types と演算子を使用してください。MongoDB

stringJavaScript値のハッシュを持つ コードの を表します。

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

これは、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")

これは、すべてのキーを 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 の値を表します。

BSON::MaxKey.new

常に別の値と比較される BSON の値を表します。

BSON::MinKey.new

特定のマシン上のオブジェクトに対する 12 バイトの一意の識別子を表します。

BSON::ObjectId.new

開始値と増分値を持つ特別な時間を表します。

BSON::Timestamp.new(5, 30)

指定されなかった値のプレースホルダーを表します。

BSON::Undefined.new

正確な精度で小数の丸めをエミュレートできる 128 ビットの 10 進数ベースの浮動小数点値を表します。

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

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に設定します。

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"

一部の 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 に直列化される場合、時間はミリ秒単位で丸められます。

注意

常に切り捨てられた時間。 時間が 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 により、浮動小数点の計算が不正確になると予期しない結果が発生する可能性があるため、アプリケーションではすべての時間の計算を実行することが 強く推奨されます 。

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 正規表現の違いを詳細に説明し、両方を使用する方法について説明します。

MongoDB サーバーは 、PCRE ライブラリを使用して実装された Perl 互換正規表現を使用します および Ruby 正規表現 は、 Onigmo 正規表現エンジン を使用して実装されています は、 Atlas のノードであり、 。これらの 2 つの正規表現の実装は通常同等の機能を提供しますが、以下に説明するようにいくつかの重要な構文の違いがあります。

残念ながら、PCRE 正規表現をプログラムで同等の Ruby 正規表現に変換する簡単な方法はなく、PCRE の Ruby バインディングは現在存在しません。

Ruby と PCRE の正規表現はどちらも修飾子をサポートしています。 これらは、Ruby 用語では「オプション」と呼ばれ、PCRE 用語では「フラグ」と呼ばれます。 修飾子とs m修飾子の意味は、Ruby と PCRE で異なります。

  • Ruby にはs修飾子はありません。代わりに Ruby m修飾子が PCRE s修飾子と同じ機能を実行し、ピリオド( . )が改行を含む任意の文字と一致するようにします。 混乱が生じます。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 行の末尾を処理)

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 ドキュメントをロードすると、重複キーの最後の値が同じキーの前の値を上書きします。

戻る

よくあるエラー