与构建者合作
Overview
在本指南中,您可以学习;了解PHP库提供的构建器类,用于创建操作中使用的类型。您可以使用聚合构建器功能中的构建器类和工厂方法为其他操作(例如查找、更新和删除操作)创建筛选器。要学习;了解有关聚合构建器的更多信息,请参阅聚合指南的 聚合构建器 部分。
使用构建者创建查询有助于在编译时识别错误并在运行时避免错误。本指南提供有关可用于执行以下任务的构建器类的信息:
注意
设置操作选项
您不能使用工厂方法为等效聚合阶段指定选项。示例,您不能使用 Stage::limit()
方法为查找操作设立返回的文档限制。您必须使用基于字符串的语法指定选项,如以下代码所示:
$options = [ 'limit' => 5, '<option name>' => '<specification>', ];
本指南提供了如何在非聚合操作中使用构建者的示例。要查看聚合示例,请参阅《使用聚合转换数据》指南。
样本数据
本指南中的示例使用Atlas示例数据集的sample_geospatial
数据库中的shipwrecks
集合。 要从PHP应用程序访问权限此集合,请实例化一个连接到Atlas 集群的MongoDB\Client
,并将以下值分配给$collection
变量:
$collection = $client->sample_geospatial->shipwrecks;
要学习;了解如何创建免费的MongoDB Atlas 群集并加载示例数据集,请参阅Atlas入门指南。
导入构建器类
要运行本指南中的示例,您必须将以下类导入到您的应用程序中:
use MongoDB\Builder\Pipeline; use MongoDB\Builder\Query; use MongoDB\Builder\Stage;
创建筛选器
您可以使用 Query
构建器类中的工厂方法来创建过滤定义,以在查找、更新和删除操作中使用。使用 Query::query()
工厂方法创建查询时,您可以使用命名参数语法并实现类型安全。如需学习;了解有关创建筛选器的更多信息,请参阅“指定查询”指南。
以下步骤描述了如何使用构建者创建过滤定义:
调用
Query::query()
方法创建查询。传递要过滤的字段名称和
Query
类中的工厂方法。您可以在过滤中传递一对或多对字段名称和条件,以应用多个子句。
以下代码显示了使用构建者创建过滤定义的模板:
$filter = Query::query( <field name>: Query::<factory method>(<parameters>), <field name>: Query::<factory method>(<parameters>), ... );
要使用逻辑查询运算符($and
、$or
、$not
、$nor
)组合查询条件,可以使用以下查询模板:
$filter = Query::<logical operator>( Query::query(<field name>: Query::<factory method>(<parameters>)), Query::query(<field name>: Query::<factory method>(<parameters>)), ... );
要学习;了解更多信息,请参阅MongoDB Server手册中的逻辑查询操作符。
以下部分提供了使用构建者为不同操作创建过滤定义的示例。
检索示例
此示例将执行以下动作:
使用
Query::eq()
工厂方法匹配feature_type
字段值为'Wrecks - Visible'
的文档使用
Query::near()
工厂方法匹配coordinates
位置字段在指定坐标10000
米范围内的文档调用
MongoDB\Collection::find()
方法以检索匹配的文档打印匹配的文档
// Creates a query filter by using builders and // retrieves matching documents $docs = $collection->find( Query::query( feature_type: Query::eq('Wrecks - Visible'), coordinates: Query::near( Query::geometry( type: 'Point', coordinates: [-79.9, 9.3], ), maxDistance: 10000, ) ) ); // Prints matching documents foreach ($docs as $doc) { echo json_encode($doc), PHP_EOL; }
{"_id":...,"feature_type":"Wrecks - Visible","coordinates":[-79.9137115,9.3390503],...} {"_id":...,"feature_type":"Wrecks - Visible","coordinates":[-79.9357223,9.3340302],...} {"_id":...,"feature_type":"Wrecks - Visible","coordinates":[-79.9081268,9.3547792],...} // Results truncated
要了解有关查找操作的更多信息,请参阅检索数据指南。
删除示例
此示例将执行以下动作:
使用
Query::or()
工厂方法匹配满足以下任查询子句的文档:使用
Query::regex()
工厂方法检查feature_type
字段值是否包含字符串'nondangerous'
的子句使用
Query::gt()
工厂方法检查depth
字段值是否大于10.0
的子句
调用
MongoDB\Collection::deleteOne()
方法删除第一个匹配文档打印已删除文档的数量
// Creates a query filter by using builders // and deletes the first matching document $result = $collection->deleteOne( Query::or( Query::query(feature_type: Query::regex('nondangerous$', '')), Query::query(depth: Query::gt(10.0)), ) ); // Prints number of deleted documents echo 'Deleted documents: ', $result->getDeletedCount(), PHP_EOL;
Deleted documents: 1
要了解有关删除操作的更多信息,请参阅删除文档指南。
定义更新文档
您可以使用 Stage
构建器类中的工厂方法来创建更新文档。更新文档描述了对目标文档进行的更新。要学习;了解有关更新文档的更多信息,请参阅更新文档指南。
以下步骤描述了如何使用构建者创建更新文档:
创建一个
Pipeline
实例。通过调用
Stage
类(例如Stage::set()
)中的方法并传递字段名称和值来传递一个或多个阶段。
以下代码显示了使用构建者定义更新的模板:
$update = new Pipeline( Stage::set(<field name>: <value>), Stage::set(<field name>: <value>), ... );
此示例将执行以下动作:
使用
Query::eq()
工厂方法匹配watlev
字段值为'partly submerged at high water'
的文档使用
Stage::set()
方法将year
字段设立为1870
调用
MongoDB\Collection::updateOne()
方法执行更新打印已更新文档的数量
// Creates a query filter and an update document by // using builders and updates the first matching document $result = $collection->updateOne( Query::query(watlev: Query::eq('partly submerged at high water')), new Pipeline( Stage::set(year: 1870), ), ); // Prints number of updated documents echo 'Updated documents: ', $result->getModifiedCount(), PHP_EOL;
Updated documents: 1
修改变更流输出
您可以使用 Stage
类中的工厂方法,通过创建管道来修改变更流的输出。要学习;了解有关变更流的更多信息,请参阅《监控数据更改》指南。
以下步骤描述了如何使用构建者创建变更流过滤:
创建一个大量。
通过从
Stage
类调用工厂方法和所需参数来传递一个或多个$match
阶段。
以下代码显示了使用构建者修改变更流输出的模板:
$pipeline = [ Stage::<factory method>(...), Stage::<factory method>(...), ... ];
您可以将此管道传递给以下方法:
此示例将执行以下动作:
使用
Stage::match()
方法仅过滤更新操作的更改事件使用
Stage::project()
方法仅输出operationType
、ns
(命名空间)和fullDocument
字段调用
MongoDB\Collection::watch()
方法打开变更流并设置fullDocument
选项以在更新后输出完整文档打印发生的变更事件
// Creates a pipeline to filter for update operations and return // only specific fields $pipeline = [ Stage::match(operationType: Query::eq('update')), Stage::project(operationType: 1, ns: 1, fullDocument: 1), ]; // Opens the change stream $changeStream = $collection->watch( $pipeline, ['fullDocument' => MongoDB\Operation\Watch::FULL_DOCUMENT_UPDATE_LOOKUP] ); // Prints change events based on the pipeline specifications for ($changeStream->rewind(); true; $changeStream->next()) { if (! $changeStream->valid()) { continue; } $event = $changeStream->current(); echo json_encode($event), PHP_EOL; if ($event['operationType'] === 'invalidate') { break; } }
{ "_id":..., "operationType":"update", "fullDocument":{"_id":...,"feature_type":"Wrecks - Visible",...}, "ns":{"db":"sample_geospatial","coll":"shipwrecks"} }
要学习;了解有关变更事件提供的信息的更多信息,请参阅MongoDB Server手册中的变更事件。