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).
Booleans and NULL
TRUE, FALSE, and NULL can be used as-is.
Numbers
Numbers are distinct from strings in MongoDB: "123" does not match 123.
Thus, if you want to make sure numbers are sorted and matched correctly, you
must make sure that they are actually saved as numbers.
$doc = array( "a" => 123 , "b" => "123" ); $collection -> insert ( $doc ); $doc -> find (array( "a" => 123 )); // matches $doc -> find (array( "a" => "123" )); // doesn't match $doc -> find (array( "a" => 123.0 )); // matches $doc -> find (array( "b" => 123 )); // doesn't match $doc -> find (array( "b" => "123" )); // matches ?>
As noted above, floating point numbers do compare with/match integer numbers
as one would expect.
Large Numbers
By default, on a 32-bit system, numbers are sent to the database as 32-bit
integers. On a 64-bit system, they are sent as 64-bit integers. For
backwards compatibility, all systems deserialize 64-bit integers as floating
point numbers. Floating point numbers are not exact. If you need exact
values, you must tweak your
» php.ini settings.
On a 32-bit system, if mongo.long_as_object is set,
64-bit integers will be returns as MongoInt64
objects. The integer will be stored in the value field
with perfect precision (as a string). You can also use
MongoInt64 to save 64-bit integers on 32-bit
machines.
On 64-bit systems, you can either set mongo.long_as_object
or set mongo.native_long.
mongo.native_long will return 64-bit integers and
"normal" PHP integers. You can use MongoInt32 to
save 32-bit integers on 64-bit machines.
You should set the mongo.long_as_object and
mongo.native_long behavior that you plan to use, even if
it is the default behavior (to protect against future changes to the
defaults).
See also: » php.ini Options,
MongoInt32, MongoInt64.
Strings
Strings must be UTF-8. Non-UTF-8 strings must either be converted to UTF-8
before being sent to the database or saved as binary data.
Regular expressions can be used to match strings, and are expressed using the
MongoRegex class.
Binary Data
Non-UTF-8 strings, images, and any other binary data should be sent to the
database using the MongoBinData type.
Dates
Dates can be created using the MongoDate class. They
are stored as milliseconds since the epoch.
MongoTimestamp is not for saving dates or timestamps,
it is used internally by MongoDB. Unless you are creating a tool that
interacts with the internals of replication or sharding, you should use
MongoDate, not MongoTimestamp.
Unique Ids
The driver will automatically create an _id field before
inserting a document (unless one is specified by the user). This field is an
instance of MongoId (called "ObjectId" in most other
languages).
These ids are 12 bytes long and composed of:
4 bytes of timestamp
No two records can have the same id if they were inserted at different
times.
3 bytes machine id
No two records can have the same id if they were inserted on different
machines
2 bytes thread id
No two records can have the same id if they were inserted by different
threads running on the same machine.
3 bytes incrementing value
Each time an id is created, a global counter is incremented and used
as the increment value of the next id.
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.
JavaScript
MongoDB comes with a JavaScript engine, so you can embed JavaScript in
queries (using a $where clause), send it directly to the database to be
executed, and use it to perform aggregations.
For security, use MongoCode's scope
field to use PHP variables in JavaScript. Code that does not require
external values can either use MongoCode or just be
a string. See the
» section on security for more
information about sending JavaScript to the database.
Arrays and Objects
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.
<?php // $scores will be saved as an array $scores = array( 98 , 100 , 73 , 85 ); $collection -> insert (array( "scores" => $scores )); // $scores will be saved as an object $scores = array( "quiz1" => 98 , "midterm" => 100 , "quiz2" => 73 , "final" => 85 ); $collection -> insert (array( "scores" => $scores )); ?>
If you query for these objects using the database shell, they will look like:
> db.students.find()
{ "_id" : ObjectId("4b06beada9ad6390dab17c43"), "scores" : [ 98, 100, 73, 85 ] }
{ "_id" : ObjectId("4b06bebea9ad6390dab17c44"), "scores" : { "quiz1" : 98, "midterm" : 100, "quiz2" : 73, "final" : 85 } }
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:
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 ); ?>
From the database shell, this will look something like:
> 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" }
The driver will not detect reference loops in arrays and objects. For
example, this will give a fatal error:
$collection -> insert ( $GLOBALS ); ?>
Fatal error: Nesting level too deep - recursive dependency? If you need to insert documents that may have recursive dependency, you have
to check for it yourself before passing it to the driver.