Compartir a través de


$firstN

El $firstN operador devuelve los primeros valores N de un grupo según el criterio de ordenación del grupo. Si no se especifica ningún criterio de ordenación, el orden no está definido.

Syntax

{
    $firstN: {
        input: [listOfFields],
        sortBy: {
            <fieldName>: <sortOrder>
        },
        n: <numDocumentsToReturn>
    }
}

Parámetros

Parámetro Description
listOfFields Lista de campos que se van a devolver para los primeros documentos N del conjunto de resultados
fieldName Campo que se va a usar para ordenar el conjunto de resultados
sortOrder 1 o -1. 1 implica la ordenación en orden ascendente del valor del campo, mientras que -1 implica la ordenación en orden descendente de los valores del campo
n Número de documentos que se van a devolver desde la parte superior del conjunto de resultados ordenado

Examples

Considere este documento de ejemplo de la colección de tiendas.

{
    "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4",
    "name": "First Up Consultants | Beverage Shop - Satterfieldmouth",
    "location": {
        "lat": -89.2384,
        "lon": -46.4012
    },
    "staff": {
        "totalStaff": {
            "fullTime": 8,
            "partTime": 20
        }
    },
    "sales": {
        "totalSales": 75670,
        "salesByCategory": [
            {
                "categoryName": "Wine Accessories",
                "totalSales": 34440
            },
            {
                "categoryName": "Bitters",
                "totalSales": 39496
            },
            {
                "categoryName": "Rum",
                "totalSales": 1734
            }
        ]
    },
    "promotionEvents": [
        {
            "eventName": "Unbeatable Bargain Bash",
            "promotionalDates": {
                "startDate": {
                    "Year": 2024,
                    "Month": 6,
                    "Day": 23
                },
                "endDate": {
                    "Year": 2024,
                    "Month": 7,
                    "Day": 2
                }
            },
            "discounts": [
                {
                    "categoryName": "Whiskey",
                    "discountPercentage": 7
                },
                {
                    "categoryName": "Bitters",
                    "discountPercentage": 15
                },
                {
                    "categoryName": "Brandy",
                    "discountPercentage": 8
                },
                {
                    "categoryName": "Sports Drinks",
                    "discountPercentage": 22
                },
                {
                    "categoryName": "Vodka",
                    "discountPercentage": 19
                }
            ]
        },
        {
            "eventName": "Steal of a Deal Days",
            "promotionalDates": {
                "startDate": {
                    "Year": 2024,
                    "Month": 9,
                    "Day": 21
                },
                "endDate": {
                    "Year": 2024,
                    "Month": 9,
                    "Day": 29
                }
            },
            "discounts": [
                {
                    "categoryName": "Organic Wine",
                    "discountPercentage": 19
                },
                {
                    "categoryName": "White Wine",
                    "discountPercentage": 20
                },
                {
                    "categoryName": "Sparkling Wine",
                    "discountPercentage": 19
                },
                {
                    "categoryName": "Whiskey",
                    "discountPercentage": 17
                },
                {
                    "categoryName": "Vodka",
                    "discountPercentage": 23
                }
            ]
        }
    ]
}

Ejemplo 1: Usar $firstN operador como acumulador para buscar los dos primeros almacenes por ventas totales

Para obtener los dos almacenes principales por ventas totales, ejecute una consulta para ordenar todos los documentos en orden descendente de sales.totalSales y devolver los dos primeros documentos del conjunto de resultados ordenados.

db.stores.aggregate([{
        $sort: {
            "sales.totalSales": -1
        }
    },
    {
        $group: {
            _id: null,
            topTwoStores: {
                $firstN: {
                    n: 2,
                    input: {
                        storeId: "$_id",
                        storeName: "$name",
                        totalSales: "$sales.totalSales"
                    }
                }
            }
        }
    }
])

Esta consulta devuelve el siguiente resultado:

[
    {
        "_id": null,
        "topTwoStores": [
            {
                "storeId": "ffe155dd-caa2-4ac1-8ec9-0342241a84a3",
                "storeName": "Lakeshore Retail | Electronics Stop - Vicentastad",
                "totalSales": 399426
            },
            {
                "storeId": "cba62761-10f8-4379-9eea-a9006c667927",
                "storeName": "Fabrikam, Inc. | Electronics Nook - East Verlashire",
                "totalSales": 374845
            }
        ]
    }
]

Ejemplo 2: Usar $firstN operador como acumulador para buscar las dos primeras categorías por almacén

Para recuperar las dos primeras categorías por ventas totales dentro de cada tienda, ejecute una consulta para ordenar todos los documentos en orden descendente de sales.totalSales dentro del ámbito de cada tienda y devolver las dos primeras categorías del conjunto de resultados ordenado por almacén.

db.stores.aggregate([
  { $unwind: "$sales.salesByCategory" },
  {
    $match: {
      "sales.salesByCategory.totalSales": { $exists: true }
    }
  },
  {
    $sort: {
      "_id": 1,
      "sales.salesByCategory.totalSales": -1
    }
  },
  {
    $group: {
      _id: "$_id",
      storeName: { $first: "$name" },
      categoryCount: { $sum: 1 },
      firstTwoCategories: {
        $push: {
          categoryName: "$sales.salesByCategory.categoryName",
          totalSales: "$sales.salesByCategory.totalSales"
        }
      }
    }
  },
  {
    $project: {
      storeName: 1,
      categoryCount: 1,
      firstTwoCategories: { $slice: ["$firstTwoCategories", 2] }
    }
  },
  {
    $match: {
      categoryCount: { $gte: 2 }
    }
  },
  { $limit: 2 }
])

Los dos primeros resultados devueltos por esta consulta son:

[
    {
        "_id": "2e07b49d-1730-491b-b847-44b6a34812c1",
        "storeName": "VanArsdel, Ltd. | Electronics Market – North Bransonborough",
        "categoryCount": 3,
        "firstTwoCategories": [
            {
                "categoryName": "iPads",
                "totalSales": 37113
            },
            {
                "categoryName": "Laptops",
                "totalSales": 9175
            }
        ]
    },
    {
        "_id": "1bec7539-dc75-4f7e-b4e8-afdf8ff2f234",
        "storeName": "Adatum Corporation | Health Food Market – East Karina",
        "categoryCount": 2,
        "firstTwoCategories": [
            {
                "categoryName": "Protein Bars",
                "totalSales": 49900
            },
            {
                "categoryName": "Superfoods",
                "totalSales": 39683
            }
        ]
    }
]

Ejemplo 3: Uso del firstN operador como array-expression para buscar las tres primeras categorías de ventas

En el ejemplo se muestra el uso del operador para buscar las tres primeras categorías de ventas para su análisis.

db.stores.aggregate([
  { $match: {"_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74"} },
  {
    $project: {
      name: 1,
      totalSales: "$sales.totalSales",
      firstThreeCategories: {
        $firstN: {
          input: "$sales.salesByCategory",
          n: 3
        }
      }
    }
  }
])

Esta consulta devuelve el siguiente resultado:

[
  {
      "_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74",
      "name": "Proseware, Inc. | Home Entertainment Hub - East Linwoodbury",
      "totalSales": 165000,
      "firstThreeCategories": [
          {
              "categoryName": "Sound Bars",
              "totalSales": 2120
          },
          null,
          {
              "categoryName": "Game Controllers",
              "totalSales": 43522
          }
      ]
  }
]