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

$fill(集計ステージ)

$fill

バージョン5.3の新機能。

ドキュメント内のnullと欠落しているフィールド値を入力します。

欠落しているデータ ポイントを入力するには、 $fillを使用します。

  • 周囲の値に基づくシーケンス内。

  • 固定値の場合。

$fillステージの構文は次のとおりです。

{ $fill: { partitionBy: <expression>, partitionByFields: [ <field 1>, <field 2>, ... , <field n> ], sortBy: { <sort field 1>: <sort order>, <sort field 2>: <sort order>, ..., <sort field n>: <sort order> }, output: { <field 1>: { value: <expression> }, <field 2>: { method: <string> }, ... } }}

$fillステージは次のフィールドを持つドキュメントを取得します。

フィールド
必要性
説明

任意

ドキュメントをグループ化する式を指定します。 $fillステージでは、ドキュメントのグループはパーティションと呼ばれます。

partitionByとpartitionByFieldsを省略すると、 $fillはコレクション全体に 1 つのパーティションを使用します。

partitionByとpartitionByFieldは相互に排他的です。

例 を参照してください。

任意

ドキュメントをグループ化するための複合キーとしてフィールドの配列を指定します。 $fillステージでは、各ドキュメントグループはパーティションと呼ばれます。

partitionByとpartitionByFieldsを省略すると、 $fillはコレクション全体に 1 つのパーティションを使用します。

partitionByとpartitionByFieldは相互に排他的です。

詳しくはpartitionByFields制限 を参照してください。

メソッド が少なくとも 1 つの 出力. .<field> で指定されている場合は必須です。

それ以外は任意です。

各パーティション内のドキュメントをソートするフィールドを指定します。 $sortステージと同じ構文を使用します。

必須

欠落値を入力する各フィールドを含むオブジェクトを指定します。 出力オブジェクトには複数のフィールドを指定できます。

オブジェクト名は、入力するフィールドの名前です。 オブジェクト値は、フィールドの入力方法を指定します。

必須

ターゲット フィールドに欠落値を入力する方法を示すオブジェクトを指定します。

オブジェクト名はvalueまたはmethodのいずれかである必要があります。 名前が次の場合:

  • value、値は、ターゲット フィールドを入力するために使用される値を示す式である必要があります。

  • methodの場合、値はlinearまたはlocfのいずれかである必要があります。 次の値を指定する場合:

    • linear fill メソッドでは、シーケンス内の周囲の null 以外の値に基づき、線形補間 を使用して値が入力されます。

    • locf fill メソッドを使用する場合、値はパーティション内のフィールドの最後の null 以外の値に基づいて入力されます。 locfは、転送された最後の観察を示します。

      詳しくは以下を参照してください。

$fillは、 partitionByFields配列内のいずれかのフィールド名がある場合にエラーを返します。

  • 非 string 値として評価されます。

  • $から始まります。

The linear 埋め込みメソッドは、シーケンス内の周囲の null 以外の値に基づき、線形補間 を使用して null と欠落フィールドを埋めます。

  • フィールドがnullまたは欠落しているドキュメントごとに、 linearFillはsortBy順序に従って、周囲のnull以外の値間の欠落値範囲に比例してそれらのフィールドを埋めます。 欠落しているフィールドの値を決定するために、 linearFillは以下を使用します。

    • 周囲のnullの値との差。

    • 周囲の値の間に入力するnullフィールドの数。

  • linearメソッドでは、 sortByの順序に従って、それらの値が先行してnull以外の値に続く場合、複数の連続するnull値を入力できます。

    例

    これらのドキュメントがコレクションに含まれている場合:

    { index: 0, value: 0 },{ index: 1, value: null },{ index: 2, value: null },{ index: 3, value: null },{ index: 4, value: 10 }

    linear入力メソッドを使用してnull値を入力すると、ドキュメントは次のようになります。

    { index: 0, value: 0 },{ index: 1, value: 2.5 },{ index: 2, value: 5 },{ index: 3, value: 7.5 },{ index: 4, value: 10 }
  • null nullの値が先行せず、その後に続く値はnullのままになります。

  • linear fill メソッドを使用するには、 sortByフィールドも使用してデータを並べ替える必要があります。

linear入力メソッドを使用する完全な例については、「線形補間で欠落しているフィールド値を入力する 」を参照してください。

linear フィルメソッドを使用する場合:

  • sortByでは、フィールドを1つだけ指定できます。複数のフィールドを指定すると、$fillはエラーを返します。

  • $fill は、単一のパーティション内のsortBy フィールドに繰り返される値がある場合、エラーを返します。

MongoDB 8.0.20 以降、$fillは、異なるパーティションに同一のsortBy値が含まれている場合に補間できます。詳細については、「異なるパーティション内の同一値の補間」を参照してください。

locf は、転送された最後の結果を表します。

  • 入力されているフィールドにnullと null 以外の値の両方が含まれている場合、 locfはnullと欠落値を、 sortBy順序に従ってフィールドの最後に確認された null 以外の値に設定します。

    • フィールドにnullまたは欠落値のみが含まれている場合、 locfはそのパーティションのフィールド値をnullに設定します。

    • null 並べ替え順序 で null 以外の値の前に表示される欠落しているフィールド値はnullのままです。

  • locf fill メソッドを使用するには、 sortByフィールドも使用してデータを並べ替える必要があります。

locf入力メソッドを使用する完全な例については、「 最後に確認された値に基づいて、欠落しているフィールド値を入力する 」を参照してください。

ドキュメント内でnullと欠落しているフィールド値を入力するには、次のコマンドを使用します。

  • $fillステージ。

    $fillステージを使用する場合、出力で指定するフィールドはソース データと同じフィールドになります。

  • $linearFillと$locf集計演算子

    $linearFillまたは$locfの場合、ソース データとして使用されるフィールドとは異なるフィールドに値を設定できます。

このセクションの例では、 $fillを使用して欠落値を入力する方法を示します。

ある金物店では、毎日の売上を要約するドキュメントを含むdailySalesコレクションを管理しています。 鍵店では次のタイプの鍵を販売しています。

  • boots

  • sandals

  • sneakers

次の dailySales コレクションを作成します。

db.dailySales.insertMany( [ { "date": ISODate("2022-02-02"), "bootsSold": 10, "sandalsSold": 20, "sneakersSold": 12 }, { "date": ISODate("2022-02-03"), "bootsSold": 7, "sneakersSold": 18 }, { "date": ISODate("2022-02-04"), "sneakersSold": 5 }] )

dailySalesコレクション内のすべてのドキュメントに各ドライバーが含まれているわけではありません。 在庫のあり、

次の例では、 $fillを使用して、毎日の販売に欠落しているキー タイプの販売数量を0に設定します。

db.dailySales.aggregate( [ { $fill: { output: { "bootsSold": { value: 0 }, "sandalsSold": { value: 0 }, "sneakersSold": { value: 0 } } } }] )

上記のパイプラインでは、

  • $fill は、欠落しているフィールドの値を入力します。

  • 出力は以下を指定します。

  • 入力するフィールドの名前。

  • 入力フィールドを設定する値。この例では 、
    出力は 0 の定数値を指定します。

出力例:

[ { _id: ObjectId("6202df9f394d47411658b51e"), date: ISODate("2022-02-02T00:00:00.000Z"), bootsSold: 10, sandalsSold: 20, sneakersSold: 12 }, { _id: ObjectId("6202df9f394d47411658b51f"), date: ISODate("2022-02-03T00:00:00.000Z"), bootsSold: 7, sneakersSold: 18, sandalsSold: 0 }, { _id: ObjectId("6202df9f394d47411658b520"), date: ISODate("2022-02-04T00:00:00.000Z"), sneakersSold: 5, bootsSold: 0, sandalsSold: 0 }]

次のドキュメントを含む stockコレクションを作成します。このドキュメントは 1 時間ごとの単一会社の株価を追跡します。

db.stock.insertMany( [ { time: ISODate("2021-03-08T09:00:00.000Z"), price: 500 }, { time: ISODate("2021-03-08T10:00:00.000Z"), }, { time: ISODate("2021-03-08T11:00:00.000Z"), price: 515 }, { time: ISODate("2021-03-08T12:00:00.000Z") }, { time: ISODate("2021-03-08T13:00:00.000Z") }, { time: ISODate("2021-03-08T14:00:00.000Z"), price: 485 }] )

コレクション内の一部のドキュメントでpriceフィールドが欠落しています。

線形補間 を使用して欠落しているprice $fill値を入力するには、linear と 入力メソッドを使用します。

db.stock.aggregate( [ { $fill: { sortBy: { time: 1 }, output: { "price": { method: "linear" } } } }] )

上記のパイプラインでは、

  • $fill は、欠落しているフィールドの値を入力します。

  • sortBy: { time: 1 } は、ドキュメントをtimeフィールドで最初から最新の順に昇順でソートします。

  • 出力は以下を指定します。

  • price 欠落値を入力するフィールドとして。

  • { method: "linear" } 入力メソッドとして。linear を満たす
    メソッドは、シーケンス内の周囲の price 値に基づき線形補間を使用することで、欠落している price 値を埋めます。

出力例:

[ { _id: ObjectId("620ad41c394d47411658b5e9"), time: ISODate("2021-03-08T09:00:00.000Z"), price: 500 }, { _id: ObjectId("620ad41c394d47411658b5ea"), time: ISODate("2021-03-08T10:00:00.000Z"), price: 507.5 }, { _id: ObjectId("620ad41c394d47411658b5eb"), time: ISODate("2021-03-08T11:00:00.000Z"), price: 515 }, { _id: ObjectId("620ad41c394d47411658b5ec"), time: ISODate("2021-03-08T12:00:00.000Z"), price: 505 }, { _id: ObjectId("620ad41c394d47411658b5ed"), time: ISODate("2021-03-08T13:00:00.000Z"), price: 495 }, { _id: ObjectId("620ad41c394d47411658b5ee"), time: ISODate("2021-03-08T14:00:00.000Z"), price: 485 }]

次のドキュメントを含む restaurantReviewsコレクションを作成します。このコレクションは 1 件のレストランのレビュー スコアを一定の期間保存します。

db.restaurantReviews.insertMany( [ { date: ISODate("2021-03-08"), score: 90 }, { date: ISODate("2021-03-09"), score: 92 }, { date: ISODate("2021-03-10") }, { date: ISODate("2021-03-11") }, { date: ISODate("2021-03-12"), score: 85 }, { date: ISODate("2021-03-13") }] )

コレクション内の一部のドキュメントでscoreフィールドが欠落しています。

欠落しているscoreフィールドに入力し、データに差がないようにするには、 $fillを使用します。 次の例では、 $fillはlocf埋め込みメソッドを使用して、欠落しているscore値をシーケンス内の前のscoreで埋めます。

db.restaurantReviews.aggregate( [ { $fill: { sortBy: { date: 1 }, output: { "score": { method: "locf" } } } }] )

上記のパイプラインでは、

  • $fillは欠落しているscore値を埋めます。

  • sortBy: { date: 1 } は、ドキュメントをdateフィールドで最初から最新の順に昇順でソートします。

  • 出力は以下を指定します。

  • score 欠落値を入力するフィールドとして。

  • { method: "locf" } 入力メソッドとして。locf を満たす
    メソッドは、欠落している score 値をシーケンス内で最後に確認された score で埋めます。

出力例:

[ { _id: ObjectId("62040bc9394d47411658b553"), date: ISODate("2021-03-08T00:00:00.000Z"), score: 90 }, { _id: ObjectId("62040bc9394d47411658b554"), date: ISODate("2021-03-09T00:00:00.000Z"), score: 92 }, { _id: ObjectId("62040bc9394d47411658b555"), date: ISODate("2021-03-10T00:00:00.000Z"), score: 92 }, { _id: ObjectId("62040bc9394d47411658b556"), date: ISODate("2021-03-11T00:00:00.000Z"), score: 92 }, { _id: ObjectId("62040bc9394d47411658b557"), date: ISODate("2021-03-12T00:00:00.000Z"), score: 85 }, { _id: ObjectId("62040bc9394d47411658b558"), date: ISODate("2021-03-13T00:00:00.000Z"), score: 85 }]

レストランのレビューを含む前の例を検討してみましょうが、1 つのレストランを追跡するのではなく、 コレクションには複数のレストランのレビューが含まれています。

restaurantReviewsMultipleという名前のコレクションを作成し、そのコレクションに次のドキュメントを入力します。

db.restaurantReviewsMultiple.insertMany( [ { date: ISODate("2021-03-08"), restaurant: "Joe's Pizza", score: 90 }, { date: ISODate("2021-03-08"), restaurant: "Sally's Deli", score: 75 }, { date: ISODate("2021-03-09"), restaurant: "Joe's Pizza", score: 92 }, { date: ISODate("2021-03-09"), restaurant: "Sally's Deli" }, { date: ISODate("2021-03-10"), restaurant: "Joe's Pizza" }, { date: ISODate("2021-03-10"), restaurant: "Sally's Deli", score: 68 }, { date: ISODate("2021-03-11"), restaurant: "Joe's Pizza", score: 93 }, { date: ISODate("2021-03-11"), restaurant: "Sally's Deli" }] )

コレクション内の一部のドキュメントでscoreフィールドが欠落しています。

欠落しているscoreフィールドに入力し、データに差がないようにするには、 $fillを使用します。 次の例では、 $fillはlocf埋め込みメソッドを使用して、欠落しているscore値をシーケンス内の前のscoreで埋めます。

db.restaurantReviewsMultiple.aggregate( [ { $fill: { sortBy: { date: 1 }, partitionBy: { "restaurant": "$restaurant" }, output: { "score": { method: "locf" } } } }] )

上記のパイプラインでは、

  • $fillは欠落しているscore値を埋めます。

  • sortBy: { date: 1 } は、ドキュメントをdateフィールドで最初から最新の順に昇順でソートします。

  • partitionBy: { "restaurant": "$restaurant" } はrestaurantでデータを分割します。 Joe's PizzaとSally's Deliの 2 つのレストランがあります。

  • 出力は以下を指定します。

  • score 欠落値を入力するフィールドとして。

  • { method: "locf" } 入力メソッドとして。locf を満たす
    メソッドは、欠落している score 値をシーケンス内で最後に確認された score で埋めます。

出力例:

[{ _id: ObjectId("620559f4394d47411658b58f"), date: ISODate("2021-03-08T00:00:00.000Z"), restaurant: "Joe's Pizza", score: 90},{ _id: ObjectId("620559f4394d47411658b591"), date: ISODate("2021-03-09T00:00:00.000Z"), restaurant: "Joe's Pizza", score: 92},{ _id: ObjectId("620559f4394d47411658b593"), date: ISODate("2021-03-10T00:00:00.000Z"), restaurant: "Joe's Pizza", score: 92},{ _id: ObjectId("620559f4394d47411658b595"), date: ISODate("2021-03-11T00:00:00.000Z"), restaurant: "Joe's Pizza", score: 93},{ _id: ObjectId("620559f4394d47411658b590"), date: ISODate("2021-03-08T00:00:00.000Z"), restaurant: "Sally's Deli", score: 75},{ _id: ObjectId("620559f4394d47411658b592"), date: ISODate("2021-03-09T00:00:00.000Z"), restaurant: "Sally's Deli", score: 75},{ _id: ObjectId("620559f4394d47411658b594"), date: ISODate("2021-03-10T00:00:00.000Z"), restaurant: "Sally's Deli", score: 68},{ _id: ObjectId("620559f4394d47411658b596"), date: ISODate("2021-03-11T00:00:00.000Z"), restaurant: "Sally's Deli", score: 68}]

欠損値を入力しても、出力には値が$fill演算子によって入力されたかどうか、あるいは値が最初にドキュメントに存在していたかどうかが示されません。 入力値と既存値を区別するには、 $fillの前に$setステージを使用し、値が存在するかどうかに基づいて新しいフィールドを設定します。

例、次のドキュメントを含む restaurantReviewsコレクションを作成します。これはレストランのレビュー スコアを一定期間保存するものです。

db.restaurantReviews.insertMany( [ { date: ISODate("2021-03-08"), score: 90 }, { date: ISODate("2021-03-09"), score: 92 }, { date: ISODate("2021-03-10") }, { date: ISODate("2021-03-11") }, { date: ISODate("2021-03-12"), score: 85 }, { date: ISODate("2021-03-13") }] )

コレクション内の一部のドキュメントで scoreフィールドが欠落しています。欠落している score 値を入力するには、$fill 演算子を使用します。

次のアクションを実行するためのパイプラインを作成します。

  • $set を使用して各ドキュメントに新しいフィールドを追加し、$fill 演算子が値を入力する前にドキュメントの scoreフィールドが存在するかどうかを示します。この新しいフィールドはvalueExisted と呼ばれます。

  • 欠落しているscore値に、シーケンス内で最後に確認されたscoreを入力します。 入力メソッドlocfは「last observation carried forward(LOCF)」を表します。

パイプラインは、次のコードのようになります。

db.restaurantReviews.aggregate( [ { $set: { "valueExisted": { "$ifNull": [ { "$toBool": { "$toString": "$score" } }, false ] } } }, { $fill: { sortBy: { date: 1 }, output: { "score": { method: "locf" } } } }] )

注意

ゼロの値の処理

$ifNull式では、 scoreの値は string に変換され、次にブール値に変換されます。 $toBool式は string を常にtrueに変換します。 score値が string に変換されない場合、 0のscore値では、 valueExistedはfalseに設定されます。

出力:

[ { _id: ObjectId("63595116b1fac2ee2e957f15"), date: ISODate("2021-03-08T00:00:00.000Z"), score: 90, valueExisted: true }, { _id: ObjectId("63595116b1fac2ee2e957f16"), date: ISODate("2021-03-09T00:00:00.000Z"), score: 92, valueExisted: true }, { _id: ObjectId("63595116b1fac2ee2e957f17"), date: ISODate("2021-03-10T00:00:00.000Z"), valueExisted: false, score: 92 }, { _id: ObjectId("63595116b1fac2ee2e957f18"), date: ISODate("2021-03-11T00:00:00.000Z"), valueExisted: false, score: 92 }, { _id: ObjectId("63595116b1fac2ee2e957f19"), date: ISODate("2021-03-12T00:00:00.000Z"), score: 85, valueExisted: true }, { _id: ObjectId("63595116b1fac2ee2e957f1a"), date: ISODate("2021-03-13T00:00:00.000Z"), valueExisted: false, score: 85 }]

バージョン8.0.20で変更。

MongoDB 8.0.20 以降、$fill は linear メソッドを使用して、異なるパーティションに同一の値がある場合に補間できます。

同一の日付にレストランのレビュー スコアを保存する次のドキュメントを含む次の restaurantReviewsMultipleコレクションを作成します。

db.restaurantReviewsMultiple.insertMany( [ { date: ISODate("2021-03-08"), restaurant: "Steve's Pizza", score: 90 }, { date: ISODate("2021-03-08"), restaurant: "Sally's Deli", score: 75 }] )

次の集計例では、"linear" を使用して、異なるパーティション内の同一の日付を補間します。

db.restaurantReviewsMultiple.aggregate( [ { $fill: { sortBy: { date: 1 }, partitionBy: { "restaurant": "$restaurant" }, output: { "score": { method: "linear" } } } }] )

MongoDB 8.0.20以降、この例では次の出力が返されます。

[ { _id: ObjectId("620559f4394d47411658b590"), date: ISODate("2021-03-08T00:00:00.000Z"), restaurant: "Sally's Deli", score: 75 }, { _id: ObjectId("620559f4394d47411658b58f"), date: ISODate("2021-03-08T00:00:00.000Z"), restaurant: "Steve's Pizza", score: 90 }]