Docs Menu
Docs Home
/
MongoDBマニュアル
/ / /

$fill(集計)

項目一覧

  • 定義
  • 構文
  • 行動と限界
  • partitionByFields 制限事項
  • linear 動作
  • locf 動作
  • $fillと集計演算子の比較
  • 欠落しているフィールド値を定数値で入力
  • 線形補間で欠落しているフィールド値を入力
  • 最後に確認された値に基づいて、欠落しているフィールド値を入力する
  • 個別のパーティションのデータを入力
  • を使用してフィールドが入力されたかどうかを示す $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

任意

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

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

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

例を参照してください。

任意

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

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

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

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

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

それ以外は任意です。

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

必須

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

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

必須

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

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

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

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

  • $から始まります。

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

  • フィールドがnullまたは欠落しているドキュメントごとに、 linearFillsortBy順序に従って、周囲の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フィールドも使用してデータを並べ替える必要があります。

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

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

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

  • 入力されているフィールドにnullと null 以外の値の両方が含まれている場合、 locfnullと欠落値を、 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
}
]

時間単位で 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を使用します。 次の例では、 $filllocf埋め込みメソッドを使用して、欠落している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を使用します。 次の例では、 $filllocf埋め込みメソッドを使用して、欠落している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 PizzaSally'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 に変換されない場合、 0score値では、 valueExistedfalseに設定されます。

出力:

[
{
_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
}
]

戻る

$facet