2010-02-01 15:24:10 +00:00
|
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
|
|
<!-- $Revision$ -->
|
|
|
|
|
|
|
|
<part xml:id="mongo.types" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
|
|
|
|
|
|
<title>Types</title>
|
|
|
|
|
|
|
|
<partintro>
|
|
|
|
|
|
|
|
<section>
|
|
|
|
<para>
|
|
|
|
MongoDB allows programmers to save and query for data expressed in all of the
|
|
|
|
basic PHP types, compound types (arrays, associative arrays, and objects), and
|
|
|
|
a half-dozen classes provided by the MongoDB PHP driver (for regular
|
|
|
|
expressions, dates, and other specialized applications).
|
|
|
|
</para>
|
|
|
|
</section>
|
|
|
|
|
|
|
|
<section>
|
|
|
|
<title>Simple Types</title>
|
|
|
|
<para>
|
|
|
|
The built-in types are:
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
<informaltable>
|
|
|
|
<tgroup cols="3">
|
|
|
|
<thead>
|
|
|
|
<row>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry>Size in MongoDB (bytes)</entry>
|
|
|
|
</row>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<row>
|
|
|
|
<entry>&null;</entry>
|
|
|
|
<entry>Fairly self-explanatory.</entry>
|
|
|
|
<entry>0</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry>boolean</entry>
|
|
|
|
<entry>&true; and &false;</entry>
|
|
|
|
<entry>1</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry>int</entry>
|
|
|
|
<entry>Integer values.</entry>
|
|
|
|
<entry>4</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry>float</entry>
|
|
|
|
<entry>Double values.</entry>
|
|
|
|
<entry>8</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry>string</entry>
|
|
|
|
<entry>Strings of UTF-8 characters.</entry>
|
|
|
|
<entry>string length + 1</entry>
|
|
|
|
</row>
|
|
|
|
</tbody>
|
|
|
|
</tgroup>
|
|
|
|
</informaltable>
|
|
|
|
</para>
|
|
|
|
</section>
|
|
|
|
|
|
|
|
<section>
|
|
|
|
<title>Arrays and Objects</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Arrays and objects can also be saved to the database. An array with ascending
|
|
|
|
numeric keys will be saved as a an array, anything else will be saved as an
|
|
|
|
object.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<programlisting role="php">
|
|
|
|
<![CDATA[
|
|
|
|
<?php
|
|
|
|
|
2010-03-08 15:42:26 +00:00
|
|
|
// $scores will be saved as an array
|
|
|
|
$scores = array(98, 100, 73, 85);
|
2010-07-09 11:28:40 +00:00
|
|
|
$collection->insert(array("scores" => $scores));
|
2010-02-01 15:24:10 +00:00
|
|
|
|
|
|
|
// $scores will be saved as an object
|
|
|
|
$scores = array("quiz1" => 98, "midterm" => 100, "quiz2" => 73, "final" => 85);
|
2010-07-09 11:28:40 +00:00
|
|
|
$collection->insert(array("scores" => $scores));
|
2010-02-01 15:24:10 +00:00
|
|
|
|
|
|
|
?>
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
If you query for these objects using the database shell, they will look like:
|
|
|
|
<programlisting>
|
|
|
|
<![CDATA[
|
|
|
|
> db.students.find()
|
|
|
|
{ "_id" : ObjectId("4b06beada9ad6390dab17c43"), "scores" : [ 98, 100, 73, 85 ] }
|
|
|
|
{ "_id" : ObjectId("4b06bebea9ad6390dab17c44"), "scores" : { "quiz1" : 98, "midterm" : 100, "quiz2" : 73, "final" : 85 } }
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The database can also save arbitrary PHP objects (although they will be
|
|
|
|
returned as associative arrays). The fields are used for the key/value
|
|
|
|
pairs. For example, a blog post might look like:
|
|
|
|
<programlisting role="php">
|
|
|
|
<![CDATA[
|
|
|
|
<?php
|
|
|
|
|
|
|
|
// the blog post class
|
|
|
|
class Post {
|
|
|
|
|
|
|
|
var $author;
|
|
|
|
var $content;
|
|
|
|
var $comments = array();
|
|
|
|
var $date;
|
|
|
|
|
|
|
|
public function __construct($author, $content) {
|
|
|
|
$this->author = $author;
|
|
|
|
$this->content = $content;
|
|
|
|
$this->date = new MongoDate();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setTitle($title) {
|
|
|
|
$this->title = $title;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// create a simple blog post and insert it into the database
|
|
|
|
$post1 = new Post("Adam", "This is a blog post");
|
|
|
|
|
|
|
|
$blog->insert($post1);
|
|
|
|
|
|
|
|
|
|
|
|
// there is nothing restricting the type of the "author" field, so we can make
|
|
|
|
// it a nested object
|
|
|
|
$author = array("name" => "Fred", "karma" => 42);
|
|
|
|
$post2 = new Post($author, "This is another blog post.");
|
|
|
|
|
|
|
|
// we create an extra field by setting the title
|
|
|
|
$post2->setTitle("Second Post");
|
|
|
|
|
|
|
|
$blog->insert($post2);
|
|
|
|
|
|
|
|
?>
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
From the database shell, this will look something like:
|
|
|
|
<programlisting>
|
2010-03-08 15:42:26 +00:00
|
|
|
<![CDATA[
|
2010-02-01 15:24:10 +00:00
|
|
|
> db.blog.find()
|
|
|
|
{ "_id" : ObjectId("4b06c263edb87a281e09dad8"), "author" : "Adam", "content" : "This is a blog post", "comments" : [ ], "date" : "Fri Nov 20 2009 11:22:59 GMT-0500 (EST)" }
|
|
|
|
{ "_id" : ObjectId("4b06c282edb87a281e09dad9"), "author" : { "name" : "Fred", "karma" : 42 }, "content" : "This is a blog post", "comments" : [ ], "date" : "Fri Nov 20 2009 11:23:30 GMT-0500 (EST)", "title" : "Second Post" }
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
2010-03-08 15:42:26 +00:00
|
|
|
|
|
|
|
<para>
|
|
|
|
The driver will not detect reference loops in arrays and objects. For
|
|
|
|
example, this will give a fatal error:
|
|
|
|
<programlisting role="php">
|
|
|
|
<![CDATA[
|
|
|
|
<?php
|
|
|
|
|
|
|
|
$collection->insert($GLOBALS);
|
|
|
|
|
|
|
|
?>
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
<programlisting>
|
|
|
|
<![CDATA[
|
|
|
|
|
|
|
|
Fatal error: Nesting level too deep - recursive dependency?
|
|
|
|
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
If you need to insert documents that may have recursive dependency, you have
|
|
|
|
to check for it yourself before passing it to the driver.
|
|
|
|
</para>
|
2010-02-01 15:24:10 +00:00
|
|
|
</section>
|
|
|
|
|
|
|
|
<section>
|
|
|
|
<title>MongoDB Types</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The Mongo PHP driver also defines a few new types to use with the database.
|
|
|
|
See class documentation for details and examples.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
<informaltable>
|
|
|
|
<tgroup cols="3">
|
|
|
|
<thead>
|
|
|
|
<row>
|
|
|
|
<entry>Type</entry>
|
|
|
|
<entry>Description</entry>
|
|
|
|
<entry>Size in MongoDB (bytes)</entry>
|
|
|
|
</row>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
|
|
|
<row>
|
|
|
|
<entry><classname>MongoBinData</classname></entry>
|
|
|
|
<entry>Binary data.</entry>
|
|
|
|
<entry>Number of bytes in binary data + 5</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><classname>MongoCode</classname></entry>
|
|
|
|
<entry>JavaScript code.</entry>
|
|
|
|
<entry>String length of code + object size of scope.</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><classname>MongoDate</classname></entry>
|
|
|
|
<entry>Dates and times. Stored as milliseconds since the epoch.</entry>
|
|
|
|
<entry>8</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><classname>MongoId</classname></entry>
|
|
|
|
<entry>Unique document id:
|
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>4 bytes of timestamp</para>
|
|
|
|
<para>
|
|
|
|
No two records can have the same id if they were inserted at different
|
|
|
|
times.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>3 bytes machine id</para>
|
|
|
|
<para>
|
|
|
|
No two records can have the same id if they were inserted on different
|
|
|
|
machines
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>2 bytes thread id</para>
|
|
|
|
<para>
|
|
|
|
No two records can have the same id if they were inserted by different
|
|
|
|
threads running on the same machine.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
<listitem>
|
|
|
|
<para>3 bytes incrementing value</para>
|
|
|
|
<para>
|
|
|
|
Each time an id is created, a global counter is incremented and used
|
|
|
|
as the increment value of the next id.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
|
|
Thus, no two records can have the same id unless a single process on a
|
|
|
|
single machine managed to insert 256^3 (over 16 million) documents in
|
|
|
|
one second, overflowing the increment field.
|
|
|
|
</entry>
|
|
|
|
<entry>12</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><classname>MongoMinKey</classname></entry>
|
|
|
|
<entry>Always smaller than any other value.</entry>
|
|
|
|
<entry>String length of code + object size of scope.</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><classname>MongoMaxKey</classname></entry>
|
|
|
|
<entry>JavaScript code.</entry>
|
|
|
|
<entry>Always larger than any other value.</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><classname>MongoRegex</classname></entry>
|
|
|
|
<entry>Regular expressions.</entry>
|
|
|
|
<entry>
|
|
|
|
Number of characters in regular expression + number of flags
|
|
|
|
</entry>
|
|
|
|
</row>
|
|
|
|
<row>
|
|
|
|
<entry><classname>MongoTimestamp</classname></entry>
|
2010-09-02 18:41:54 +00:00
|
|
|
<entry>Replication timestamp</entry>
|
2010-02-01 15:24:10 +00:00
|
|
|
<entry>8</entry>
|
|
|
|
</row>
|
|
|
|
</tbody>
|
|
|
|
</tgroup>
|
|
|
|
</informaltable>
|
|
|
|
</para>
|
|
|
|
</section>
|
2010-03-08 15:42:26 +00:00
|
|
|
|
|
|
|
<section>
|
|
|
|
<title>BSON</title>
|
|
|
|
<para>
|
|
|
|
MongoDB uses a storage format called "BSON," Binary Serializable Object
|
|
|
|
Notation, which is similar to JSON but more compact and rich in types. Listed
|
|
|
|
below is the exact byte size of each type (or information required to compute
|
|
|
|
its size, in the case of variable-length types). Keep in mind that these
|
|
|
|
sizes do not include field names. The size of an object can be manually
|
|
|
|
computed, but it may be easier for programmers to call the
|
|
|
|
<function>bson_encode</function> function and take the length of the resulting
|
|
|
|
string.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
An example of manually computing BSON size for saving the object
|
|
|
|
array("x" => null, "y" => 40):
|
|
|
|
<programlisting>
|
|
|
|
<![CDATA[
|
|
|
|
4 bytes (object size)
|
|
|
|
|
|
|
|
1 byte (type of "x" field)
|
|
|
|
2 bytes ("x" and "\0")
|
|
|
|
0 bytes (for null)
|
|
|
|
|
|
|
|
1 byte (type of "y" field)
|
|
|
|
2 bytes ("y" and "\0")
|
|
|
|
4 bytes (for an integer)
|
|
|
|
|
|
|
|
1 byte (end-of-object byte)
|
|
|
|
-----------------------
|
|
|
|
15 bytes
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
</para>
|
|
|
|
</section>
|
|
|
|
|
2010-02-01 15:24:10 +00:00
|
|
|
</partintro>
|
|
|
|
|
|
|
|
&reference.mongo.mongoid;
|
|
|
|
&reference.mongo.mongocode;
|
|
|
|
&reference.mongo.mongodate;
|
|
|
|
&reference.mongo.mongoregex;
|
|
|
|
&reference.mongo.mongobindata;
|
2010-09-07 15:34:49 +00:00
|
|
|
&reference.mongo.mongoint32;
|
|
|
|
&reference.mongo.mongoint64;
|
2010-02-01 15:24:10 +00:00
|
|
|
&reference.mongo.mongodbref;
|
|
|
|
&reference.mongo.mongominkey;
|
|
|
|
&reference.mongo.mongomaxkey;
|
|
|
|
&reference.mongo.mongotimestamp;
|
|
|
|
|
|
|
|
</part>
|