====
BSON
====

.. default-domain:: mongodb

.. include:: /includes/note-legacy.rst

bsonspec.org
------------

BSON is a binary-encoded serialization of JSON-like documents. BSON is
designed to be lightweight, traversable, and efficient. BSON, like JSON,
supports the embedding of objects and arrays within other objects and
arrays. See `bsonspec.org <http://bsonspec.org/>`_ for the spec and more
information in general.

BSON and MongoDB
----------------

MongoDB uses BSON as the data storage and network transfer format for
"documents".

BSON at first seems BLOB-like, but there exists an important difference:
the MongoDB database understands BSON internals. This means that MongoDB
can "reach inside" BSON objects, even nested ones, using :ref:`dot
notation <document-dot-notation>`. Among other things, this allows
MongoDB to build indexes and match objects against query expressions on
both top-level and nested BSON keys.

.. seealso:: the `BSON blog post <http://blog.mongodb.org/post/114440717/bson>`_
   and `BSON and Data Interchange <http://blog.mongodb.org/post/9333386434/bson-and-data-interchange>`_

Language-Specific Examples
--------------------------

We often map from a language's "dictionary" type, which may be its
native objects, to BSON. The mapping is particularly natural in
dynamically typed languages:

.. code-block:: sh

   JavaScript: {"foo" : "bar"}
   Perl: {"foo" => "bar"}
   PHP: array("foo" => "bar")
   Python: {"foo" : "bar"}
   Ruby: {"foo" => "bar"}
   Java: DBObject obj = new BasicDBObject("foo", "bar");

C
~

.. code-block:: c

   bson b;
   bson_buffer buf;
   bson_buffer_init( &buf )
   bson_append_string( &buf, "name", "Joe" );
   bson_append_int( &buf, "age", 33 );
   bson_from_buffer( &b, &buf );
   bson_print( &b );

See `http://github.com/mongodb/mongo-c-driver/blob/master/src/bson.h <http://github.com/mongodb/mongo-c-driver/blob/master/src/bson.h>`_
for more information.

C++
~~~

.. code-block:: cpp

   BSONObj p = BSON( "name" << "Joe" << "age" << 33 );
   cout << p.toString() << endl;
   cout << p["age"].number() << endl;

See the BSON section of the
`C++ Tutorial <http://www.mongodb.org/pages/viewpage.action?pageId=133415>`_
for more information.

Java
~~~~

.. code-block:: java

   BasicDBObject doc = new BasicDBObject();
   doc.put("name", "MongoDB");
   doc.put("type", "database");
   doc.put("count", 1);
   BasicDBObject info = new BasicDBObject();
   info.put("x", 203);
   info.put("y", 102);
   doc.put("info", info);
   coll.insert(doc);

PHP
~~~

The PHP driver includes ``bson_encode`` and ``bson_decode`` functions.
``bson_encode`` takes any PHP type and serializes it, returning a string of
bytes:

.. code-block:: php

   $bson = bson_encode(null);
   $bson = bson_encode(true);
   $bson = bson_encode(4);
   $bson = bson_encode("hello, world");
   $bson = bson_encode(array("foo" => "bar"));
   $bson = bson_encode(new MongoDate());

Mongo-specific objects (``MongoId``, ``MongoDate``, ``MongoRegex``,
``MongoCode``) will be encoded in their respective BSON formats. For
other objects, it will create a BSON representation with the key/value
pairs you would get by running for ``($object as $key => $value)``.

``bson_decode`` takes a string representing a BSON object and parses it into
an associative array.

Python
~~~~~~

.. code-block:: python

   >>> from bson import BSON
   >>> bson_string = BSON.encode({"hello": "world"})
   >>> bson_string
   '\x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00'
   >>> bson_string.decode()
   {u'hello': u'world'}

PyMongo also supports "ordered dictionaries" through the ``bson.son``
module. The ``BSON`` class can handle ``SON`` instances using the same methods
you would use for regular dictionaries. Python 2.7's
``collections.OrderedDict`` is also supported.

Ruby
~~~~

There are now two gems that handle BSON-encoding: ``bson`` and ``bson_ext``.
These gems can be used to work with BSON independently of the MongoDB
Ruby driver.

.. code-block:: ruby

   irb
   >> require 'rubygems'
   => true
   >> require 'bson'
   => true
   >> doc = {:hello => "world"}
   >> bson = BSON.serialize(doc).to_s
   => "\026\000\000\000\002hello\000\006\000\000\000world\000\000"
   >> BSON.deserialize(bson.unpack("C*"))
   => {"hello" => "world"}

The ``BSON`` class also supports ordered hashes. Simply construct your
documents using the ``OrderedHash`` class, also found in the MongoDB Ruby
Driver.

MongoDB Document Types
----------------------

MongoDB uses BSON documents for three things:

1. Data storage (user documents). These are the regular JSON-like
   objects that the database stores for us. These BSON documents are
   sent to the database via the INSERT operation. User documents have
   limitations on the "element name" space due to the usage of special
   characters in the JSON-like query language.

   - A user document element name cannot begin with ``$``.

   - A user document element name cannot have a ``.`` in the name.

   - The element name ``_id`` is reserved for use as a primary key id,
     but you can store anything that is unique in that field. The
     database expects that drivers will prevent users from creating
     documents that violate these constraints.

2. Query "Selector" Documents: Query documents (or selectors) are BSON
   documents that are used in QUERY, DELETE and UPDATE operations. They
   are used by these operations to match against documents. Selector
   objects have no limitations on the "element name" space, as they must
   be able to supply special "marker" elements, like ``$where`` and the
   special "command" operations.

3. "Modifier" Documents : Documents that contain 'modifier actions' that
   modify user documents in the case of an update.
