Этой статье я расскажу о своем опыте миграции с устаревшего mongo PHP extension на mongodb. Расширения имеют абсолютно разный API. Поэтому есть смысл применить для нового более высокоуровневую абстракцию.
Я для этой цели использовал MongoDB PHP Library. У этой библиотеки API достаточно близок к старой версии. В документации есть upgrade guide, но без примеров. При этом есть куча мелких отличий, которые, в свою очередь, чреваты кучей багов. Ниже перечислю основные, из тех с которыми пришлось столкнуться:
1. Подключение.
Теперь подключение выглядит так:
$client = new \MongoDB\Client( 'mongodb://rs1.example.com,rs2.example.com/?replicaSet=myReplicaSet', [ 'readPreference' => 'secondaryPreferred' ] );
C аутентификацией (для пароля нужно добавить urlencode):
mongodb://username:[email protected],rs2.example.com/
Если указать реплику и аутентификацию в параметрах (как было раньше) — работать не будет.
2. Объекты от старого расширения.
Используйте $db->collectionName
вместо new \MongoCollection($db, ‘collectionName’).
\MongoRegex
меняется на \MongoDB\BSON\Regex
и принимает другие параметры на вход.
\MongoId
заменен на \MongoDB\BSON\ObjectID
.
Это наиболее часто используемые классы. Если используется что то еще — ищите аналоги в документации.
3. Методы find\findOne.
Теперь вместо массива будет возвращаться объект \MongoDB\Model\BSONDocument
. На первый взгляд он может работать так же как массив. Но тут нужно быть осторожным. Потому что если в старом коде используется что то типа is_array()
, array_merge()
и т.д., в применении к такому объекту, работать это не будет.
Второй параметр теперь options. Если нужно задать список возвращаемых полей, используйте параметр projection в options:
$collection->find([], [‘projection’ => [‘id’, ‘name’, ‘email’]])
В новой библиотеке нет методов limit()
, offset()
, skip()
, order()
, nextOne()
. Вместо использования методов добавляейте эти параметры в options. Например:
$collection->find([], [ 'skip' => 10, 'limit' => 10, 'sort' => [‘name’ => -1] ]);
*Строка в параметре limit теперь вызовет fatal error.
Так же, теперь нельзя применить метод count к курсору. Можно использовать
$collection->count()
, но не $collection->find()->count()
.
4. Метод update.
Теперь для этой цели много новых методов. И как с ними работать далеко не всегда очевидно.
Для себя я выбрал три:
updateOne([‘name’ => ‘foo’], [‘$set’ => [‘title’ => ‘test’, ...]])
— если нужно обновить только часть объекта. Переданный параметр ‘_id’ вызовет fatal error.
findOneAndReplace([‘name’ => ‘foo’], $fullObject)
— если нужно переписать объект целиком. ‘_id’ должен быть объектом, не строкой.
updateMany([‘name’ => ‘foo’], [‘$set’ => [‘title’ => ‘test’, ...]])
— работает аналогично с updateOne.
Все эти методы возвращают MongoDB\UpdateResult
, а не обновленный объект, как было раньше.
5. Остальное.
Некоторые методы были просто переименованы, например remove()
, insertMany()
. Практически во всех методах поменялись возвращаемые параметры.
Insert был заменен на insertOne
и возвращает MongoDB\InsertOneResult
.
Формат результатов в методе aggregate()
был изменен.
Смотрите upgrade guide насчет других изменений.