|
TypesTable 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(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:
<?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
;
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
{
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
{
public
int
$sec
;
public
int
$usec
;
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
MongoDB recognizes six regular expression flags:
Class synopsis
MongoRegex
class MongoRegex
{
public
string
$regex
;
public
string
$flags
;
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
{
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
;
public
string
$bin
;
public
int
$type
= 2
;
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.
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
{
public
string
$value
;
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
{
public
string
$value
;
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
{
public static array create
( string $collection
, mixed $id
[, string $database
] )
public static array get
( MongoDB $db
, array $ref
)
public static bool isRef
( mixed $ref
)
}
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
{
public
int
$sec
= 0
;
public
int
$inc
= 0
;
public __construct
([ int $sec = time()
[, int $inc
]] )
public string __toString
( void
)
}
|