$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
ステージは次のフィールドを持つドキュメントを取得します。
フィールド | 必要性 | 説明 |
---|---|---|
任意 | ドキュメントをグループ化するための式を指定します。 partitionByとpartitionByFieldsを省略すると、 partitionByとpartitionByFieldは相互に排他的です。 | |
任意 | ドキュメントをグループ化するための複合キーとしてフィールドの配列を指定します。 partitionByとpartitionByFieldsを省略すると、 partitionByとpartitionByFieldは相互に排他的です。 | |
メソッド が少なくとも 1 つの 出力. .<field> で指定されている場合は必須です。 それ以外は任意です。 | 各パーティション内のドキュメントをソートするフィールドを指定します。 | |
必須 | 欠落値を入力する各フィールドを含むオブジェクトを指定します。 出力オブジェクトには複数のフィールドを指定できます。 オブジェクト名は、入力するフィールドの名前です。 オブジェクト値は、フィールドの入力方法を指定します。 | |
必須 | ターゲット フィールドに欠落値を入力する方法を示すオブジェクトを指定します。 オブジェクト名は |
行動と限界
partitionByFields
制限事項
$fill
は、 partitionByFields配列内のいずれかのフィールド名がある場合にエラーを返します。
非 string 値として評価されます。
$
から始まります。
linear
動作
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
入力メソッドを使用する完全な例については、「線形補間で欠落しているフィールド値を入力する 」を参照してください。
locf
動作
locf
は、転送された最後の結果を表します。
入力されているフィールドに
null
と null 以外の値の両方が含まれている場合、locf
はnull
と欠落値を、 sortBy順序に従ってフィールドの最後に確認された null 以外の値に設定します。フィールドに
null
または欠落値のみが含まれている場合、locf
はそのパーティションのフィールド値をnull
に設定します。null
並べ替え順序 で null 以外の値の前に表示される欠落しているフィールド値はnull
のままです。
locf
fill メソッドを使用するには、 sortByフィールドも使用してデータを並べ替える必要があります。
locf
入力メソッドを使用する完全な例については、「 最後に確認された値に基づいて、欠落しているフィールド値を入力する 」を参照してください。
$fill
と集計演算子の比較
ドキュメント内で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 } } } } ] )
上記のパイプラインでは、
出力例:
[ { _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 } ]
線形補間で欠落しているフィールド値を入力
時間単位で 1 つの会社の株価を追跡するstock
コレクションを作成します。
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 } ]
最後に確認された値に基づいて、欠落しているフィールド値を入力する
1 つのレストランの一定期間のレビュー スコアを含む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
を使用します。 次の例では、 $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
演算子によって入力されたかどうか、あるいは値が最初にドキュメントに存在していたかどうかが示されません。 入力値と既存値を区別するには、 $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" } } } } ] )
注意
ゼロの値の処理
出力:
[ { _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 } ]