Прошла неделя с тех пор как я начал использовать MongoDB в качестве базы данных.
В качестве ORM изначально использовал mongodm, так как она написана в наиболее близком к моему стилю.
Но, по мере использования выяснились некоторые проблемы, например, использование 1Гб памяти при полной выборке по относительно небольшой коллекции: библиотека пыталась сразу создать все модели. Также указание соединения и названия коллекции в модели — не слишком удобно.
В связи с тем, что переписывать по сути надо не так много (4 файла в оригинале), написал за пару дней свой вариант, в своем стиле, и выложил сегодня на github.
Итак, представляю kanon-mongo:
Требования:
PHP >= 5.3
PECL mongoclient >= 1.3.0
Для автозагрузки классов можете воспользоваться картой классов в описании на github.
Создание модели
<?php
namespace mynamespace;
use ruolamediakanonmongomodel;
class article extends model{
protected static $_properties = [
'parent' => [
'model'=>'my\namespace\article',
'type'=>'reference'
],
'name' => [
'default'=>'',
'type'=>'string'
]
];
}
Установка соединения:
use ruolamediakanonmongo;
mongoconnection::getInstance('default') // или просто mongoconnection::getInstance(), также будет использовать инстанс по имени 'default'
->connect([
'connection' => [
'hostnames' => 'localhost',
'database' => 'dbname',
]
])
->registerModel(
'my\namespace\article', // имя класса
'articles' // имя коллекции
);
Использование моделей:
$article1 = new article();
$article1->name = 'Новая статья';
$article1->save();
$article2 = new article(['name' => 'Hello world']);
$article2->parent = $article1; // ссылка на первую статью
$article2->save();
var_dump($article1->getId());
echo $article1->getId(); // MongoDB использует поле _id как основной ключ, храня в нем объекты класса MongoId, которые можно конвертировать в строку.
var_dump($article1->name);
$article1->delete();
Запросы: (параметры запросов аналогичны указанным в документации php.net/mongoclient)
$result = article::find($criteria, $fields);
$result = article::findOne($criteria, $fields);
// $result будет объектом класса ruolamediakanonmongoresult, состоящего из курсора MongoCursor и имени класса, инстансы которого он должен возвращать заместо массивов,
// Можно получить курсор из результата, а также использовать его методы для настройки результата:
$cursor = $result->getCursor();
// Создание result из имени класса и объекта MongoCursor:
$result = new result('my\namespace\article', $cursor);
// Методы результата (аналогичны методам курсора, за исключением asc, desc)
$result->asc('name');
$result->desc('name');
$result->sort(['name'=>1]); // @see http://php.net/mongocursor.sort
$result->skip(3); // @see http://php.net/mongocursor.skip
$result->limit(10); // see http://php.net/mongocursor.limit
// Запросы с помощью коллекций (а также получение коллекции по имени класса):
$collection = collection::forClass('my\namespace\article'); // ruolamediakanonmongocollection
$mongoCollection = $collection->select(); // MongoCollection
$cursor = $mongoCollection->find($criteria, $fields); // MongoCursor
$result = new result('my\namespace\article', $cursor); // ruolamediakanonmongoresult
foreach ($result as $article){ // mynamespacearticle
echo $article->name.'<br />';
}
Исходники
Github
Лицензия
MIT
P.S.
Предвкушая вопрос, почему не попробовать другую библиотеку — потому что мне удобнее использовать ORMы именно в таком виде, как я написал.
Спасибо за внимание.
Автор: olamedia