$fill

$fill ステージは、集計パイプライン内のドキュメント内の欠損値または null 値を埋めるために使用されます。 静的な値、線状補間、または前/次のドキュメントの値を使用するなど、欠損データを事前設定するためのさまざまな方法が用意されています。

構文

{
  $fill: {
    sortBy: <sort specification>,
    partitionBy: <partition fields>,
    partitionByFields: <array of partition field names>,
    output: {
      <field1>: { value: <expression> },
      <field2>: { method: <string> }
    }
  }
}

パラメーター

パラメーター Description
sortBy ドキュメントの順序に依存する fill のメソッドを適用する際に、ドキュメントの並べ替え順序を指定します。
partitionBy Optional. ドキュメントをパーティションにグループ化します。 fill 操作は各パーティション内で個別に適用されます。
partitionByFields Optional. フィールド名の配列を使用する partitionBy の代替構文。
output 埋めるフィールドと、欠損データを埋めるために使用するメソッドまたは値を指定します。

fill のメソッド

メソッド Description
value 指定した静的な値または式の結果を使用して埋めます。
linear 既知の値 (数値フィールドのみ) の間を線状補間を使用して埋めます。
locf 最後の観測値の繰り越し - 最後の既知の値を使用します。
linear 周囲の値間の線状補間。

例示

stores コレクションのこのサンプル ドキュメントについて考えてみましょう。

{
  "_id": "2cf3f885-9962-4b67-a172-aa9039e9ae2f",
  "name": "First Up Consultants | Bed and Bath Center - South Amir",
  "location": {
    "lat": 60.7954,
    "lon": -142.0012
  },
  "staff": {
    "totalStaff": {
      "fullTime": 18,
      "partTime": 17
    }
  },
  "sales": {
    "totalSales": 37701,
    "salesByCategory": [
      {
        "categoryName": "Mattress Toppers",
        "totalSales": 37701
      }
    ]
  },
  "promotionEvents": [
    {
      "eventName": "Price Drop Palooza",
      "promotionalDates": {
        "startDate": {
          "Year": 2024,
          "Month": 9,
          "Day": 21
        },
        "endDate": {
          "Year": 2024,
          "Month": 9,
          "Day": 30
        }
      },
      "discounts": [
        {
          "categoryName": "Bath Accessories",
          "discountPercentage": 18
        },
        {
          "categoryName": "Pillow Top Mattresses",
          "discountPercentage": 17
        }
      ]
    }
  ]
}

例 1: 欠損値を静的な値で埋める

このクエリは、totalSales配列の不足しているsalesByCategory値を既定値の 0 で入力します。

db.stores.aggregate([{
    $match: {
        company: {
            $in: ["First Up Consultants"]
        }
    }
}, {
    $unwind: "$sales.salesByCategory"
}, {
    $fill: {
        output: {
            "sales.salesByCategory.totalSales": {
                value: 0
            }
        }
    }
}, {
    $group: {
        _id: "$_id",
        name: {
            $first: "$name"
        },
        salesByCategory: {
            $push: "$sales.salesByCategory"
        }
    }
}])

このクエリによって返される最初の 2 つの結果は次のとおりです。

[
    {
        "_id": "affdc09c-7356-4fff-a857-e8301f57159c",
        "name": "First Up Consultants | Sports Gear Pantry - Wildermanhaven",
        "salesByCategory": [
            {
                "categoryName": "Baseball Gear",
                "totalSales": 33878
            },
            {
                "categoryName": "Volleyball Gear",
                "totalSales": 34031
            }
        ]
    },
    {
        "_id": "1cf667b4-d8ce-4f1a-bad1-a1f0bbce26c2",
        "name": "First Up Consultants | Picture Frame Variety - New Abrahamborough",
        "salesByCategory": [
            {
                "categoryName": "Picture Hanging Supplies",
                "totalSales": 7229
            },
            {
                "categoryName": "Collage Frames",
                "totalSales": 40014
            }
        ]
    }
]

例 2: 前回の観測値を繰り越して欠損しているスタッフ データを埋める

このクエリは、各ストア グループ内の最後の既知の値を使用して、不足しているパートタイム スタッフ データを入力します。

db.stores.aggregate([{
    $fill: {
        sortBy: {
            "_id": 1
        },
        output: {
            "staff.totalStaff.partTime": {
                method: "locf"
            }
        }
    }
}, {
    $project: {
        name: 1,
        "staff.totalStaff": 1
    }
}])

このクエリによって返される最初の 2 つの結果は次のとおりです。

[
    {
        "_id": "00003278-4226-4ca7-871d-e80d8f414431",
        "name": "Wide World Importers | Camera Depot - Lake Luramouth",
        "staff": {
            "totalStaff": {
                "fullTime": 20,
                "partTime": 6
            }
        }
    },
    {
        "_id": "00009bd0-c44e-4cc8-ab03-347076d74a1a",
        "name": "Wide World Importers | Music Stop - Rebeccaside",
        "staff": {
            "totalStaff": {
                "fullTime": 9,
                "partTime": 0
            }
        }
    }
]

例 3: 不足している割引率を平均値で埋める

このクエリでは、不足している割引率に、すべての店舗の平均割引率が入力されます。

db.stores.aggregate([
  { $unwind: "$promotionEvents" },
  { $unwind: "$promotionEvents.discounts" },
  {
    $fill: {
      partitionBy: "$promotionEvents.eventName",
      sortBy: { "promotionEvents.discounts.categoryName": 1 },
      output: {
        "promotionEvents.discounts.discountPercentage": { 
          value: { $avg: "$promotionEvents.discounts.discountPercentage" } 
        }
      }
    }
  },
  {
    $group: {
      _id: { storeId: "$_id", eventName: "$promotionEvents.eventName" },
      storeName: { $first: "$name" },
      eventName: { $first: "$promotionEvents.eventName" },
      discounts: { $push: "$promotionEvents.discounts" }
    }
  }
])

このクエリによって返される最初の 2 つの結果は次のとおりです。

[
    {
        "_id": {
            "storeId": "70d4cc90-23b1-46e3-8f59-630648e311a4",
            "eventName": "Price Slash Spectacular"
        },
        "storeName": "Wide World Importers | Music Bazaar - West Johnpaulhaven",
        "eventName": "Price Slash Spectacular",
        "discounts": [
            {
                "categoryName": "CDs",
                "discountPercentage": 22
            },
            {
                "categoryName": "Vinyl Records",
                "discountPercentage": 21
            }
        ]
    },
    {
        "_id": {
            "storeId": "24873ac4-b2d1-4216-a425-3375a384b23d",
            "eventName": "Massive Deal Mania"
        },
        "storeName": "Northwind Traders | Furniture Pantry - Farrellchester",
        "eventName": "Massive Deal Mania",
        "discounts": [
            {
                "categoryName": "Bookcases",
                "discountPercentage": 22
            },
            {
                "categoryName": "Cabinets",
                "discountPercentage": 8
            }
        ]
    }
]

使用例

  • データ クリーニング: インポートしたデータセットの欠損値を埋める
  • 時系列データ: 補間を使用して連続データのギャップを処理する
  • 既定値: 省略可能なフィールドに既定値を割り当てる
  • データの正規化: ドキュメント全体で一貫性のあるデータ構造を確保する