旧版驱动程序升级指南
概述
MongoDB PHP 库和底层 mongodb 扩展 与旧版 扩展具有显着的 APImongo
差异。本页将总结这些差异,以方便从旧版驱动程序升级的用户。
此外,社区开发 的 mongo-php-adapter 库存在,它使用该库和mongo
扩展来实现 扩展mongodb
API。虽然 MongoDB 未正式支持此适配器库,但值得一提。
BSON
类型类
从旧版驱动程序升级时,必须将 MongoId 等类型类替换为 MongoDB\BSON 命名空间 中的类 。新驱动程序还为其BSON types引入了接口,如果应用程序需要针对BSON值进行类型提示,则应首选该接口。
下表列出了所有旧版类以及新驱动程序中的等效类。
传统类 | BSON 类型类 | BSON 类型接口 |
---|---|---|
Mongoid | ||
MongoCode | ||
MongoDate | ||
MongoRegex | ||
MongoBinData | ||
MongoInt32 | 未实施。 [1] | |
MongoInt64 | 未实施。 [2] | |
MongoDBRef | 未实施。 [3] | |
MongoMinKey | ||
MongoMaxKey | ||
MongoTimestamp |
[1] | 新驱动程序没有为 MongoInt32 实现等效的类。 解码 BSON 时,32 位整数将始终表示为 PHP 整数。 对 BSON 进行编码时,PHP 整数将根据其值编码为 32 位或 64 位整数。 |
[2] | MongoDB\BSON\Int64 没有定义接口。 |
[3] | ( 1 、 2 、 3 )新驱动程序没有为 MongoDBRef 实现等效的类,因为DBRef只是具有特定结构的 BSON 文档,而不是真正的 BSON 类型。 新驱动程序也不提供任何用于处理 DBRef 对象的助手,因为不鼓励使用它们。 |
模拟旧版驱动程序
旧版mongo
扩展会将 BSON 文档和数组作为 PHP 数组返回。 虽然 PHP 数组使用起来很方便,但这种行为是有问题的:
不同的 BSON types 可以反序列化为相同的 PHP 值(例如
{"0": "foo"}
和["foo"]
),这使得无法推断原始 BSON 类型。如果数字索引的 PHP 数组的键序列中存在间隔,则该数组将被序列化为 BSON 文档。 此类间隙是由于取消设置键以删除元素并忘记以数字方式对数组重新索引而造成的。
MongoDB PHP 库的 BSONDocument
和BSONArray
类通过在序列化和反序列化期间保留 BSON 类型信息来解决这些问题;但是,某些用户可能仍喜欢使用传统行为。如果需要,可以使用typeMap
选项让库以 PHP 数组的形式返回所有内容:
$client = new MongoDB\Client( 'mongodb://127.0.0.1/', [], [ 'typeMap' => [ 'array' => 'array', 'document' => 'array', 'root' => 'array', ], ] ); $document = $client->test->zips->findOne(['_id' => '94301']); var_dump($document);
上面的示例会输出类似以下内容:
array(5) { ["_id"]=> string(5) "94301" ["city"]=> string(9) "PALO ALTO" ["loc"]=> array(2) { [0]=> float(-122.149685) [1]=> float(37.444324) } ["pop"]=> int(15965) ["state"]=> string(2) "CA" }
collection API
该库的 类实现MongoDB\Collection
MongoDB 的跨驱动程序 CRUD 和 索引管理 规格。尽管某些方法名称已根据新规范进行了更改,但新类提供了与传统驱动程序的 MongoCollection 类相同的功能,但有一些值得注意的例外情况。
设计新 API 的一个指导原则是,使用显式方法名称优于旧 API 中的重载术语。例如, MongoCollection::save()
和MongoCollection::findAndModify()
有不同的操作模式,具体取决于它们的参数。方法还进行了拆分,以区分更新特定字段和全文档替换。
下表列出了所有旧方法以及新驱动程序中的等效方法。
MongoCollection 方法 | |
---|---|
MongoCollection::aggregate() | |
MongoCollection::aggregateCursor() | |
MongoCollection::batchInsert() | |
MongoCollection::count() | |
MongoCollection::createDBRef() | 尚未实施。 [3] |
MongoCollection::createIndex() | |
MongoCollection::deleteIndex() | |
MongoCollection::deleteIndexes() | |
MongoCollection::drop() | |
MongoCollection::distinct() | |
MongoCollection::ensureIndex() | |
MongoCollection::find() | |
MongoCollection::findAndModify() | |
MongoCollection::findOne() | |
MongoCollection::getDBRef() | 未实施。 [3] |
MongoCollection::getIndexInfo() | |
MongoCollection::getName() | |
MongoCollection::getReadPreference() | |
MongoCollection::getSlaveOkay() | 未实施。 |
MongoCollection::getWriteConcern() | |
MongoCollection::group() | 未实施。使用 MongoDB\Database::command() 。有关示例,请参阅群组命令助手。 |
MongoCollection::insert() | |
MongoCollection::parallelCollectionScan() | 未实施。 |
MongoCollection::remove() | |
MongoCollection::save() | |
MongoCollection::setReadPreference() | |
MongoCollection::setSlaveOkay() | 未实施。 |
MongoCollection::setWriteConcern() | |
MongoCollection::update() | |
MongoCollection::validate() | 未实施。 |
访问已插入文档的 ID
在传统驱动程序中,MongoCollection::insert()
、MongoCollection::batchInsert()
和MongoCollection::save()
(插入时)将通过插入带有生成的_id
ObjectId(即 MongoId 对象)的 键来修改其输入参数。这种行为有点像黑客,因为它不依赖于 通过引用传递 参数 ;相反,它通过扩展 API 直接修改内存,并且无法在 PHP 用户区实现。因此,新驱动程序中不再执行此操作。
可以在写入结果对象上通过以下方法访问插入的文档(无论是否生成)的 ID:
批量写入操作
旧版驱动程序的 MongoWriteBatch 类已替换为通用MongoDB\Collection::bulkWrite()
方法。 旧版驱动程序仅允许相同类型的批量操作,而新方法允许混合操作(例如 插入、更新和删除)。
MongoCollection::save() 已删除
MongoCollection::save()
,它是插入或更新插入操作的语法糖,已被删除,取而代之的是显式使用MongoDB\Collection::insertOne()
或MongoDB\Collection::replaceOne()
(使用upsert
选项)。
虽然save
方法确实可用于交互式环境(例如MongoDBshell ),但它被有意排除在CRUD 规范 之外 用于语言驱动程序。一般来说,应用程序代码应该知道文档是否具有标识符,能够显式插入或替换文档并分别处理返回的MongoDB\InsertOneResult
或MongoDB\UpdateResult
。 这也有助于避免无意中和潜在危险的完整文档替换。
群组命令助手
MongoDB\Collection
没有群组命令的辅助方法。以下示例演示了如何使用MongoDB\Database::command()
方法执行群组命令:
$database = (new MongoDB\Client)->selectDatabase('db_name'); $cursor = $database->command([ 'group' => [ 'ns' => 'collection_name', 'key' => ['field_name' => 1], 'initial' => ['total' => 0], '$reduce' => new MongoDB\BSON\Javascript('...'), ], ]); $resultDocument = $cursor->toArray()[0];