Overview
在本指南中,您可以学习;了解如何使用变更流来监控数据的实时变更。 变更流是MongoDB Server的一项功能,允许应用程序订阅集合、数据库或部署上的数据更改。
使用MongoDB PHP库时,您可以调用watch()方法返回MongoDB\ChangeStream的实例。 然后,您可以遍历MongoDB\ChangeStream实例以监控数据更改,例如更新、插入和删除。
提示
Atlas Stream Processing
作为变更流的替代方案,您可以使用Atlas Stream Processing来处理和转换数据流。与仅注册数据库事件的变更流不同,Atlas Stream Processing托管多种数据事件类型并提供扩展的数据处理功能。要学习;了解有关此功能的更多信息,请参阅MongoDB Atlas文档中的Atlas Stream Processing 。
样本数据
本指南中的示例使用Atlas示例数据集的sample_restaurants数据库中的restaurants集合。 要从PHP应用程序访问权限此集合,请实例化一个连接到Atlas 集群的MongoDB\Client ,并将以下值分配给$collection变量:
$collection = $client->sample_restaurants->restaurants;
提示
要学习如何创建免费的MongoDB 部署并加载示例数据集,请参阅MongoDB 入门指南。
一些示例使用toJSON()函数将变更事件(属于BSON文档)表示为 扩展JSON。 要使用此函数,请将以下代码粘贴到应用程序文件:
function toJSON(object $document): string { return MongoDB\BSON\Document::fromPHP($document)->toRelaxedExtendedJSON(); }
打开变更流
要打开变更流,请调用watch()方法。 您调用watch()方法的实例决定了变更流监控的事件范围。 您可以对以下类的实例调用watch()方法:
MongoDB\Client:监控MongoDB 部署中的所有更改MongoDB\Database:监控数据库中所有集合的变更MongoDB\Collection:监控集合中的更改
以下示例在restaurants集合上打开变更流,并在发生变更时输出变更:
$changeStream = $collection->watch(); $changeStream->rewind(); while (true) { $changeStream->next(); if ($changeStream->valid()) { continue; } $event = $changeStream->current(); echo toJSON($event), PHP_EOL; if ($changeStream->current()['operationType'] === 'invalidate') { break; } }
要开始监视更改,请运行前面的代码。 然后,在另一个shell中修改 restaurants集合。 以下示例更新了name字段值为'Blarney Castle'的文档:
$result = $collection->updateOne( ['name' => 'Blarney Castle'], ['$set' => ['cuisine' => 'Irish']], );
更新集合时,变更流应用程序会在发生变更时打印变更。 打印的变更事件类似于以下输出:
{ "_id" : { "_data" : "..." }, "operationType" : "update", "clusterTime" : { "$timestamp" : { ... } }, "wallTime" : { "$date" : "..." }, "ns" : { "db" : "sample_restaurants", "coll" : "restaurants" }, "documentKey" : { "_id" : { "$oid" : "..." } }, "updateDescription" : { "updatedFields" : { "cuisine" : "Irish" }, "removedFields" : [ ], "truncatedArrays" : [ ] } }
修改变更流输出
要修改变更流输出,可以将大量中的管道阶段作为参数传递给watch()方法。 您可以在大量中包含以下阶段:
$addFields或$set:向文档添加新字段$match:筛选文档$project:投影文档字段的子集$replaceWith或$replaceRoot:将输入文档替换为指定文档$redact:限制文档内容$unset:从文档中删除字段
以下示例将包含$match阶段的管道传递给watch()方法。 这指示watch()方法仅在发生更新操作时输出事件:
$pipeline = [['$match' => ['operationType' => 'update']]]; $changeStream = $collection->watch($pipeline); $changeStream->rewind(); while (true) { $changeStream->next(); if ($changeStream->valid()) { continue; } $event = $changeStream->current(); echo toJSON($event), PHP_EOL; if ($changeStream->current()['operationType'] === 'invalidate') { break; } }
修改 watch() 行为
要修改watch()方法的行为,可以将选项大量作为参数传递给watch() 。 下表描述了您可以在大量中设立的有用选项:
选项 | 说明 |
|---|---|
| 指定是否在更改后显示完整文档,而不是仅显示对文档所做的更改。若要了解有关此选项的更多信息,请参阅本指南的包含预图像和后图像部分。 |
| 指定是否显示更改前的完整文档,而不是仅显示对文档所做的更改。 要了解有关此选项的更多信息,请参阅包括前图像和后图像。 |
| 指示 |
| 指示变更流仅提供在指定时间戳时或之后发生的变更。此选项与 |
| 设置用于变更流游标的排序规则。要了解更多信息,请参阅本页面的 排序规则 部分。 |
有关watch()选项的完整列表,请参阅API文档中的MongoDB \Collection::watch() 。
包含前像和后像
重要
仅当您的部署使用 MongoDB v 6.0或更高版本时,才能对集合启用前图像和后图像。
默认,当您对集合执行操作时,相应的变更事件仅包括该操作修改的字段的增量。 要查看更改之前或之后的完整文档,请将大量参数中的fullDocumentBeforeChange或fullDocument选项指定为watch() 。
前像是文档在更改之前的完整版本。 要将前像包含在变更流事件,请将fullDocumentBeforeChange选项设立为以下值之一:
MongoDB\Operation\Watch::FULL_DOCUMENT_BEFORE_CHANGE_WHEN_AVAILABLE:变更事件包括变更事件的已修改文档的前像。 如果前像不可用,则此变更事件字段的值为null。MongoDB\Operation\Watch::FULL_DOCUMENT_BEFORE_CHANGE_REQUIRED:变更事件包括变更事件的已修改文档的前像。 如果前像不可用,服务器将引发错误。
后像是文档更改后的完整版本。 要将后图像包含在变更流事件,请将fullDocument选项设立为以下值之一:
MongoDB\Operation\Watch::FULL_DOCUMENT_UPDATE_LOOKUP:更改事件包括更改后某个时间点的整个已更改文档的副本。MongoDB\Operation\Watch::FULL_DOCUMENT_WHEN_AVAILABLE:变更事件包括变更事件的已修改文档的后像。 如果后像不可用,则此变更事件字段的值为null。MongoDB\Operation\Watch::FULL_DOCUMENT_REQUIRED:变更事件包括变更事件的已修改文档的后像。 如果后图像不可用,服务器将引发错误。
以下示例对集合调用watch()方法,并通过设置fullDocument选项包含更新文档的后像:
$options = ['fullDocument' => MongoDB\Operation\Watch::FULL_DOCUMENT_UPDATE_LOOKUP]; $changeStream = $collection->watch([], $options); $changeStream->rewind(); while (true) { $changeStream->next(); if ($changeStream->valid()) { continue; } $event = $changeStream->current(); echo toJSON($event), PHP_EOL; if ($changeStream->current()['operationType'] === 'invalidate') { break; } }
当变更流应用程序在单独的shell中运行时,使用前面的更新示例更新restaurants集合中的文档会打印类似于以下输出的变更事件:
{ "_id" : { "_data" : "..." }, "operationType" : "update", "clusterTime" : { "$timestamp" : { ... } }, "wallTime" : { "$date" : "..." }, "fullDocument" : { "_id" : { "$oid" : "..." }, "address" : { "building" : "202-24", "coord" : [ -73.925044200000002093, 40.559546199999999772 ], "street" : "Rockaway Point Boulevard", "zipcode" : "11697" }, "borough" : "Queens", "cuisine" : "Irish", "grades" : [ ...], "name" : "Blarney Castle", "restaurant_id" : "40366356" }, "ns" : { "db" : "sample_restaurants", "coll" : "restaurants" }, "documentKey" : { "_id" : { "$oid" : "..." } }, "updateDescription" : { "updatedFields" : { "cuisine" : "Irish" }, "removedFields" : [ ], "truncatedArrays" : [ ] } }
提示
要了解有关前图像和后图像的更多信息,请参阅Change Streams MongoDB Server手册中的 具有文档前图像和后图像的 。
排序规则
要为操作指定排序规则,请传递 $options大量参数,该参数将 collation 选项设置为操作方法。将 collation 选项分配给配置排序规则规则的大量。
下表描述了可以设立以配置排序规则的字段:
字段 | 说明 |
|---|---|
| |
| (可选)指定是否包括大小写比较。当设立为 |
| (可选)指定三级比较期间大小写差异的排序顺序。数据类型: |
| (可选)指定要执行的比较级别,如 ICU 文档中所定义。数据类型: |
| (可选)指定驱动程序是将数字字符串作为数字还是字符串进行比较。 |
| (可选)指定库是否将空格和标点视为基本字符以进行比较。 |
| (可选)指定当 |
| (可选)指定包含变音符号的字符串是否从后往前排序。数据类型: |
要学习;了解有关排序规则和每个字段可能值的更多信息,请参阅MongoDB Server手册中的排序规则条目。
更多信息
要了解有关变更流的更多信息,请参阅Change Streams MongoDB Server手册中的 。
API 文档
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: