$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 문서 순서에 따라 채우기 메서드를 적용할 때 문서의 정렬 순서를 지정합니다.
partitionBy Optional. 문서를 파티션으로 그룹화합니다. 채우기 작업은 각 파티션 내에서 별도로 적용됩니다.
partitionByFields Optional. 필드 이름 배열을 사용하는 partitionBy의 대체 구문입니다.
output 채워야 할 필드와 누락된 데이터를 채우는 데 사용할 메서드 또는 값을 지정합니다.

채우기 메서드

메서드 Description
value 지정된 정적 값 또는 식 결과로 채웁니다.
linear 알려진 값 사이의 선형 보간을 사용하여 채웁니다(숫자 필드에만 해당).
locf 마지막 관찰값 - 마지막으로 알려진 값을 사용합니다.
linear 주변 값 간의 선형 보간입니다.

예시

스토어 컬렉션에서 이 샘플 문서를 고려합니다.

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

이 쿼리에서 반환된 처음 두 가지 결과는 다음과 같습니다.

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

이 쿼리에서 반환된 처음 두 가지 결과는 다음과 같습니다.

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

이 쿼리에서 반환된 처음 두 가지 결과는 다음과 같습니다.

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

사용 사례

  • 데이터 정화: 가져온 데이터 세트에 누락된 값 채우기
  • 시계열 데이터: 보간을 사용하여 순차 데이터의 간격 처리
  • 기본값: 선택적 필드에 기본값 할당
  • 데이터 정규화: 문서 전체에 일관된 데이터 구조 보장