Docs 菜单

与构建者合作

在本指南中,您可以学习;了解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() 工厂方法创建查询时,您可以使用命名参数语法并实现类型安全。如需学习;了解有关创建筛选器的更多信息,请参阅“指定查询”指南。

以下步骤描述了如何使用构建者创建过滤定义:

  1. 调用 Query::query() 方法创建查询。

  2. 传递要过滤的字段名称和 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 构建器类中的工厂方法来创建更新文档。更新文档描述了对目标文档进行的更新。要学习;了解有关更新文档的更多信息,请参阅更新文档指南。

以下步骤描述了如何使用构建者创建更新文档:

  1. 创建一个Pipeline实例。

  2. 通过调用 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 类中的工厂方法,通过创建管道来修改变更流的输出。要学习;了解有关变更流的更多信息,请参阅《监控数据更改》指南。

以下步骤描述了如何使用构建者创建变更流过滤:

  1. 创建一个大量。

  2. 通过从 Stage 类调用工厂方法和所需参数来传递一个或多个 $match 阶段。

以下代码显示了使用构建者修改变更流输出的模板:

$pipeline = [
Stage::<factory method>(...),
Stage::<factory method>(...),
...
];

您可以将此管道传递给以下方法:

此示例将执行以下动作:

  • 使用 Stage::match() 方法仅过滤更新操作的更改事件

  • 使用 Stage::project() 方法仅输出 operationTypens(命名空间)和 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手册中的变更事件