Types

Table of Contents

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.

<?php

$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(981007385);
$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:

<?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);

?>

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:

<?php

$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.

The MongoId class

Introduction

A unique identifier created for database objects. If an object is inserted into the database without an _id field, an _id field will be added to it with a MongoId instance as its value. If the data has a naturally occuring unique field (say, a username or timestamp) it is fine to use this as the _id field instead, and it will not be replaced with a MongoId.

Instances of the MongoId class fulfill the role that autoincrementing does in a relational database: to provide a unique key if the data does not natually have one. Autoincrementing does not work well with a sharded database, as it is impossible to find what the next number should be quickly. This class fulfills the constraints of quickly generating a value that is unique across shards.

Each MongoId is 12 bytes (making its string form 24 hexidecimal characters). The first four bytes are a timestamp, the next three are a hash of the client machine's hostname, the next two are the two least significant bytes of the process id running the script, and the last three bytes are an incrementing value.

MongoIds are serializable/unserializable. Their serialized form is similar to their string form:

C:7:"MongoId":24:{4af9f23d8ead0e1d32000000}

Class synopsis

MongoId
class MongoId {
public string $id = NULL ;
/* Methods */
public __construct ([ string $id = NULL ] )
public static string getHostname ( void )
public int getInc ( void )
public int getPID ( void )
public int getTimestamp ( void )
public static bool isValid ( mixed $value )
public static MongoId __set_state ( array $props )
public string __toString ( void )
}

Fields

id
This field contains the string representation of this object.

See Also

MongoDB core docs on » ids.

The MongoCode class

Introduction

Represents JavaScript code for the database.

MongoCode objects are composed of two parts: a string of code and an optional scope. The string of code must be valid JavaScript. The scope is a associative array of variable name/value pairs.

Class synopsis

MongoCode
class MongoCode {
/* Methods */
public __construct ( string $code [, array $scope = array() ] )
public string __toString ( void )
}

The MongoDate class

Introduction

Represent date objects for the database. This class should be used to save dates to the database and to query for dates. For example:

Example #1 Storing dates with MongoDate

<?php

// save a date to the database
$collection->save(array("ts" => new MongoDate()));

$start = new MongoDate(strtotime("2010-01-15 00:00:00"));
$end = new MongoDate(strtotime("2010-01-30 00:00:00"));

// find dates between 1/15/2010 and 1/30/2010
$collection->find(array("ts" => array('$gt' => $start'$lte' => $end)));

?>

MongoDB stores dates as milliseconds past the epoch. This means that dates do not contain timezone information. Timezones must be stored in a separate field if needed. Second, this means that any precision beyond milliseconds will be lost when the document is sent to/from the database.

Class synopsis

MongoDate
class MongoDate {
/* Fields */
public int $sec ;
public int $usec ;
/* Methods */
public __construct ([ int $sec = time() [, int $usec = 0 ]] )
public string __toString ( void )
}

The MongoRegex class

Introduction

This class can be used to create regular expressions. Typically, these expressions will be used to query the database and find matching strings. More unusually, they can be saved to the database and retrieved.

Regular expressions consist of four parts. First a / as starting delimiter, then then pattern, another / and finally a string containing flags.

Example #1 Regular expression pattern

/pattern/flags

MongoDB recognizes six regular expression flags:

  • i: Case insensitive

  • m: Multiline

  • x: Can contain comments

  • l: locale

  • s: dotall, "." matches everything, including newlines

  • u: match unicode

Class synopsis

MongoRegex
class MongoRegex {
/* Fields */
public string $regex ;
public string $flags ;
/* Methods */
public __construct ( string $regex )
public string __toString ( void )
}

The MongoBinData class

Introduction

An object that can be used to store or retrieve binary data from the database.

The maximum size of a single object that can be inserted into the database is 16MB. For data that is larger than this (movies, music, Henry Kissinger's autobiography), use MongoGridFS. For data that is smaller than 16MB, you may find it easier to embed it within the document using MongoBinData.

For example, to embed an image in a document, one could write:

<?php

$profile 
= array(
    
"username" => "foobity",
    
"pic" => new MongoBinData(file_get_contents("gravatar.jpg"), MongoBinData::GENERIC),
);

$users->save($profile);

?>

This class contains a type field, which currently gives no additional functionality in the PHP driver or the database. There are seven predefined types, which are defined as class constants below. For backwards compatibility, the PHP driver uses MongoBinData::BYTE_ARRAY as the default; however, this may change to MongoBinData::GENERIC in the future. Users are encouraged to specify a type in MongoBinData::__construct.

Class synopsis

MongoBinData
class MongoBinData {
/* Constants */
const int MongoBinData::GENERIC = 0 ;
const int MongoBinData::FUNC = 1 ;
const int MongoBinData::BYTE_ARRAY = 2 ;
const int MongoBinData::UUID = 3 ;
const int MongoBinData::UUID_RFC4122 = 4 ;
const int MongoBinData::MD5 = 5 ;
const int MongoBinData::CUSTOM = 128 ;
/* Fields */
public string $bin ;
public int $type = 2 ;
/* Methods */
public __construct ( string $data [, int $type = 2 ] )
public string __toString ( void )
}

Predefined Constants

Binary Data Types

MongoBinData::GENERIC
0x00
Generic binary data.
MongoBinData::FUNC
0x01
Function.
MongoBinData::BYTE_ARRAY
0x02
Generic binary data (deprecated in favor of MongoBinData::GENERIC).
MongoBinData::UUID
0x03
Universally unique identifier (deprecated in favor of MongoBinData::UUID_RFC4122).
MongoBinData::UUID_RFC4122
0x04
Universally unique identifier (according to » RFC 4122).
MongoBinData::MD5
0x05
MD5.
MongoBinData::CUSTOM
0x80
User-defined type.

Changelog

Version Description
1.5.0 Added MongoBinData::GENERIC and MongoBinData::UUID_RFC4122 constants.

The MongoInt32 class

Introduction

The class can be used to save 32-bit integers to the database on a 64-bit system.

Class synopsis

MongoInt32
class MongoInt32 {
/* Fields */
public string $value ;
/* Methods */
public __construct ( string $value )
public string __toString ( void )
}

Fields

value
This is the string value of the 32-bit number. For instance, 123's value would be "123".

The MongoInt64 class

Introduction

The class can be used to save 64-bit integers to the database on a 32-bit system.

Class synopsis

MongoInt64
class MongoInt64 {
/* Fields */
public string $value ;
/* Methods */
public __construct ( string $value )
public string __toString ( void )
}

Fields

value
This is the string value of the 64-bit number. For instance, 123's value would be "123".

The MongoDBRef class

Introduction

This class can be used to create lightweight links between objects in different collections.

Motivation: Suppose we need to refer to a document in another collection. The easiest way is to create a field in the current document. For example, if we had a "people" collection and an "addresses" collection, we might want to create a link between each person document and an address document:

Example #1 Linking documents

<?php

$people 
$db->people;
$addresses $db->addresses;

$myAddress = array("line 1" => "123 Main Street"
    
"line 2" => null,
    
"city" => "Springfield",
    
"state" => "Vermont",
    
"country" => "USA");

// save the address
$addresses->insert($myAddress);

// save a person with a reference to the address
$me = array("name" => "Fred""address" => $myAddress['_id']);
$people->insert($me);

?>

Then, later on, we can find the person's address by querying the "addresses" collection with the MongoId we saved in the "people" collection.

Suppose now that we have a more general case, where we don't know which collection (or even which database) contains the referenced document. MongoDBRef is a good choice for this case, as it is a common format that all of the drivers and the database understand.

If each person had a list of things they liked which could come from multiple collections, such as "hobbies", "sports", "books", etc., we could use MongoDBRefs to keep track of what "like" went with what collection:

Example #2 Creating MongoDBRef links

<?php

$people 
$db->selectCollection("people");

// model trains are in the "hobbies" collection
$trainRef MongoDBRef::create("hobbies"$modelTrains['_id']);
// soccer is in the "sports" collection
$soccerRef MongoDBRef::create("sports"$soccer['_id']);

// now we'll know what collections the items in the "likes" array came from when
// we retrieve this document
$people->insert(array("name" => "Fred""likes" => array($trainRef$soccerRef)));

?>

Database references can be thought of as hyperlinks: they give the unique address of another document, but they do not load it or automatically follow the link/reference.

A database reference is just a normal associative array, not an instance of MongoDBRef, so this class is a little different than the other data type classes. This class contains exclusively static methods for manipulating database references.

Class synopsis

MongoDBRef
class MongoDBRef {
/* Methods */
public static array create ( string $collection , mixed $id [, string $database ] )
public static array get ( MongoDB $db , array $ref )
public static bool isRef ( mixed $ref )
}

See Also

MongoDB core docs on » databases references.

The MongoMinKey class

Introduction

MongoMinKey is a special type used by the database that evaluates to less than any other type. Thus, if a query is sorted by a given field in ascending order, any document with a MongoMinKey as its value will be returned first.

MongoMinKey has no associated fields, methods, or constants. It is merely the "smallest" thing that can be inserted into the database.

Class synopsis

MongoMinKey
class MongoMinKey {
}

Using MongoMinKey as a value

<?php

$collection
->insert(array("task" => "lunch""do by" => new MongoMinKey));
$collection->insert(array("task" => "staff meeting""do by" => new MongoDate(strtotime("+4 days"))));

$cursor $collection->find()->sort(array("do by" => 1));

?>

The cursor will contain the lunch document, then the staff meeting document. The lunch document will always be returned first, regardless of what else is added to the collection (unless other documents are added with MongoMinKey in the "do by" field).

The MongoMaxKey class

Introduction

MongoMaxKey is a special type used by the database that evaluates to greater than any other type. Thus, if a query is sorted by a given field in ascending order, any document with a MongoMaxKey as its value will be returned last.

MongoMaxKey has no associated fields, methods, or constants. It is merely the "largest" thing that can be inserted into the database.

Class synopsis

MongoMaxKey
class MongoMaxKey {
}

Using MongoMaxKey as a value

<?php

$collection
->insert(array("task" => "dishes""do by" => new MongoMaxKey));
$collection->insert(array("task" => "staff meeting""do by" => new MongoDate(strtotime("+4 days"))));

$cursor $collection->find()->sort(array("do by" => 1));

?>

The cursor will contain the staff meeting document, then the dishes document. The dishes document will always be returned last, regardless of what else is added to the collection (unless other documents are added with MongoMaxKey in the "do by" field).

The MongoTimestamp class

Introduction

MongoTimestamp is used by sharding. If you're not looking to write sharding tools, what you probably want is MongoDate.

MongoTimestamp is 4 bytes of timestamp (seconds since the epoch) and 4 bytes of increment.

This class is not for measuring time, creating a timestamp on a document or automatically adding or updating a timestamp on a document. Unless you are writing something that interacts with the sharding internals, stop, go directly to MongoDate, do not pass go, do not collect 200 dollars. This is not the class you are looking for.

If you are writing sharding tools, read on.

Class synopsis

MongoTimestamp
class MongoTimestamp {
/* Fields */
public int $sec = 0 ;
public int $inc = 0 ;
/* Methods */
public __construct ([ int $sec = time() [, int $inc ]] )
public string __toString ( void )
}