次の方法で共有


$topN

適用対象: MongoDB 仮想コア

$topN アキュムレータ演算子を使用すると、指定した並べ替え順序に基づいて、グループから上位 N 個の要素が返されます。 これは $top の機能を拡張するものです。最上位の 1 要素だけでなく、複数の上位要素を取得できます。

構文

$topN アキュムレータ演算子の構文は次のとおりです。

{
  $group: {
    _id: <expression>,
    <field>: { 
      $topN: {
        n: <number>,
        sortBy: { <field1>: <sort order>, <field2>: <sort order>, ... },
        output: <expression>
      }
    }
  }
}

パラメーター

説明
n 返される要素の数。 正の整数にする必要があります。
sortBy フィールド名と並べ替え方向 (昇順の場合は 1、降順の場合は -1) を指定したドキュメントを使用して、並べ替え順序を指定します。
output 上位 N 個のドキュメントから返されるフィールドまたは値を指定する式。

stores データセットからのサンプル json の使用方法を理解しましょう。

{
  "_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74",
  "name": "Proseware, Inc. | Home Entertainment Hub - East Linwoodbury",
  "sales": {
    "totalSales": 151864,
    "salesByCategory": [
      {
        "categoryName": "Sound Bars",
        "totalSales": 2120
      },
      {
        "categoryName": "Home Theater Projectors",
        "totalSales": 45004
      },
      {
        "categoryName": "Game Controllers",
        "totalSales": 43522
      },
      {
        "categoryName": "Remote Controls",
        "totalSales": 28946
      },
      {
        "categoryName": "VR Games",
        "totalSales": 32272
      }
    ]
  },
  "promotionEvents": [
    {
      "eventName": "Massive Markdown Mania",
      "discounts": [
        {
          "categoryName": "DVD Players",
          "discountPercentage": 14
        },
        {
          "categoryName": "Media Players",
          "discountPercentage": 21
        },
        {
          "categoryName": "Televisions",
          "discountPercentage": 22
        }
      ]
    }
  ]
}

例 1: 店舗ごとに上位 3 つの販売カテゴリを取得する

各店舗の売上上位 3 つのカテゴリを検索します。

db.stores.aggregate([
  { $unwind: "$sales.salesByCategory" },
  {
    $group: {
      _id: "$_id",
      storeName: { $first: "$name" },
      top3Categories: {
        $topN: {
          n: 3,
          sortBy: { "sales.salesByCategory.totalSales": -1 },
          output: {
            categoryName: "$sales.salesByCategory.categoryName",
            totalSales: "$sales.salesByCategory.totalSales"
          }
        }
      }
    }
  }
])

これにより、各店舗の売上上位 3 つのカテゴリを示す出力が生成されます。

[
  {
    _id: '8c8f23c9-1893-4ddd-97ad-dd57088058a5',
    storeName: 'Proseware, Inc. | Camera Haven - North Jerroldville',
    top3Categories: [
      { categoryName: 'Waterproof Camcorders', totalSales: 25237 },
      { categoryName: 'Camera Lenses', totalSales: 21189 },
      { categoryName: 'Action Camcorders', totalSales: 19467 }
    ]
  },
  {
    _id: '7f0b0454-e22b-4646-8eb4-32ad5eb48042',
    storeName: 'First Up Consultants | Tool Boutique - Paoloberg',
    top3Categories: [
      { categoryName: 'Drills', totalSales: 40686 },
      { categoryName: 'Screwdrivers', totalSales: 30155 },
      { categoryName: 'Chisels', totalSales: 15762 }
    ]
  },
.
.
.
]

例 2: 最近の 2 つの販売促進イベントを取得する

開始日に基づいて、店舗ごとに最近の 2 つの販売促進イベントを検索します。

db.stores.aggregate([
  { $unwind: "$promotionEvents" },
  {
    $group: {
      _id: "$_id",
      storeName: { $first: "$name" },
      top2RecentPromotions: {
        $topN: {
          n: 2,
          sortBy: { 
            "promotionEvents.promotionalDates.startDate.Year": -1,
            "promotionEvents.promotionalDates.startDate.Month": -1,
            "promotionEvents.promotionalDates.startDate.Day": -1
          },
          output: {
            eventName: "$promotionEvents.eventName",
            startDate: "$promotionEvents.promotionalDates.startDate"
          }
        }
      }
    }
  }
])

これにより、店舗ごとに最近の 2 つの販売促進イベントが返されます。

[
  {
    _id: '4a99546f-a1d2-4e61-ae9f-b8c7c1faf73c',
    storeName: 'Lakeshore Retail | Stationery Nook - West Van',
    top2RecentPromotions: [
      {
        eventName: 'Crazy Markdown Madness',
        startDate: { Year: 2024, Month: 9, Day: 21 }
      },
      {
        eventName: 'Flash Sale Fiesta',
        startDate: { Year: 2024, Month: 6, Day: 23 }
      }
    ]
  },
  {
    _id: 'e0c47a06-4fe0-46b7-a309-8971bbb3978f',
    storeName: 'VanArsdel, Ltd. | Baby Products Bargains - Elainamouth',
    top2RecentPromotions: [
      {
        eventName: 'Crazy Deal Days',
        startDate: { Year: 2024, Month: 9, Day: 21 }
      }
    ]
  },
.
.
.
]

例 3: カテゴリ別に割引率の高い上位 5 件を取得する

各店舗のすべての販売促進イベント全体で割引率が最も高い上位 5 つのカテゴリを検索します。

db.stores.aggregate([
  { $unwind: "$promotionEvents" },
  { $unwind: "$promotionEvents.discounts" },
  {
    $group: {
      _id: "$_id",
      storeName: { $first: "$name" },
      top5Discounts: {
        $topN: {
          n: 5,
          sortBy: { "promotionEvents.discounts.discountPercentage": -1 },
          output: {
            categoryName: "$promotionEvents.discounts.categoryName",
            discountPercentage: "$promotionEvents.discounts.discountPercentage",
            eventName: "$promotionEvents.eventName"
          }
        }
      }
    }
  }
])

これにより、各店舗の割引率が最も高い上位 5 つのカテゴリが表示されます。

[
  {
    _id: '4a99546f-a1d2-4e61-ae9f-b8c7c1faf73c',
    storeName: 'Lakeshore Retail | Stationery Nook - West Van',
    top5Discounts: [
      {
        categoryName: 'Rulers',
        discountPercentage: 24,
        eventName: 'Markdown Madness'
      },
      {
        categoryName: 'Notebooks',
        discountPercentage: 21,
        eventName: 'Markdown Madness'
      },
      {
        categoryName: 'Paper Clips',
        discountPercentage: 17,
        eventName: 'Flash Sale Fiesta'
      },
      {
        categoryName: 'Pencils',
        discountPercentage: 15,
        eventName: 'Bargain Blitz Bash'
      },
      {
        categoryName: 'Erasers',
        discountPercentage: 14,
        eventName: 'Crazy Markdown Madness'
      }
    ]
  },
.
.
.
]