Arrays
BSON arrays encode and decode via Perl array references.
Documents
Because Perl's hashes guarantee key-order randomness, using hash references as documents will lead to
BSON documents with a different key order. For top-level keys, this shouldn't cause problems, but it may
cause problems for embedded documents when querying, sorting or indexing on the embedded document.
For sending data to the server, the BSON::Doc class provides a very lightweight wrapper around ordered
key-value pairs, but it's opaque.
$doc = bson_doc( name => "Larry", color => "purple" );
You can also use Tie::IxHash for a more-interactive ordered document, but at the expense of tied-object
overhead.
The BSON encoder has an "ordered" attribute that, if enabled, returns all documents as order-preserving
tied hashes. This is slow, but is the only way to ensure that documents can roundtrip preserving key
order.
Numbers
By default, the BSON decoder decodes doubles and integers into a Perl-native form. To maximize fidelity
during a roundtrip, the decoder supports the wrap_numbers attribute to always decode to a BSON type
wrapper class with numeric overloading.
32-bitPlatforms
On a 32-bit platform, the BSON library treats Math::BigInt as the "native" type for integers outside the
(signed) 32-bit range. Values that are encoded as 64-bit integers will be decoded as Math::BigInt
objects.
64-bitPlatforms
On a 64-bit platform, (signed) Int64 values are supported, but, by default, numbers will be stored in the
smallest BSON size needed. To force a 64-bit representation for numbers in the signed 32-bit range, use
a type wrapper:
$int64 = bson_int64(0); # 64 bits of 0
Longdoubles
On a perl compiled with long-double support, floating point number precision will be lost when sending
data to MongoDB.
Decimal128
MongoDB 3.4 adds support for the IEEE 754 Decimal128 type. The BSON::Decimal128 class is used as a proxy
for these values for both inserting and querying documents. Be sure to use strings when constructing
Decimal128 objects.
$item = {
name => "widget",
price => bson_decimal128("4.99"), # 4.99 as a string
currency => "USD",
};
$coll->insert_one($item);
Strings
String values are expected to be character-data (not bytes). They are encoded as UTF-8 before being sent
to the database and decoded from UTF-8 when received. If a string can't be decoded, an error will be
thrown.
To save or query arbitrary, non-UTF8 bytes, use a binary type wrapper (see "Binary Data", below).
Booleans
Boolean values are emulated using the boolean package via the "boolean::true" and "boolean::false"
functions. Using boolean objects in documents will ensure the documents have the BSON boolean type in
the database. Likewise, BSON boolean types in the database will be returned as boolean objects.
An example of inserting boolean values:
use boolean;
$collection->insert_one({"okay" => true, "name" => "fred"});
An example of using boolean values for query operators (only returns documents where the name field
exists):
$cursor = $collection->find({"name" => {'$exists' => true}});
Often, you can just use 1 or 0 in query operations instead of "true" and "false", but some commands
require boolean objects and the database will return an error if integers 1 or 0 are used.
Boolean objects from the following JSON libraries will also be encoded correctly in the database:
• JSON::XS
• JSON::PP
• Cpanel::JSON::XS
• Mojo::JSON
• JSON::Tiny
ObjectIDs
The BSON object ID type (aka "OID") is a 12 byte identifier that ensures uniqueness by mixing a timestamp
and counter with host and process-specific bytes.
All MongoDB documents have an "_id" field as a unique identifier. This field does not have to be an
object ID, but if the field does not exist, an object ID is created automatically for it when the
document is inserted into the database.
The BSON::OID class is the type wrapper for object IDs.
To create a unique id:
$oid = bson_oid();
To create a BSON::OID from an existing 24-character hexadecimal string:
$oid = bson_oid("123456789012345678901234");
RegularExpressions
Use "qr/.../" to use a regular expression in a query, but be sure to limit your regular expression to
syntax and features supported by PCRE, which are not fully compatible with Perl
<https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions#Differences_from_Perl>.
$cursor = $collection->find({"name" => qr/[Jj]oh?n/});
Regular expressions will match strings saved in the database.
NOTE: only the following flags are supported: "imsxlu".
You can also save and retrieve regular expressions themselves, but regular expressions will be retrieved
as BSON::Regex objects for safety (these will round-trip correctly).
From that object, you can attempt to compile a reference to a "qr{}" using the "try_compile" method.
However, due to PCRE differences, this could fail to compile or could have different match behavior than
intended.
$collection->insert_one({"regex" => qr/foo/i});
$obj = $collection->find_one;
if ("FOO" =~ $obj->{regex}->try_compile) { # matches
print "hooray\n";
}
SECURITYNOTE: A regular expression can evaluate arbitrary code if "use re 'eval'" is in scope. You are
strongly advised never to use untrusted input as a regular expression.
Dates
BSON has a datetime type representing signed Int64 milliseconds relative to the Unix epoch. As of
MongoDB v2.0.0, the lightweight BSON::Time wrapper is now the default wrapper for datetime data.
The bson_time() helper function uses fractional epoch seconds, for better integration with the
Time::HiRes module:
use Time::HiRes 'time';
$later = bson_time( time() + 60 );
For convenience, The default value for the helper is "Time::HiRes::time":
$now = bson_time();
BSON::Time has methods for inflating into various popular Perl date classes, including DateTime,
Time::Moment and DateTime::Tiny. The BSON encoder can also encode objects of these types, with
limitations on precision and timezone based on the underlying class. For example, DateTime::Tiny has no
time zone or sub-second precision.
BinaryData
By default, all database strings are UTF-8. To store images, binaries, and other non-UTF-8 data, one can
use the BSON binary data type via the BSON::Bytes wrapper.
The BSON binary type includes the notion of a "subtype" attribute, which can be any integer between 0 and
255. The meaning of subtypes from 0 to 127 are reserved for definition by MongoDB; values 128 to 255 are
user-defined. Binary data values will only match in a MongoDB query if both the binary bytes and the
subtypes are the same. The default subtype is 0 (a.k.a. "generic binary data") and generally should not
be modified.
To roundtrip binary data, use the BSON::Bytes wrapper:
# non-utf8 string
$bytes = "\xFF\xFE\xFF";
$collection->insert_one({"photo" => bson_bytes($bytes)});
Binary data will be decoded into a BSON::Bytes object. It stringifies as the underlying bytes for
convenience.
One can also store binary data by using a string reference.
$collection->insert_one({"photo" => \$bytes});
MinKeyandMaxKey
BSON::MinKey is "less than" any other value of any type. This can be useful for always returning certain
documents first.
BSON::MaxKey is "greater than" any other value of any type. This can be useful for always returning
certain documents last.
There is a helper function for each:
$min = bson_minkey();
$max = bson_maxkey();