定義
$sample入力ドキュメントから指定された数のドキュメントをランダムに選択します。
$sampleステージ構文:{ $sample: { size: <positive integer N> } } Nは、ランダムに選択するドキュメントの数です。Nを1以上の整数に設定します。
動作
疑似ランダム カーソルの動作
次の条件が すべて 当てはまる場合、 $sampleは疑似ランダム カーソルを使用してNドキュメントを選択します。
$sampleは、パイプラインの第一ステージです。Nは、コレクション内の全ドキュメントの 5% 未満です。注意
$sampleがコレクション全体をスキャンするタイミングを決定するために使用するしきい値を構成することはできません。しきい値は5 % です。サイズがコレクション内のドキュメントの合計数の5 % を超える場合、$sampleは生成されたランダム値でTop-k ソートを実行します。サンプルドキュメントが100 MB を超えると、Top-k ソートがディスクにスピルする可能性があります。このコレクションには 100 を超えるドキュメントが含まれています。
疑似ランダム カーソルは、 一意のランダムサンプルを保証するものでは ありません 。コレクション内部のB木構造をランダムに降順で降順に並べ替えてドキュメントを選択するため、結果はコレクションの一部に提供されます。以下の場合、SKU である可能性が高くなります。
コレクション内のドキュメントが均等に分散されていないため、ツリー構造のバランスが取れていません。
コレクションには多数の削除されたドキュメントがあります。
多数のドキュメントは、カーソルのトランザクションには表示されません。
ユースケースで均一サンプルが必要な場合は、疑似ランダム カーソルを回避します。そのためには、別のステージの後に$sample N5を実行するか、コレクション内のドキュメントの % 以上に を設定します。
ランダムソートの動作
以前の条件のいずれかが false の場合、 $sampleは次のようになります。
先行する集計ステージまたはコレクション スキャンから出力されるすべてのドキュメントを読み取ります。
ランダムな並べ替えを実行して、
Nドキュメントを選択します。 ランダムソートには、ソートメモリ制限 が適用されます。注意
ビューは、 集計パイプライン の結果です。 ビューで
$sampleを使用すると、MongoDB は ステージをビューの集計パイプライン構文の末尾に追加します。 したがって、ビューの$sampleステージは最初のステージではなく、常にコレクションスキャンが行われます。
シャーディングされたクラスター
シャーディングされたクラスターで $sample を使用すると、各シャードは個別にサンプル操作を実行します。mongos は、各シャードのサンプル操作をマージした結果をサンプリングし、要求された数のドキュメントを返します。
例
このセクションでは、次のusersコレクションを使用する集計パイプラインの例を示します。
db.users.insertMany( [ { _id : 1, name : "dave123", q1 : true, q2 : true }, { _id : 2, name : "dave2", q1 : false, q2 : false }, { _id : 3, name : "ahn", q1 : true, q2 : true }, { _id : 4, name : "li", q1 : true, q2 : false }, { _id : 5, name : "annT", q1 : false, q2 : true }, { _id : 6, name : "li", q1 : true, q2 : true }, { _id : 7, name : "ty", q1 : false, q2 : true } ] )
次の集計操作は、コレクションから 3 ドキュメントをランダムに選択します。
db.users.aggregate( [ { $sample: { size: 3 } } ] )
この操作は、3 つのランダムなドキュメントを返します。
MongoDB Node.jsドライバーを使用して $sample ステージを集計パイプラインに追加するには、パイプラインオブジェクトで $sample 演算子を使用します。
次の例では、入力コレクションから 5 つのランダムなドキュメントを返すパイプラインステージを作成します。次に、この例では集計パイプラインを実行します。
const pipeline = [{ $sample: { size: 5 } }]; const cursor = collection.aggregate(pipeline); return cursor;