AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。

Change Streams によるデータの監視

このガイドでは、変更ストリームを使用してデータベースへのリアルタイムの変更を監視する方法を学習できます。 変更ストリームは、アプリケーションがコレクション、データベース、または配置のデータ変更をサブスクライブできる MongoDB Server の機能です。

Tip

Atlas Stream Processing

変更ストリームの代わりに、Atlas Stream Processing を使用してデータのストリームを処理および変換できます。データベースイベントのみを登録する変更ストリームとは異なり、Atlas Stream Processing は複数のデータイベント型を管理し、拡張データプロセシング機能を提供します。この機能の詳細については、 MongoDB AtlasドキュメントのAtlas Stream Processingを参照してください。

次のオブジェクトのwatch()メソッドを使用して、MongoDB の変更を監視できます。

各オブジェクトに対して、 watch()メソッドは変更ストリームを開き、変更が発生したときに変更イベントドキュメントを発行します。

オプションとして、watch() メソッドは複数の集約ステージの配列で構成される集約パイプラインを最初のパラメーターとして取ることができます。集計ステージでは、変更イベントをフィルタリングして変換します。

次のスニペットでは、$match ステージで runtime の値が 15 未満のすべての変更イベントドキュメントが照合され、その他のドキュメントがすべて除外されます。

const pipeline = [ { $match: { runtime: { $lt: 15 } } } ];const changeStream = myColl.watch(pipeline);

watch()メソッドは、2 番目のパラメーターとしてoptionsオブジェクトを受け入れます。このオブジェクトで構成できる設定の詳細については、このセクションの最後にあるリンクを参照してください。

watch() メソッドは ChangeStream のインスタンスを返します。変更ストリームを反復処理したり、イベントをリスニングしたりすることで、変更ストリームからイベントを読み取ることができます。

警告

EventEmitter モードと Iterator モードでのChangeStreamの使用は、ドライバーでサポートされていないため、エラーが発生します。これは、ドキュメントを最初に受け取るコンシューマーをドライバー側で保証できない場合の未定義の動作を防ぐためのものです。

変更ストリームからイベントを読み取る方法を示すタブを選択します。

バージョン 4.12 以降、 ChangeStreamオブジェクトは非同期反復可能オブジェクトになります。この変更により、 for-awaitループを使用して、開いている変更ストリームからイベントを取得できるようになります。

for await (const change of changeStream) { console.log("Received change: ", change);}

注意

この例を使ってMongoDBのインスタンスに接続し、サンプルデータを含むデータベースとやり取りできます。MongoDBインスタンスへの接続とサンプルデータセットの読み込みの詳細については、 Node.jsドライバーを使い始める ガイドを参照してください。

注意

Typescript固有の機能はありません

次のコード例ではJavaScriptを使用します。このユースケースに関連するドライバーのTypescript固有の機能はありません。

次の例ではinsertDBデータベースのhaikusコレクションの変更ストリームがオープンされ、変更イベントが発生に応じて出力されます。

// Watch for changes in a collection by using a change streamimport { MongoClient } from "mongodb"; // Replace the uri string with your MongoDB deployment's connection string.const uri = "<connection string uri>"; const client = new MongoClient(uri); // Declare a variable to hold the change streamlet changeStream; // Define an asynchronous function to manage the change streamasync function run() { try { const database = client.db("insertDB"); const haikus = database.collection("haikus"); // Open a Change Stream on the "haikus" collection changeStream = haikus.watch(); // Print change events as they occur for await (const change of changeStream) { console.log("Received change:\n", change); } // Close the change stream when done await changeStream.close(); } finally { // Close the MongoDB client connection await client.close(); }}run().catch(console.dir);

Tip

明示的なリソース管理

Node.jsドライバーは、MongoClient、ClientSession、ChangeStreams、およびカーソルの明示的なリソース管理をネイティブでサポートしています。この機能は実験的なものであり、変更される可能性があります。明示的なリソース管理を使用する方法については、v6.9 リリースノートを参照してください。

このコードを実行してから、挿入または削除操作の実行など、 haikusコレクションに変更を加えると、変更イベント ドキュメントがターミナルに出力されます。

たとえば、コレクションにドキュメントを挿入すると、コードによって次の内容が出力されます。

Received change:{ _id: { _data: '...' }, operationType: 'insert', clusterTime: new Timestamp({ t: 1675800603, i: 31 }), fullDocument: { _id: new ObjectId("..."), ... }, ns: { db: 'insertDB', coll: 'haikus' }, documentKey: { _id: new ObjectId("...") }}

注意

更新から完全なドキュメントを受け取る

アップデート操作に関する情報を含む変更イベントは、デフォルトではアップデートされたドキュメント全体ではなく、変更されたフィールドのみを返します。次のように、オプションオブジェクトの fullDocument フィールドを "updateLookup" に設定することで、ドキュメントの最新バージョンも返すように変更ストリームを設定できます。

const options = { fullDocument: "updateLookup" };// This could be any pipeline.const pipeline = []; const changeStream = myColl.watch(pipeline, options);

次の例では、 insertDBデータベースのhaikusコレクションの変更ストリームを開きます。コレクションで発生する変更イベントを受信して出力するリスナー関数を作成します。

まず、コレクションで変更ストリームを開き、on() メソッドを使用して、変更ストリーム上でリスナーを定義します。リスナーを設定したら、コレクションに対する変更を実行して変更イベントを生成します。

コレクション上で変更イベントを生成するために、insertOne() メソッドを使用して新しいドキュメントを追加します。insertOne() がリスナー関数の登録より先に実行される可能性があるため、simulateAsyncPause と定義したタイマーを使用し、1 秒間待ってから挿入を実行します。

また、ドキュメント挿入後に simulateAsyncPause も使用します。これにより、close() メソッドによって ChangeStream インスタンスが閉じる前に、リスナー関数が変更イベントを受け取って処理を完了するための十分な時間を確保できます。

注意

タイマーを使用する理由

この例で使用されているタイマーは、あくまでもデモンストレーションのためのものです。これにより、リスナーの登録と、終了前のリスナーによる変更イベントの処理に十分な時間を確保できます。

注意

Typescript固有の機能はありません

次のコード例ではJavaScriptを使用します。このユースケースに関連するドライバーのTypescript固有の機能はありません。

/* Change stream listener */ import { MongoClient } from "mongodb"; // Replace the uri string with your MongoDB deployment's connection stringconst uri = "<connection string uri>"; const client = new MongoClient(uri); const simulateAsyncPause = () => new Promise(resolve => { setTimeout(() => resolve(), 1000); }); let changeStream;async function run() { try { const database = client.db("insertDB"); const haikus = database.collection("haikus"); // Open a Change Stream on the "haikus" collection changeStream = haikus.watch(); // Set up a change stream listener when change events are emitted changeStream.on("change", next => { // Print any change event console.log("received a change to the collection: \t", next); }); // Pause before inserting a document await simulateAsyncPause(); // Insert a new document into the collection await myColl.insertOne({ title: "Record of a Shriveled Datum", content: "No bytes, no problem. Just insert a document, in MongoDB", }); // Pause before closing the change stream await simulateAsyncPause(); // Close the change stream and print a message to the console when it is closed await changeStream.close(); console.log("closed the change stream"); } finally { // Close the database connection on completion or error await client.close(); }}run().catch(console.dir);

このページで説明されているクラスとメソッドの詳細については、次のリソースを参照してください。