データベース Triggers
項目一覧
データベースTriggersを使用すると、リンクされた MongoDB Atlas クラスターでデータベースが変更されるたびに、サーバー側のロジックを実行できます。 個々のコレクション、データベース全体、およびクラスター全体に対して Triggers を構成できます。
データベース サーバーで実行される SQL データ Triggers とは異なり、Triggers はデータベース サーバーとは独立してスケーリングするサーバーレス コンピューティング層で実行されます。Triggers は自動的に Atlas Functions を呼び出し、AWS EventBridge を介してイベントを外部ハンドラーに転送できます。
データベース Triggers を使用して、イベント駆動型のデータ インタラクションを実装します。たとえば、関連するドキュメントが変更されたときに 1 つのドキュメントの情報を自動的に更新したり、新しいドキュメントが挿入されるたびに外部サービスにリクエストを送信したりできます。
データベース Triggers は、MongoDB の変更ストリームを使用して、コレクション内のリアルタイムの変更を監視します。変更ストリームは、コレクション内のドキュメントに対する操作をそれぞれ記述する、一連のデータベースイベントです。アプリは、コレクションで作成されたデータベーストリガーごとに新しい変更ストリームを開きます。
重要
ストリームの制限の変更
クラスターで開くことができる変更ストリームの総数には、クラスターのサイズに応じて制限があります。詳細については、「変更ストリームの制限」を参照してください。
サーバーレスインスタンスまたはフェデレーティッドデータベースインスタンスは変更ストリームをサポートしていないため、データベーストリガーを定義することはできません。
trigger を起動する操作と、trigger が起動したときに何が起こるかを制御します。たとえば、ドキュメントの特定のフィールドが更新されるたびに関数を実行できます。この関数は変更イベント全体にアクセスできるため、何が変更されたかを常に把握できます。変更イベントを AWS EventBridge に渡して、Atlas の外部でイベントを取り扱うこともできます。
Atlas Triggers は、変更イベントをフィルタリングするための $match 式と、各イベントに含まれるデータを制限するための $project 式をサポートします。
警告
配置レベルおよびデータベース レベルの Triggers では、他の Triggers を起動して再帰を引き起こすような Triggers を構成することができます。たとえば、同じデータベース内のコレクションに書込むデータベース レベルの Triggers、同じクラスター内の別のデータベースにログを書込むクラスター レベルのロガーまたはログ フォワーダーなどがあります。
データベーストリガーを作成する
App Services UI でデータベース トリガー構成画面を開くには、左側のナビゲーション メニューで Triggers をクリックし、Create a Trigger をクリックして、Trigger Type の横にあるDatabase タブをクリックします。
triggerを構成し、ページの下部にあるSaveをクリックして、現在の配置ドラフトに追加します。
App Services CLI を使用してデータベーストリガーを作成する方法は、次のとおりです。
注意
Atlas App Services は、trigger 構成ファイルに特定のファイル名を強制しません。ただし、インポートされると、Atlas App Services は、定義する trigger の名前と一致するように各構成ファイルの名前を変更します(たとえば、mytrigger.json
)。
構成
データベース Triggers には、次の構成オプションがあります。
trigger の詳細
Trigger Details のセクションでは、まずTrigger Type をクリックします。データベース トリガーの場合、この値を Database に設定します。
次に、必要な粒度のレベルに基づいて、Watch Against をクリックします。選択肢は次のとおりです。
Collection、指定されたコレクションで変更が発生した場合
Database、指定されたデータベース内で任意のコレクションに変更が発生した場合
Deployment、指定されたクラスターで配置の変更が発生した場合。ソース タイプに「配置」を選択している場合、以下のデータベースは変更について監視されません。
管理データベース
admin
、local
、およびconfig
同期データベースの
__realm_sync
と__realm_sync_<app_id>
重要
配置レベルのソース タイプは、専用階層でのみ使用できます。
使用しているソース タイプに応じて、追加オプションは異なります。次の表で、これらのオプションについて説明します。
ソース タイプ | オプション |
---|---|
Collection |
|
Database |
|
Deployment |
|
Tip
プレイメージとパフォーマンスの最適化
プレイメージには、パフォーマンスに影響する可能性のある追加のストレージ オーバーヘッドが必要です。コレクションでプレイメージを使用していない場合は、プレイメージを無効にする必要があります。詳細については、「コレクション レベルのプレイメージの無効化」を参照してください。
ドキュメントのプレイメージは、MongoDB 4.4 以降を実行しているシャーディングされていない Atlas クラスターと、MongoDB 5.3 以降を実行しているシャーディングされた Atlas クラスターでサポートされています。クラスターが MongoDB 5.3 以降を実行している限り、(プレイメージを含め)シャーディングされていないクラスターをシャーディングされたクラスターにアップグレードできます。
トリガー構成
フィールド | 説明 |
---|---|
Auto-Resume Triggers | 有効な場合、この trigger の再開トークンがクラスターの oplog に見つからない場合、trigger は次の関連する変更ストリーム イベントでイベントの情報処理を自動的に再開します。trigger が一時停止されてから trigger が実行を再開するまでのすべての変更ストリーム イベントでは、trigger は起動しません。 |
Event Ordering | 有効にすると、trigger イベントは発生順に処理されます。無効にすると、イベントは並列処理されるため、多くのイベントが同時に発生した場合の処理速度が向上します。 イベントの順序付けが有効になっている場合、この trigger は変更イベントのタイムスタンプに基づいて順番に複数回実行されます。イベントの順序付けが無効になっている場合、この trigger の複数回の実行は独立して発生します。 |
Skip Events On Re-Enable | デフォルトで無効です。有効にすると、この trigger が無効になっている間に発生した変更イベントは処理されません。 |
eventType
Event Type セクションで、trigger が起動したときに実行されるアクションを選択します。関数を実行するか、AWS EventBridge を使用するかを選択できます。
高度な
Advanced セクションでは、次の任意の構成オプションを使用できます。
フィールド | 説明 | ||||||||
---|---|---|---|---|---|---|---|---|---|
Project Expression | 変更ストリーム内の各イベントからフィールドのサブセットを選択する $project 式。これを使用して、trigger の実行を最適化できます。 この式は、変更イベント内のフィールド名を、フィールドを除外する(
| ||||||||
Match Expression | Atlas App Services が trigger の起動を引き起こす変更イベントをフィルタリングするために使用する$match式ドキュメント。 trigger は、受け取るすべての変更イベント オブジェクトをこのマッチ式に対して評価し、特定の変更イベントに対して式が 注意埋め込みフィールドにドット表記を使用するMongoDB は、マッチ式内の埋め込みドキュメントに対して完全な等価一致を実行します。 埋め込みドキュメント内の特定のフィールドを一致させる場合は、ドット表記を使用してフィールドを直接参照します。 詳細については、MongoDB サーバー マニュアルの 「埋め込みドキュメントに対するクエリ」 を参照してください。 | ||||||||
Maximum Throughput | リンクされたデータソースが専用サーバー(M10+ 階層)の場合、最大スループットの同時プロセス数をデフォルトの 10,000 よりも増やすことができます。 重要最大スループットを有効にするには、イベント順序を無効にする必要があります。 最大スループットを増加させる前に、1 つ以上の Triggers がレート制限された外部 API を呼び出しているかどうかを考慮してください。Triggers レートを上げると、これらの制限を超える可能性があります。 スループットを増やすと、ワークロードが大きくなり、クラスター全体のパフォーマンスに影響する可能性があります。 |
イベント タイプの変更
データベース変更イベントは、リンクされた MongoDB Atlas クラスターの特定のコレクション内の個々の変更を表します。
すべてのデータベース イベントは、基礎の変更ストリームによって発行された変更イベント オブジェクトと同じ操作タイプと構造を持ちます。変更イベントには、次の操作タイプがあります。
操作タイプ | 説明 |
---|---|
ドキュメントの挿入(すべての trigger タイプ) | コレクションに追加された新しいドキュメントを表します。 |
ドキュメントの更新(すべての trigger タイプ) | コレクション内の既存のドキュメントに対する変更を表します。 |
ドキュメントの削除(すべての trigger タイプ) | コレクションから削除されたドキュメントを表します。 |
ドキュメントの置換(すべての trigger タイプ) | コレクション内のドキュメントと置き換えられた新しいドキュメントを表します。 |
コレクションの作成(データベースと配置の trigger タイプのみ) | 新しいコレクションの作成を表します。 |
コレクションの変更(データベースと配置の trigger タイプのみ) | 変更コレクションを表します。 |
コレクションの名前変更(データベースと配置の trigger タイプのみ) | 名前が変更されるコレクションを表します。 |
コレクションの削除(データベースと配置の trigger タイプのみ) | 削除されるコレクションを表します。 |
コレクションのシャーディング(データベースと配置の trigger タイプのみ) | シャーディングされていない状態からシャーディングされた状態に変化するコレクションを表します。 |
コレクションの再シャーディング(データベースと配置の trigger タイプのみ) | コレクションのシャーディングに対する変更を表します。 |
コレクションのシャードキーの調整(データベースと配置の trigger タイプのみ) | コレクションのシャードキーの変更を表します。 |
インデックスの作成(データベースと配置の trigger タイプのみ) | 新しいインデックスの作成を表します。 |
インデックスの削除(データベースと配置の trigger タイプのみ) | 削除されるインデックスを表します。 |
データベースの削除(配置 trigger タイプのみ) | 削除されるデータベースを表します。 |
データベース変更イベント オブジェクトの一般的な形式は次のとおりです。
{ _id : <ObjectId>, "operationType": <string>, "fullDocument": <document>, "fullDocumentBeforeChange": <document>, "ns": { "db" : <string>, "coll" : <string> }, "documentKey": { "_id": <ObjectId> }, "updateDescription": <document>, "clusterTime": <Timestamp> }
データベーストリガーの例
あるオンラインショップが、注文の場所が変わるたびに顧客に通知したいと考えています。store.orders
コレクション内の各注文は、次のようなドキュメントとして記録されます。
{ _id: ObjectId("59cf1860a95168b8f685e378"), customerId: ObjectId("59cf17e1a95168b8f685e377"), orderDate: ISODate("2018-06-26T16:20:42.313Z"), shipDate: ISODate("2018-06-27T08:20:23.311Z"), orderContents: [ { qty: 1, name: "Earl Grey Tea Bags - 100ct", price: NumberDecimal("10.99") } ], shippingLocation: [ { location: "Memphis", time: ISODate("2018-06-27T18:22:33.243Z") }, ] }
このプロセスを自動化するために、このショップは store.orders
コレクション内の更新変更イベントをリッスンするデータベーストリガーを作成します。trigger が更新イベントを観察すると、変更イベント オブジェクトが関連付けられた関数、textShippingUpdate
に渡されます。この関数は、変更イベントで shippingLocation
フィールドに変更がないかチェックし、更新されている場合は、注文の新しい場所を記載したテキスト メッセージを顧客に送信します。
{ "type": "DATABASE", "name": "shippingLocationUpdater", "function_name": "textShippingUpdate", "config": { "service_name": "mongodb-atlas", "database": "store", "collection": "orders", "operation_types": ["UPDATE"], "unordered": false, "full_document": true, "match": {} }, "disabled": false }
exports = async function (changeEvent) { // Destructure out fields from the change stream event object const { updateDescription, fullDocument } = changeEvent; // Check if the shippingLocation field was updated const updatedFields = Object.keys(updateDescription.updatedFields); const isNewLocation = updatedFields.some(field => field.match(/shippingLocation/) ); // If the location changed, text the customer the updated location. if (isNewLocation) { const { customerId, shippingLocation } = fullDocument; const mongodb = context.services.get("mongodb-atlas"); const customers = mongodb.db("store").collection("customers"); const { location } = shippingLocation.pop(); const customer = await customers.findOne({ _id: customerId }); const twilio = require('twilio')( // Your Account SID and Auth Token from the Twilio console: context.values.get("TwilioAccountSID"), context.values.get("TwilioAuthToken"), ); await twilio.messages.create({ To: customer.phoneNumber, From: context.values.get("ourPhoneNumber"), Body: `Your order has moved! The new location is ${location}.` }) } };
一時停止された Triggers
データベース Triggers は、Triggers の変更ストリームの継続を妨げるイベントに応答して一時停止状態になることがあります。Triggers を一時停止できるイベントには、次のものがあります。
dropDatabase
やrenameCollection
など、ネットワークの中断によって発生したイベントを無効化します。変更ストリームを再開するのに必要な再開トークンは、もはやクラスターの oplog に存在しなくなります。アプリ ログでは、これを
ChangeStreamHistoryLost
エラーとして扱います。
trigger が一時停止または失敗した場合、Atlas App Services はプロジェクト オーナーに問題を警告するメールを送信します。
一時停止された trigger を自動的に再開する
再開トークンが oplog にないために trigger が一時停止された場合に、自動的に再開するように trigger を構成できます。trigger は、再開トークンが失われてから再開プロセスが完了するまでの間、見逃した変更ストリーム イベントを処理しません。
App Services UI でデータベーストリガーを作成または更新するときは、中断された場合に自動的に再開するトリガーの構成ページに移動します。
Advanced (Optional)セクションで、[Auto-Resume Triggers] を選択します。
変更を保存して配置します。
Realm CLI を使用してデータベーストリガーをアップデートまたは作成する場合は、一時停止した場合に自動的に再開するトリガーの構成ファイルを作成するか、その構成ファイルに移動します。
trigger の設定ファイルに、以下を含めます。
{ "name": "<Trigger Name>", "type": "DATABASE", "config": { "tolerate_resume_errors": true, // ...rest of Database Trigger configuration }, // ...rest of Trigger general configuration }
次のコマンドを使用して変更を実施します。
appservices push --remote=<App ID>
一時停止された trigger を手動で再開する
一時停止した trigger を手動で再開すると、アプリは、変更ストリームが停止した後の次の変更ストリーム イベントで trigger を再開しようとします。再開トークンがクラスター oplog にない場合は、trigger は再開トークンなしで起動する必要があります。これは、trigger が新しいイベントのリッスンを開始するが、見逃した過去のイベントは処理しないことを意味します。
一時停止後も再開トークンをより長く保持するように oplog サイズを調整するには、Atlas クラスターをスケーリングします。oplog のサイズをクラスターのピーク oplog スループット(GB/時)の数倍に維持して、一時停止された trigger の再開トークンが trigger が実行される前に oplog からドロップされるリスクを減らします。クラスターの oplog スループットは、Atlas クラスター メトリクスの Oplog GB/時間グラフで表示します。
一時停止された trigger は、App Services UI から、または App Services CLI を使用してアプリケーション ディレクトリをインポートすることで再起動することができます。
トリガーを再起動する
トリガーのActions列の [Restart] をクリックする。変更ストリーム再開トークンを使用して trigger を再開するか、新しい変更ストリームを開くかを選択できます。再開トークンを使用するかどうかを指定して、 [Resume Database Trigger] をクリックします。
注意
再開トークン
再開トークンを使用する場合、App Services は、処理した最後の変更イベントの直後のイベントで、trigger の基になる変更ストリームを再開しようとします。成功した場合、trigger は中断中に発生したイベントを処理します。再開トークンを使用しない場合、trigger は新しいイベントのリスニングを開始しますが、中断中に発生したイベントについては起動しません。
trigger 構成ファイルが存在することを確認します
アプリケーションの新しいコピーをエクスポートした場合は、中断された trigger の最新の設定ファイルがすでに含まれているはずです。trigger と同じ名前のtrigger 構成ファイルを/triggers
ディレクトリで探すことで、構成ファイルが存在することを確認できます。
trigger 時間レポート作成
Atlas App Services UI の Triggers のリストには、次の 3 つのタイムスタンプが表示されます。
最終更新日
trigger が作成された時間、または直近で変更された時間です。
最新のハートビート
Atlas App Services は、trigger が最後に実行された時刻を追跡します。trigger がイベントを送信していない場合、サーバーはハートビートを送信して、trigger の再開トークンが最新の状態に保たれるようにします。最新のイベントが Latest Heartbeat として表示されます。
最後に処理されたクラスター時間
Atlas App Services は、trigger をサポートする変更ストリームがイベントを発行した最後の時刻である Last Cluster Time Processed も追跡します。最新のハートビート以降にイベントが発生していない場合は、Latest Heartbeat よりも前の時間になります。
パフォーマンスの最適化
バースト操作のイベント順序の無効化
短時間のイベントを受け取るコレクションで trigger が起動する場合は、イベント順序を無効にすることを検討してください(日次バッチ ジョブの一部としてデータを挿入するなど)。
順序付けされている Triggers は、前のイベントの関数の実行が終了するまで、特定のイベントの関数の実行を待ちます。結果として、順序付けされている Triggers は、連続的な各 Triggers 関数の実行時間によって実質的にレート制限されます。これにより、変更ストリームにデータベース イベントが表示されてから Triggers が起動するまでに大幅な遅延が発生する可能性があります。極端な場合、データベース イベントは、実行中の順序付けされた Triggers が処理する前に oplog から削除されることがあります。
順序づけされていない Triggers は、可能な場合は関数を並列に実行するため、(ユースケースによっては)大幅に高速になる可能性がありますが、Trigger 関数の複数の実行がイベント順に発生することを保証するものではありません。
コレクション レベルのプレイメージの無効化
ドキュメント プレイメージでは、クラスターがコレクションの各操作に関する追加データをレコードする必要があります。コレクションの任意の trigger でプレイメージを有効にすると、クラスターはコレクションに対するすべての操作のプレイメージを保存します。
追加のストレージとコンピューティングのオーバーヘッドにより、クラスターの構成によっては、trigger のパフォーマンスが低下する可能性があります。
プレイメージのストレージとコンピューティングのオーバーヘッドを回避するには、基礎の MongoDB コレクション全体のプレイメージを無効にする必要があります。これは、個々の trigger のプレイメージ設定とは別の設定です。
コレクション レベルのプレイメージを無効にすると、そのコレクションのアクティブな Triggers はプレイメージを使用できなくなります。ただし、コレクションのすべてのプリイメージ Triggers を削除または無効にすると、コレクション レベルのプレイメージも無効にできます。
方法については、「コレクションのプレイメージの無効化」を参照してください。
一致式を使用した trigger 呼び出しの制限
trigger の呼び出し回数を制限するには、Match Expression フィールドに $match 式を指定します。App Services は、変更イベント ドキュメントに対してマッチ式を評価し、特定の変更イベントに対して式が true と評価された場合にのみ trigger を呼び出します。
マッチ式は、MongoDB 読み取りクエリ構文を使用してクエリ条件を指定する JSON ドキュメントです。
マッチ式は、trigger イベントの量が明らかにパフォーマンスの問題になる場合にのみ使用することをお勧めします。それまでは、すべてのイベントを受け取り、trigger 関数コードで個別に取り扱います。
変更イベント ドキュメントの正確な形状は、トリガーの起動の原因となったイベントによって異なります。詳細については、各イベント タイプのリファレンスを参照してください。
例
次のマッチ式を使用すると、変更イベント オブジェクトで、ドキュメントの status
フィールドが変更されたことが指定されている場合にのみ trigger を起動できます。
updateDescription
は、更新イベント オブジェクトのフィールドです。
{ "updateDescription.updatedFields.status": { "$exists": true } }
次のマッチ式を使用すると、ドキュメントの needsTriggerResponse
フィールドが true
の場合にのみ trigger を起動できます。挿入、更新、置換イベントの fullDocument
フィールドは、指定された操作後のドキュメントを表します。fullDocument
フィールドを受信するには、trigger 構成で Full Document を有効にする必要があります。
{ "fullDocument.needsTriggerResponse": true }
マッチ式のテスト
次の手順は、マッチ式が期待通りに機能するかどうかをテストする方法の 1 つです。
MongoDB Shell(mongosh)をダウンロードして、クラスターへの接続に使用します。
データベース名を
DB_NAME
、コレクション名をCOLLECTION_NAME
、テスト対象のマッチ式をYOUR_MATCH_EXPRESSION
に置き換え、以下を mongosh に貼り付けて、既存のコレクションの変更ストリームを開きます。db.getSiblingDB(DB_NAME).COLLECTION_NAME.watch([{$match: YOUR_MATCH_EXPRESSION}]) while (!watchCursor.isClosed()) { if (watchCursor.hasNext()) { print(tojson(watchCursor.next())); } } 別のターミナル ウィンドウで、mongosh を使用して、コレクション内の一部のテスト ドキュメントに変更を加えます。
変更ストリームがフィルタリングして何を含め、何を除外するかを観察します。
プロジェクト式を使用した入力データ サイズの縮小
Project Expression フィールドでは、$project 式を使用して、trigger が処理するフィールドの数を制限します。
注意
プロジェクトは包括的のみ
trigger を使用する場合、プロジェクション式は包括的のみになります。プロジェクトは、包括的と排他的の混在をサポートしません。trigger では operationType
を含める必要があるため、プロジェクト式は包括的である必要があります。
1 つのフィールドを除外する場合、プロジェクション式には除外するフィールドを除くすべてのフィールドを含める必要があります。明示的に除外できるのは、デフォルトで含まれている _id
のみです。
例
trigger は、次の Project Expression で構成されます。
{ "_id": 0, "operationType": 1, "updateDescription.updatedFields.status": 1 }
Atlas App Services が trigger 関数に渡す変更イベント オブジェクトには、次の例のように、プロジェクションで指定されたフィールドのみが含まれます。
{ "operationType": "update", "updateDescription": { "updatedFields": { "status": "InProgress" } } }
その他の例
App Services App に統合された trigger の追加例については、 Githubの Triggers の例を確認してください。