データベース Triggers
データベースTriggersを使用すると、リンクされた MongoDB Atlas クラスターでデータベースが変更されるたびに、サーバー側のロジックを実行できます。 個々のコレクション、データベース全体、およびクラスター全体に対して trigger を構成できます。
データベースサーバーで実行されるSQLデータトリガーとは異なり、Atlasデータベーストリガーはデータベースサーバーとは独立してスケーリングするサーバーレス コンピューティングレイヤーで実行されます。 trigger は自動的にAtlas Functionsを呼び出し、 Amazon Web Services EventBridge を介してイベントを外部ハンドラーに転送できます。
データベース Triggers を使用して、イベント駆動型のデータ インタラクションを実装します。たとえば、関連するドキュメントが変更されたときに 1 つのドキュメントの情報を自動的に更新したり、新しいドキュメントが挿入されるたびに外部サービスにリクエストを送信したりできます。
データベーストリガーは、 MongoDB 変更ストリームを使用して、コレクション内のリアルタイムの変更を監視します。 変更ストリームは、コレクション内のドキュメントに対する操作をそれぞれ記述する、一連のデータベースイベントです。 アプリは、少なくとも 1 つの trigger が有効になっているコレクションごとに 1 つの変更ストリームを開きます。 コレクションで複数の trigger が有効になっている場合、それらはすべて同じ変更ストリームを共有します。
重要
ストリームの制限の変更
クラスターで開くことができる変更ストリームの総数には、クラスターのサイズに応じて制限があります。 詳細については、「変更ストリームの制限 」を参照してください。
また、trigger サーバーレスインスタンス または フェデレーティッドデータベースインスタンス は変更ストリームをサポートしていないため、データベース を定義することはできません。
どの操作で trigger を起動させるか、また、trigger を起動時に何が起こるかを制御します。 例、ドキュメントの特定のフィールドが更新されるたびに関数を実行できます。 この関数は 変更イベント全体にアクセスできるため、何が変更されたかを常に把握できます。 変更イベントをAWS Eventbridgeに渡して、 Atlasの外部でイベントを取り扱うこともできます。
Atlas Triggers は、変更イベントをフィルタリングするための $match 式と、各イベントに含まれるデータを制限するための $project 式をサポートします。
警告
配置レベルおよびデータベース レベルの Triggers では、他の Triggers を起動して再帰を引き起こすような Triggers を構成することができます。たとえば、同じデータベース内のコレクションに書込むデータベース レベルの Triggers、同じクラスター内の別のデータベースにログを書込むクラスター レベルのロガーまたはログ フォワーダーなどがあります。
データベーストリガーを作成する
データベースtriggerは、 Atlas UIまたはApp Services CLIを使用して作成できます。
Triggersページに移動する
まだ表示されていない場合は、プロジェクトを含む組織をナビゲーション バーの Organizations メニューで選択します。
まだ表示されていない場合は、ナビゲーション バーの Projects メニューからプロジェクトを選択します。
サイドバーで、 Services見出しの下のTriggersをクリックします。
Triggersページが表示されます。
Add Triggerをクリックしてトリガー設定ページを開きます。
Database trigger のタイプを選択します。
trigger を設定し、 [ Save ] をクリックします。
MongoDB Atlasユーザーを認証します。
MongoDB Atlas Administration APIキーを使用して、App Services CLI にログします。
appservices login --api-key="<API KEY>" --private-api-key="<PRIVATE KEY>" アプリの最新の構成ファイルを取得します。
次のコマンドを実行して、構成ファイルのローカルコピーを取得します。
appservices pull --remote=<App ID> デフォルトでは 、コマンドは現在の 作業ディレクトリにファイルをプルします。 任意の
--local
フラグを使用してディレクトリパスを指定できます。ローカルアプリファイルの
triggers
サブディレクトリにデータベースtrigger構成ファイルを追加します。変更を配置します。
次のコマンドを実行して、変更を配置します。
appservices push
注意
Atlas は trigger 構成ファイルに特定のファイル名を強制しません。 ただし、インポートされると、Atlas は、定義する trigger の名前と一致するように各構成ファイルの名前を変更します。
構成
データベース Triggers には、次の構成オプションがあります。
trigger の詳細
Trigger Detailsセクション内で、必要な粒度のレベルに基づいて、trigger が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 | 有効な場合、この trigger の再開トークンがクラスターのoplogに見つからない場合、trigger は次の関連する変更ストリームイベントでイベントの情報処理を自動的に再開します。 trigger が一時停止されてから trigger が実行を再開するまでのすべての変更ストリームイベントでは、trigger は起動しません。 |
Event Ordering | 有効にすると、trigger イベントは発生順に処理されます。無効にすると、イベントは並列処理されるため、多くのイベントが同時に発生した場合の処理速度が向上します。 イベントの順序付けが有効になっている場合、この trigger は変更イベントのタイムスタンプに基づいて順番に複数回実行されます。イベントの順序付けが無効になっている場合、この trigger の複数回の実行は独立して発生します。 ヒント:データベースの一括操作に応答する Atlas Triggers のパフォーマンスを向上させるには、イベントの順序付けを無効にします。 |
Skip Events On Re-Enable | デフォルトで無効です。有効にすると、この trigger が無効になっている間に発生した変更イベントは処理されません。 |
eventType
Event Type セクションで、trigger が起動したときに実行されるアクションを選択します。関数を実行するか、 AWS EventBridge を使用するかを選択できます。
高度な
Advanced セクションでは、次の任意の構成オプションを使用できます。
フィールド | 説明 | ||||||||
---|---|---|---|---|---|---|---|---|---|
Project Expression | 変更ストリーム内の各イベントからフィールドのサブセットを選択する $project 式。これを使用して、trigger の実行を最適化できます。 この式は、変更イベント内のフィールド名を、フィールドを除外する(
| ||||||||
Match Expression | Atlas が trigger を起動させる変更イベントをフィルタリングするために使用する$match式ドキュメント。 trigger は、受け取るすべての変更イベントオブジェクトをこのマッチ式に対して評価し、特定の 変更イベントに対して式が MongoDB は、マッチ式内の埋め込みドキュメントに対して完全な等価一致を実行します。 埋め込みドキュメント内の特定のフィールドを一致させる場合は、ドット表記を使用してフィールドを直接参照します。 詳細については、MongoDB サーバー マニュアルの 「埋め込みドキュメントに対するクエリ」 を参照してください。 パフォーマンスを最適化するには、 $match式を使用して trigger が処理するフィールドの数を制限します。 詳細はこちら。 | ||||||||
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
コレクション内の Update
変更イベントをリッスンするデータベースtriggerを作成します。 trigger はUpdate
イベントを観察すると、変更イベントオブジェクトを関連付けられた関数である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 はプロジェクトオーナーに問題を警告するメールを送信します。
一時停止された trigger を自動的に再開する
再開トークンが oplog にないために trigger が一時停止された場合に、自動的に再開するように trigger を構成できます。trigger は、再開トークンが失われてから再開プロセスが完了するまでの間、見逃した変更ストリーム イベントを処理しません。
UIで データベース を作成または更新 するtrigger 場合:Atlas
中断された場合に自動的に再開する trigger の構成ページに移動します。
Advanced (Optional)セクションで、[Auto-Resume Triggers] を選択します。
変更を保存して配置します。
一時停止された trigger を手動で再開する
一時停止した trigger を手動で再開すると、アプリは、変更ストリームが停止した後の次の変更ストリーム イベントで trigger を再開しようとします。再開トークンがクラスター oplog にない場合は、trigger は再開トークンなしで起動する必要があります。これは、trigger が新しいイベントのリッスンを開始するが、見逃した過去のイベントは処理しないことを意味します。
|service| をスケーリングする ことで、停止後に再開トークンをより長く保持するためにoplogのサイズを調整することができます。 クラスター 。oplogのサイズをクラスターのピークoplogスループット(GB/時)の数倍に維持して、一時停止された trigger の再開トークンが trigger が実行される前にoplogからドロップされるリスクを減らします。 クラスターのoplog スループットは、 |service| のoplogGB /時間 のグラフで表示します。 クラスター メトリクス。
一時停止した trigger は、Atlas UIまたは App Services CLI を使用して再起動できます。
AtlasTriggers で、プロジェクトの ページに移動します。
まだ表示されていない場合は、プロジェクトを含む組織をナビゲーション バーの Organizations メニューで選択します。
まだ表示されていない場合は、ナビゲーション バーの Projects メニューからプロジェクトを選択します。
サイドバーで、 Services見出しの下のTriggersをクリックします。
Triggersページが表示されます。
トリガーを再起動する
トリガーのActions列の [Restart] をクリックする。 変更ストリーム再開トークンを使用して trigger を再開するか、新しい変更ストリームを開くかを選択できます。
再開トークンを使用するかどうかを指定して、 [ Resume Database Trigger ] をクリックします。
注:再開トークンを 使用する場合、Atlas は、処理した最後の変更イベントの直後のイベントで、trigger の基になる変更ストリームを再開しようとします。 成功した場合、trigger は中断中に発生したイベントを処理します。 再開トークンを使用しない場合、trigger は新しいイベントのリスニングを開始しますが、中断中に発生したイベントについては起動しません。
MongoDB Atlas ユーザーの認証
MongoDB Atlas Administration APIキーを使用して、App Services CLI にログします。
appservices login --api-key="<API KEY>" --private-api-key="<PRIVATE KEY>"
trigger 構成ファイルが存在することを確認
アプリケーションの新しいコピーをエクスポートした 場合は、中断された trigger の最新の構成ファイルがすでに含まれているはずです。 trigger と同じ名前のtrigger構成ファイルを/triggers
ディレクトリで探すことで、構成ファイルが存在することを確認できます。
trigger 時間レポート作成
Atlas UIの Triggers のリストには、次の 3 つのタイムスタンプが表示されます。
最終更新日
trigger が作成された時間、または直近で変更された時間です。
最新のハートビート
Atlas は、trigger が最後に実行された時刻を追跡します。 trigger がイベントを送信していない場合、サーバーはハートビートを送信して、trigger の再開トークンが最新の状態に保たれるようにします。 最新のイベントがLatest Heartbeatとして表示されます。
最後に処理されたクラスター時間
Atlas は、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式を指定します。 Atlas は、変更イベントドキュメントに対してマッチ式を評価し、特定の 変更イベントに対して式が 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 つです。
データベース名を
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 が trigger 関数に渡す変更イベントオブジェクトには、次の例のように、プロジェクションで指定されたフィールドのみが含まれます。
{ "operationType": "update", "updateDescription": { "updatedFields": { "status": "InProgress" } } }