MongoDB позволяет программистам сохранять и запрашивать данные, выраженные во всех основных типах PHP, составных типах (массивы, ассоциативные массивы и объекты) и полдюжины классов, предоставляемых драйвером PHP MongoDB (для регулярных выражений, дат и другие специализированные приложения).
NULL
TRUE
, FALSE
, и NULL
могут использоваться как есть.
Числа отличаются от строк в MongoDB: "123" не соответствует 123. Таким образом, если вы хотите убедиться, что числа отсортированы и сопоставлены правильно, вы должны убедиться, что они действительно сохраняются, как числа.
<?php
$doc = array("a" => 123, "b" => "123");
$collection->insert($doc);
$doc->find(array("a" => 123)); // совпадает
$doc->find(array("a" => "123")); // не совпадает
$doc->find(array("a" => 123.0)); // совпадает
$doc->find(array("b" => 123)); // не совпадает
$doc->find(array("b" => "123")); // совпадает
?>
Как отмечено выше, числа с плавающей запятой сравниваются с целыми числами или совпадают с ними, как и следовало ожидать.
По умолчанию, в 32-разрядной системе числа отправляются в базу данных, как 32-разрядные целые числа. В 64-битной системе они отправляются, как 64-битные целые числа. Для обратной совместимости все системы десериализуют 64-битные целые числа, как числа с плавающей запятой. Числа с плавающей точкой не являются точными. Если вам нужны точные значения, вы должны изменить настройки php.ini.
В 32-битной системе, если установлен mongo.long_as_object, 64-битные целые числа будут возвращены, как объекты MongoInt64. Целое число будет сохранено в поле значения с идеальной точностью (в виде строки). Вы также можете использовать MongoInt64 для сохранения 64-разрядных целых чисел на 32-разрядных компьютерах.
В 64-битных системах вы можете установить mongo.long_as_object или mongo.native_long. mongo.native_long вернет 64-битные целые и "нормальные" целые числа PHP. Вы можете использовать MongoInt32 для сохранения 32-разрядных целых чисел на 64-разрядных компьютерах.
Вам следует установить поведение mongo.long_as_object и mongo.native_long, которое вы планируете использовать, даже если это поведение по умолчанию (для защиты от будущих изменений по умолчанию).
Смотрите также: параметры php.ini, MongoInt32, MongoInt64.
Строки должны быть UTF-8. Строки не-UTF-8 должны быть либо преобразованы в UTF-8 перед отправкой в базу данных, либо сохранены, как двоичные данные.
Регулярные выражения могут использоваться для сопоставления строк и выражаются с использованием класса MongoRegex.
Строки, изображения и любые другие двоичные данные не в формате UTF-8 следует отправлять в базу данных с использованием типа MongoBinData.
Даты могут быть созданы с помощью класса MongoDate. Они хранятся в миллисекундах с начала Unix-эпохи.
MongoTimestamp не предназначен для сохранения дат или временных меток, он используется внутри MongoDB. Если вы не создаете инструмент, взаимодействующий с внутренними компонентами репликации или шардинга, вы должны использовать MongoDate, а не MongoTimestamp.
Драйвер автоматически создаст поле _id перед вставкой документа (если он не указан пользователем). Это поле является экземпляром MongoId (в большинстве других языков называется "ObjectId").
Эти идентификаторы имеют длину 12 байтов и состоят из:
4 байта метки времени
Никакие две записи не могут иметь одинаковый идентификатор, если они были вставлены в разное время.
3-х байтовый идентификатор машины
Никакие две записи не могут иметь одинаковый идентификатор, если они были вставлены на разных компьютерах.
2-х байтовый идентификатор потока
Никакие две записи не могут иметь одинаковый идентификатор, если они были вставлены разными потоками, работающими на одной машине.
3 байта значения приращения
Каждый раз, когда создается идентификатор, глобальный счетчик увеличивается и используется в качестве значения приращения следующего идентификатора.
MongoDB поставляется с механизмом JavaScript, так что вы можете встраивать JavaScript в запросы (используя предложение $where), отправлять его непосредственно в базу данных для выполнения и использовать для выполнения агрегации.
В целях безопасности используйте поле scope MongoCode, чтобы использовать переменные PHP в JavaScript. Код, который не требует внешних значений, может использовать MongoCode или просто быть строкой. Смотрите раздел о безопасности для получения дополнительной информации об отправке JavaScript в базу данных.
Массивы и объекты также могут быть сохранены в базе данных. Массив с восходящими числовыми ключами будет сохранен, как массив, все остальное – как объект.
<?php
// $scores будет сохранен, как массив
$scores = array(98, 100, 73, 85);
$collection->insert(array("scores" => $scores));
// $scores будет сохранен, как объект
$scores = array("quiz1" => 98, "midterm" => 100, "quiz2" => 73, "final" => 85);
$collection->insert(array("scores" => $scores));
?>
Если вы запросите эти объекты с помощью оболочки базы данных, они будут выглядеть так:
> db.students.find() { "_id" : ObjectId("4b06beada9ad6390dab17c43"), "scores" : [ 98, 100, 73, 85 ] } { "_id" : ObjectId("4b06bebea9ad6390dab17c44"), "scores" : { "quiz1" : 98, "midterm" : 100, "quiz2" : 73, "final" : 85 } }
База данных также может сохранять произвольные объекты PHP (хотя они будут возвращаться в виде ассоциативных массивов). Поля используются для пар ключ/значение. Например, сообщение в блоге может выглядеть так:
<?php
// класс сообщения в блоге
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;
}
}
// создаем простую запись в блоге и вставляем ее в базу данных
$post1 = new Post("Adam", "This is a blog post");
$blog->insert($post1);
// нет ничего ограничивающего тип поля "автор",
// поэтому мы можем сделать его вложенным объектом
$author = array("name" => "Fred", "karma" => 42);
$post2 = new Post($author, "This is another blog post.");
// мы создаем дополнительное поле, устанавливая заголовок
$post2->setTitle("Second Post");
$blog->insert($post2);
?>
Из оболочки базы данных это будет выглядеть примерно так:
> 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" }
Драйвер не будет обнаруживать эталонные циклы в массивах и объектах. Например, это выдаст фатальную ошибку:
<?php
$collection->insert($GLOBALS);
?>
Fatal error: Nesting level too deep - recursive dependency?