适用对象:
MongoDB vCore
该 $firstN
运算符根据组的排序顺序返回组中的第一个 N 值。 如果未指定排序顺序,则顺序为未定义。 如果要从每个组检索第一个 N 文档或值,则它很有用。
语法
运算符的 $isArray
语法如下所示:
{
$firstN: {
n: <expression>,
input: <expression>
}
}
参数
DESCRIPTION | |
---|---|
n |
一个表达式,指定要返回的第一个元素的数目。 必须是正整数。 |
input |
一个表达式,指定从中返回第一个 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",
"promotionalDates": {
"startDate": {
"Year": 2023,
"Month": 6,
"Day": 29
}
}
},
{
"eventName": "Fantastic Deal Days",
"promotionalDates": {
"startDate": {
"Year": 2023,
"Month": 9,
"Day": 27
}
}
}
]
}
示例 1:按总销售额获取前三家商店
按降序按总销售额排序时,获取前三家商店。
db.stores.aggregate([
{ $sort: { "sales.totalSales": -1 } },
{
$group: {
_id: null,
topThreeStores: {
$firstN: {
n: 3,
input: {
storeId: "$_id",
storeName: "$name",
totalSales: "$sales.totalSales"
}
}
}
}
}
])
这会生成以下输出:
[
{
_id: null,
topThreeStores: [
{
storeId: '27d12c50-ef9b-4a1e-981f-2eb46bf68c70',
storeName: 'Boulder Innovations | Electronics Closet - West Freddy',
totalSales: 404106
},
{
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
}
]
}
]
示例 2:获取每个商店的前两个类别
获取每个具有多个类别的商店的前两个类别(按销售金额)。
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: {
$firstN: {
n: 2,
input: {
categoryName: "$sales.salesByCategory.categoryName",
totalSales: "$sales.salesByCategory.totalSales"
}
}
}
}
},
{ $match: { categoryCount: { $gte: 2 } } }
])
这会生成输出,其中按每个商店的销售额显示多个类别的前两个类别:
[
{
_id: '14343900-2a5c-44bf-a52b-9efe63579866',
storeName: 'Northwind Traders | Home Improvement Closet - West Evanside',
categoryCount: 2,
firstTwoCategories: [
{ categoryName: 'Doors', totalSales: 21108 },
{ categoryName: 'Hardware', totalSales: 14263 }
]
},
{
_id: '19ea47b8-4fbd-468c-88f6-133ffa517fad',
storeName: 'Proseware, Inc. | Grocery Bazaar - North Earnest',
categoryCount: 2,
firstTwoCategories: [
{ categoryName: 'Frozen Foods', totalSales: 36967 },
{ categoryName: 'Meat', totalSales: 2724 }
]
},
.
.
.
]
示例 3:获取每个商店的前两个促销事件
根据时间顺序获取每个商店的前两个促销事件。
db.stores.aggregate([
{ $unwind: "$promotionEvents" },
{
$sort: {
"_id": 1,
"promotionEvents.promotionalDates.startDate.Year": 1,
"promotionEvents.promotionalDates.startDate.Month": 1,
"promotionEvents.promotionalDates.startDate.Day": 1
}
},
{
$group: {
_id: "$_id",
storeName: { $first: "$name" },
eventCount: { $sum: 1 },
firstTwoEvents: {
$firstN: {
n: 2,
input: {
eventName: "$promotionEvents.eventName",
startYear: "$promotionEvents.promotionalDates.startDate.Year",
startMonth: "$promotionEvents.promotionalDates.startDate.Month"
}
}
}
}
},
{ $match: { eventCount: { $gte: 2 } } }
])
这会为每个具有多个事件的商店按时间顺序返回前两个促销事件。