$changeStreamSplitLargeEvent(集計)
定義
MongoDB 7.0(および 6.0.9)の新機能。
の変更ストリームに16 MB を超える大きなイベントがある場合、 BSONObjectTooLarge
例外が返されます。 MongoDB 7.0以降(および6.0.9 )、 イベントを小さなフラグメントに分割するには、 $changeStreamSplitLargeEvent
ステージを使用します。
$changeStreamSplitLargeEvent
は、厳密に必要な場合にのみ使用してください。 たとえば、アプリケーションで完全なドキュメントの変更前または変更後のイメージが必要で、 16 MB を超える大規模なイベントが生成される場合は、 $changeStreamSplitLargeEvent
を使用します。
$changeStreamSplitLargeEvent
を使用する前に、まず 変更イベント のサイズを小さくしてみてください。 例:
アプリケーションで必要な場合を除き、ドキュメントの変更前または変更後のイメージをリクエストしないでください。 これにより、通常、変更イベントにおける最大のオブジェクトである
fullDocument
フィールドとfullDocumentBeforeChange
フィールドが生成されることが増えます。アプリケーションに必要なフィールドのみを含めるには、
$project
ステージを使用します。 これにより、変更イベントのサイズが縮小され、大規模なイベントをフラグメントに分割するための追加時間が回避されます。 これにより、各バッチで返される変更イベントが増えます。
パイプラインには$changeStreamSplitLargeEvent
ステージが 1 つだけあり、最後のステージである必要があります。 $changeStreamSplitLargeEvent
は$changeStream
パイプラインでのみ使用できます。
$changeStreamSplitLargeEvent
構文:
{ $changeStreamSplitLargeEvent: {} }
動作
$changeStreamSplitLargeEvent
16 MB を超えるイベントをフラグメントに分割し、変更ストリーム カーソルを使用してフラグメントを順番に返します。
フラグメントは、最初のフラグメントで最大数のフィールドが返されるように分割されます。 これにより、イベント コンテキストができるだけ早く返されるようになります。
変更イベントが分割される場合、最上位のフィールドのサイズのみが使用されます。 $changeStreamSplitLargeEvent
はサブドキュメントを再帰的に処理または分割しません。 たとえば、 $project
ステージを使用して、サイズが20 MB の 1 つのフィールドを持つ変更イベントを作成すると、イベントは分割されず、 ステージはエラーを返します。
各フラグメントには再開トークンがあります。 フラグメントのトークンを使用して再開されたストリームは、次のいずれかになります。
後続のフラグメントから新しいストリームを開始します。
シーケンスの最後のフラグメントから再開する場合は、次のイベントから開始します。
イベントの各フラグメントにはsplitEvent
ドキュメントが含まれます。
splitEvent: { fragment: <int>, of: <int> }
以下の表で、フィールドを説明します。
フィールド | 説明 |
---|---|
fragment | フラグメント インデックスは、 1から提供されます。 |
of | イベントのフラグメントの合計数。 |
例
このセクションのサンプルシナリオでは、 myCollection
という名前の新しいコレクションを持つ$changeStreamSplitLargeEvent
の使用を示します。
myCollection
を作成し、 16 MB 未満のデータを含むドキュメントを 1 つ挿入します。
db.myCollection.insertOne( { _id: 0, largeField: "a".repeat( 16 * 1024 * 1024 - 1024 ) } )
largeField
反復文字a
が含まれています。
myCollection
に対してchangeStreamPreAndPostImagesを有効にします。これにより、変更ストリームは更新前(イメージ前)と更新後(イメージ後)のドキュメントを取得できます。
db.runCommand( { collMod: "myCollection", changeStreamPreAndPostImages: { enabled: true } } )
db.collection.watch()
を使用して、 myCollection
への変更を監視するための変更ストリーム カーソルを作成します。
myChangeStreamCursor = db.myCollection.watch( [ { $changeStreamSplitLargeEvent: {} } ], { fullDocument: "required", fullDocumentBeforeChange: "required" } )
変更ストリーム イベント の場合、
fullDocument: "required"
には、ドキュメントの変更後のイメージが含まれます。fullDocumentBeforeChange: "required"
には、ドキュメントの変更前のイメージが含まれます。
詳細については、$changeStream
を参照してください。
myCollection
でドキュメントを更新します。これにより、ドキュメントの変更前と変更後のイメージを含む 変更ストリーム イベント も生成されます。
db.myCollection.updateOne( { _id: 0 }, { $set: { largeField: "b".repeat( 16 * 1024 * 1024 - 1024 ) } } )
largeField
に繰り返しの文字b
が含まれるようになりました。
next()
メソッドを使用してmyChangeStreamCursor
からフラグメントを取得し、そのフラグメントをfirstFragment
、 secondFragment
、 thirdFragment
という名前のオブジェクトに保存します。
const firstFragment = myChangeStreamCursor.next() const secondFragment = myChangeStreamCursor.next() const thirdFragment = myChangeStreamCursor.next()
firstFragment.splitEvent
表示:
firstFragment.splitEvent
フラグメントの詳細を含む出力は次のようになります。
splitEvent: { fragment: 1, of: 3 }
同様に、 secondFragment.splitEvent
とthirdFragment.splitEvent
も次を返します。
splitEvent: { fragment: 2, of: 3 } splitEvent: { fragment: 3, of: 3 }
firstFragment
のオブジェクトキーを調べるには、次の手順に従います。
Object.keys( firstFragment )
出力:
[ '_id', 'splitEvent', 'wallTime', 'clusterTime', 'operationType', 'documentKey', 'ns', 'fullDocument' ]
firstFragment.fullDocument
のサイズをバイト単位で調べるには次のようにします。
bsonsize( firstFragment.fullDocument )
出力:
16776223
secondFragment
には、サイズが約 16 MB のfullDocumentBeforeChange
変更前のイメージが含まれています。 次の例は、 secondFragment
のオブジェクトキーを示しています。
Object.keys( secondFragment )
出力:
[ '_id', 'splitEvent', 'fullDocumentBeforeChange' ]
thirdFragment
には、サイズが約 16 MB のupdateDescription
フィールドが含まれています。 次の例は、 thirdFragment
のオブジェクトキーを示しています。
Object.keys( thirdFragment )
出力:
[ '_id', 'splitEvent', 'updateDescription' ]
変更ストリームと変更イベントの詳細については、「変更イベント 」を参照してください。