mirror of
https://github.com/sigmasternchen/php-doc-en
synced 2025-03-16 00:48:54 +00:00

git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@338676 c90b9560-bf6c-de11-be94-00142212c4b1
317 lines
9.8 KiB
XML
317 lines
9.8 KiB
XML
<?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>Booleans and &null;</title>
|
|
<para>
|
|
&true;, &false;, and &null; can be used as-is.
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Numbers</title>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?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
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
<para>
|
|
As noted above, floating point numbers do compare with/match integer numbers
|
|
as one would expect.
|
|
</para>
|
|
<section>
|
|
<title>Large Numbers</title>
|
|
<para>
|
|
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
|
|
<link linkend="mongo.configuration">php.ini settings</link>.
|
|
</para>
|
|
<para>
|
|
On a 32-bit system, if <literal>mongo.long_as_object</literal> is set,
|
|
64-bit integers will be returns as <classname>MongoInt64</classname>
|
|
objects. The integer will be stored in the <literal>value</literal> field
|
|
with perfect precision (as a string). You can also use
|
|
<classname>MongoInt64</classname> to save 64-bit integers on 32-bit
|
|
machines.
|
|
</para>
|
|
<para>
|
|
On 64-bit systems, you can either set <literal>mongo.long_as_object</literal>
|
|
or set <literal>mongo.native_long</literal>.
|
|
<literal>mongo.native_long</literal> will return 64-bit integers and
|
|
"normal" PHP integers. You can use <classname>MongoInt32</classname> to
|
|
save 32-bit integers on 64-bit machines.
|
|
</para>
|
|
<para>
|
|
You should set the <literal>mongo.long_as_object</literal> and
|
|
<literal>mongo.native_long</literal> behavior that you plan to use, even if
|
|
it is the default behavior (to protect against future changes to the
|
|
defaults).
|
|
</para>
|
|
<para>
|
|
See also: <link linkend="mongo.configuration">php.ini Options</link>,
|
|
<classname>MongoInt32</classname>, <classname>MongoInt64</classname>.
|
|
</para>
|
|
</section>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Strings</title>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Regular expressions can be used to match strings, and are expressed using the
|
|
<classname>MongoRegex</classname> class.
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Binary Data</title>
|
|
<para>
|
|
Non-UTF-8 strings, images, and any other binary data should be sent to the
|
|
database using the <classname>MongoBinData</classname> type.
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Dates</title>
|
|
<para>
|
|
Dates can be created using the <classname>MongoDate</classname> class. They
|
|
are stored as milliseconds since the epoch.
|
|
</para>
|
|
<para>
|
|
<classname>MongoTimestamp</classname> 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
|
|
<classname>MongoDate</classname>, <emphasis>not</emphasis>
|
|
<classname>MongoTimestamp</classname>.
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Unique Ids</title>
|
|
<para>
|
|
The driver will automatically create an <literal>_id</literal> field before
|
|
inserting a document (unless one is specified by the user). This field is an
|
|
instance of <classname>MongoId</classname> (called "ObjectId" in most other
|
|
languages).
|
|
</para>
|
|
<para>
|
|
These ids are 12 bytes long and composed of:
|
|
<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.
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>JavaScript</title>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
For security, use <classname>MongoCode</classname>'s <literal>scope</literal>
|
|
field to use PHP variables in JavaScript. Code that does not require
|
|
external values can either use <classname>MongoCode</classname> or just be
|
|
a string. See the
|
|
<link linkend="mongo.security">section on security</link> for more
|
|
information about sending JavaScript to the database.
|
|
</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
|
|
|
|
// $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));
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
|
|
<para>
|
|
If you query for these objects using the database shell, they will look like:
|
|
<programlisting role="shell">
|
|
<![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 role="shell">
|
|
<![CDATA[
|
|
> 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>
|
|
|
|
<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 role="txt">
|
|
<![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>
|
|
</section>
|
|
</partintro>
|
|
&reference.mongo.mongoid;
|
|
&reference.mongo.mongocode;
|
|
&reference.mongo.mongodate;
|
|
&reference.mongo.mongoregex;
|
|
&reference.mongo.mongobindata;
|
|
&reference.mongo.mongoint32;
|
|
&reference.mongo.mongoint64;
|
|
&reference.mongo.mongodbref;
|
|
&reference.mongo.mongominkey;
|
|
&reference.mongo.mongomaxkey;
|
|
&reference.mongo.mongotimestamp;
|
|
|
|
</part>
|