Services or capabilities described in Amazon Web Services documentation might vary by Region. To see the differences applicable to the China Regions,
see Getting Started with Amazon Web Services in China
(PDF).
$lastN
New from version 8.0.1.
The $lastN operator in Amazon DocumentDB returns the last N elements. When used as an accumulator in a $group stage, it returns an array of the last N values in each group. When used as an array expression operator, it returns the last N elements of an array.
Parameters
-
input: The expression that resolves to the field or array from which to return values.
-
n: A positive integer that specifies how many values to return. When used as an accumulator in a $group stage, n can also be an expression, as long as it resolves to a positive integer based on the group _id field.
Example (MongoDB Shell)
The following example shows how to use the $lastN accumulator to retrieve the last two quantities for each item during the aggregation.
$lastN selects values in the order that documents reach the $group stage. To return the last N values for a specific ordering (for example, by date or score), add a $sort stage before $group.
Create sample documents
db.sales.insertMany([
{ item: "abc", quantity: 10, date: ISODate("2023-01-01") },
{ item: "abc", quantity: 5, date: ISODate("2023-01-02") },
{ item: "abc", quantity: 8, date: ISODate("2023-01-03") },
{ item: "xyz", quantity: 15, date: ISODate("2023-01-01") },
{ item: "xyz", quantity: 7, date: ISODate("2023-01-02") },
{ item: "xyz", quantity: 3, date: ISODate("2023-01-03") }
]);
Query example
db.sales.aggregate([
{ $group: { _id: "$item", lastTwoQuantities: { $lastN: { input: "$quantity", n: 2 } } } }
]);
Output
[
{ "_id": "abc", "lastTwoQuantities": [5, 8] },
{ "_id": "xyz", "lastTwoQuantities": [7, 3] }
]
Expression usage example (MongoDB Shell)
The $lastN operator can also be used as an expression within a $project stage to return the last N elements of an array field.
Create sample documents
db.inventory.insertMany([
{ _id: 1, item: "abc", tags: ["red", "green", "blue", "yellow", "purple"] },
{ _id: 2, item: "xyz", tags: ["alpha", "beta", "gamma"] }
]);
Query example
db.inventory.aggregate([
{ $project: {
lastThreeTags: { $lastN: { input: "$tags", n: 3 } }
}}
]);
Output
[
{ "_id": 1, "lastThreeTags": ["blue", "yellow", "purple"] },
{ "_id": 2, "lastThreeTags": ["alpha", "beta", "gamma"] }
]
Window operator usage example (MongoDB Shell)
New from version 8.0.2.
The $lastN operator can also be used as a window operator in the $setWindowFields stage. In this context, it returns an array of up to the last n values for the documents in each window. You specify the operator under the output field, and optionally define the window boundaries with a window document.
When used as a window operator in $setWindowFields, $lastN is limited to 100 MB of intermediate data. An operation that exceeds this limit returns an error.
Create sample documents
db.stockPrices.insertMany([
{ _id: 1, ticker: "ABC", hour: 1, price: 50 },
{ _id: 2, ticker: "ABC", hour: 2, price: 45 },
{ _id: 3, ticker: "ABC", hour: 3, price: 60 },
{ _id: 4, ticker: "ABC", hour: 4, price: 40 },
{ _id: 5, ticker: "XYZ", hour: 1, price: 30 },
{ _id: 6, ticker: "XYZ", hour: 2, price: 35 },
{ _id: 7, ticker: "XYZ", hour: 3, price: 25 }
]);
Query example
The following example partitions the documents by ticker, sorts each partition by hour, and returns the two most recent prices seen from the start of the partition through the current document.
db.stockPrices.aggregate([
{
$setWindowFields: {
partitionBy: "$ticker",
sortBy: { hour: 1 },
output: {
lastTwoSoFar: {
$lastN: { input: "$price", n: 2 },
window: { documents: ["unbounded", "current"] }
}
}
}
}
]);
Output
[
{ "_id": 1, "ticker": "ABC", "hour": 1, "price": 50, "lastTwoSoFar": [50] },
{ "_id": 2, "ticker": "ABC", "hour": 2, "price": 45, "lastTwoSoFar": [50, 45] },
{ "_id": 3, "ticker": "ABC", "hour": 3, "price": 60, "lastTwoSoFar": [45, 60] },
{ "_id": 4, "ticker": "ABC", "hour": 4, "price": 40, "lastTwoSoFar": [60, 40] },
{ "_id": 5, "ticker": "XYZ", "hour": 1, "price": 30, "lastTwoSoFar": [30] },
{ "_id": 6, "ticker": "XYZ", "hour": 2, "price": 35, "lastTwoSoFar": [30, 35] },
{ "_id": 7, "ticker": "XYZ", "hour": 3, "price": 25, "lastTwoSoFar": [35, 25] }
]
Each document is augmented with lastTwoSoFar, the last two price values within its window (in hour order).
Code examples
To view a code example for using the $lastN operator, choose the tab for the language that you want to use. The following examples show accumulator usage (in $group), expression usage (in $project), and window operator usage (in $setWindowFields):
- Node.js
-
const { MongoClient } = require('mongodb');
async function example() {
const client = new MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false');
try {
await client.connect();
const db = client.db('test');
// Accumulator usage: last N values per group
const sales = db.collection('sales');
await sales.insertMany([
{ item: "abc", quantity: 10, date: new Date("2023-01-01") },
{ item: "abc", quantity: 5, date: new Date("2023-01-02") },
{ item: "abc", quantity: 8, date: new Date("2023-01-03") },
{ item: "xyz", quantity: 15, date: new Date("2023-01-01") },
{ item: "xyz", quantity: 7, date: new Date("2023-01-02") },
{ item: "xyz", quantity: 3, date: new Date("2023-01-03") }
]);
const accumulatorResult = await sales.aggregate([
{ $group: { _id: "$item", lastTwoQuantities: { $lastN: { input: "$quantity", n: 2 } } } }
]).toArray();
console.log('Accumulator result:', accumulatorResult);
// Expression usage: last N elements of an array field
const inventory = db.collection('inventory');
await inventory.insertMany([
{ _id: 1, item: "abc", tags: ["red", "green", "blue", "yellow", "purple"] },
{ _id: 2, item: "xyz", tags: ["alpha", "beta", "gamma"] }
]);
const expressionResult = await inventory.aggregate([
{ $project: { lastThreeTags: { $lastN: { input: "$tags", n: 3 } } } }
]).toArray();
console.log('Expression result:', expressionResult);
// Window operator usage: last N values over a window in each partition
const stockPrices = db.collection('stockPrices');
await stockPrices.insertMany([
{ _id: 1, ticker: "ABC", hour: 1, price: 50 },
{ _id: 2, ticker: "ABC", hour: 2, price: 45 },
{ _id: 3, ticker: "ABC", hour: 3, price: 60 },
{ _id: 4, ticker: "ABC", hour: 4, price: 40 },
{ _id: 5, ticker: "XYZ", hour: 1, price: 30 },
{ _id: 6, ticker: "XYZ", hour: 2, price: 35 },
{ _id: 7, ticker: "XYZ", hour: 3, price: 25 }
]);
const windowResult = await stockPrices.aggregate([
{
$setWindowFields: {
partitionBy: "$ticker",
sortBy: { hour: 1 },
output: {
lastTwoSoFar: {
$lastN: { input: "$price", n: 2 },
window: { documents: ["unbounded", "current"] }
}
}
}
}
]).toArray();
console.log('Window result:', windowResult);
} finally {
await client.close();
}
}
example();
- Python
-
from pymongo import MongoClient
from datetime import datetime
def example():
client = MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false')
try:
db = client['test']
# Accumulator usage: last N values per group
sales = db['sales']
sales.insert_many([
{ 'item': 'abc', 'quantity': 10, 'date': datetime(2023, 1, 1) },
{ 'item': 'abc', 'quantity': 5, 'date': datetime(2023, 1, 2) },
{ 'item': 'abc', 'quantity': 8, 'date': datetime(2023, 1, 3) },
{ 'item': 'xyz', 'quantity': 15, 'date': datetime(2023, 1, 1) },
{ 'item': 'xyz', 'quantity': 7, 'date': datetime(2023, 1, 2) },
{ 'item': 'xyz', 'quantity': 3, 'date': datetime(2023, 1, 3) }
])
accumulator_result = list(sales.aggregate([
{ '$group': { '_id': '$item', 'lastTwoQuantities': { '$lastN': { 'input': '$quantity', 'n': 2 } } } }
]))
print('Accumulator result:', accumulator_result)
# Expression usage: last N elements of an array field
inventory = db['inventory']
inventory.insert_many([
{ '_id': 1, 'item': 'abc', 'tags': ['red', 'green', 'blue', 'yellow', 'purple'] },
{ '_id': 2, 'item': 'xyz', 'tags': ['alpha', 'beta', 'gamma'] }
])
expression_result = list(inventory.aggregate([
{ '$project': { 'lastThreeTags': { '$lastN': { 'input': '$tags', 'n': 3 } } } }
]))
print('Expression result:', expression_result)
# Window operator usage: last N values over a window in each partition
stock_prices = db['stockPrices']
stock_prices.insert_many([
{ '_id': 1, 'ticker': 'ABC', 'hour': 1, 'price': 50 },
{ '_id': 2, 'ticker': 'ABC', 'hour': 2, 'price': 45 },
{ '_id': 3, 'ticker': 'ABC', 'hour': 3, 'price': 60 },
{ '_id': 4, 'ticker': 'ABC', 'hour': 4, 'price': 40 },
{ '_id': 5, 'ticker': 'XYZ', 'hour': 1, 'price': 30 },
{ '_id': 6, 'ticker': 'XYZ', 'hour': 2, 'price': 35 },
{ '_id': 7, 'ticker': 'XYZ', 'hour': 3, 'price': 25 }
])
window_result = list(stock_prices.aggregate([
{
'$setWindowFields': {
'partitionBy': '$ticker',
'sortBy': { 'hour': 1 },
'output': {
'lastTwoSoFar': {
'$lastN': { 'input': '$price', 'n': 2 },
'window': { 'documents': ['unbounded', 'current'] }
}
}
}
}
]))
print('Window result:', window_result)
finally:
client.close()
example()