$last
The $last operator in Amazon DocumentDB is used to return the last element in an array that matches the query criteria. It is particularly useful for retrieving the most recent or the last element in an array that satisfies a specific condition.
Parameters
Example (MongoDB Shell)
The following example demonstrates the use of the $last operator in combination with $filter to retrieve the last element from an array that meets a specific condition (e.g., subject is 'science').
Create sample documents
db.collection.insertMany([
{
"_id": 1,
"name": "John",
"scores": [
{ "subject": "math", "score": 82 },
{ "subject": "english", "score": 85 },
{ "subject": "science", "score": 90 }
]
},
{
"_id": 2,
"name": "Jane",
"scores": [
{ "subject": "math", "score": 92 },
{ "subject": "english", "score": 88 },
{ "subject": "science", "score": 87 }
]
},
{
"_id": 3,
"name": "Bob",
"scores": [
{ "subject": "math", "score": 75 },
{ "subject": "english", "score": 80 },
{ "subject": "science", "score": 85 }
]
}
]);
Query example
db.collection.aggregate([
{ $match: { name: "John" } },
{
$project: {
name: 1,
lastScienceScore: {
$last: {
$filter: {
input: "$scores",
as: "score",
cond: { $eq: ["$$score.subject", "science"] }
}
}
}
}
}
]);
Output
[
{
_id: 1,
name: 'John',
lastScienceScore: { subject: 'science', score: 90 }
}
]
Window operator usage example (MongoDB Shell)
New from version 8.0.2.
The $last operator can also be used as a window operator in the $setWindowFields stage. In this context, it returns the value of the expression from the last document in each window. You specify the operator under the output field, and optionally define the window boundaries with a window document.
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 last (latest) price recorded in each partition.
db.stockPrices.aggregate([
{
$setWindowFields: {
partitionBy: "$ticker",
sortBy: { hour: 1 },
output: {
lastPrice: {
$last: "$price",
window: { documents: ["unbounded", "unbounded"] }
}
}
}
}
]);
Output
[
{ "_id": 1, "ticker": "ABC", "hour": 1, "price": 50, "lastPrice": 40 },
{ "_id": 2, "ticker": "ABC", "hour": 2, "price": 45, "lastPrice": 40 },
{ "_id": 3, "ticker": "ABC", "hour": 3, "price": 60, "lastPrice": 40 },
{ "_id": 4, "ticker": "ABC", "hour": 4, "price": 40, "lastPrice": 40 },
{ "_id": 5, "ticker": "XYZ", "hour": 1, "price": 30, "lastPrice": 25 },
{ "_id": 6, "ticker": "XYZ", "hour": 2, "price": 35, "lastPrice": 25 },
{ "_id": 7, "ticker": "XYZ", "hour": 3, "price": 25, "lastPrice": 25 }
]
Each document is augmented with lastPrice, the price from the last document in its window (the latest hour in the partition).
Code examples
To view a code example for using the $last operator, choose the tab for the language that you want to use. The following examples show both expression usage (in $project) and window operator usage (in $setWindowFields):
- Node.js
-
const { MongoClient } = require('mongodb');
async function example() {
const client = await MongoClient.connect('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false');
const db = client.db('test');
// Expression usage: last element of a filtered array
const collection = db.collection('collection');
await collection.insertMany([
{
_id: 1,
name: "John",
scores: [
{ subject: "math", score: 82 },
{ subject: "english", score: 85 },
{ subject: "science", score: 90 }
]
},
{
_id: 2,
name: "Jane",
scores: [
{ subject: "math", score: 92 },
{ subject: "english", score: 88 },
{ subject: "science", score: 87 }
]
},
{
_id: 3,
name: "Bob",
scores: [
{ subject: "math", score: 75 },
{ subject: "english", score: 80 },
{ subject: "science", score: 85 }
]
}
]);
const expressionResult = await collection.aggregate([
{ $match: { name: "John" } },
{
$project: {
name: 1,
lastScienceScore: {
$last: {
$filter: {
input: "$scores",
as: "score",
cond: { $eq: ["$$score.subject", "science"] }
}
}
}
}
}
]).toArray();
console.log('Expression result:', JSON.stringify(expressionResult, null, 2));
// Window operator usage: last value within 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: {
lastPrice: {
$last: "$price",
window: { documents: ["unbounded", "unbounded"] }
}
}
}
}
]).toArray();
console.log('Window result:', JSON.stringify(windowResult, null, 2));
await client.close();
}
example();
- Python
-
from pymongo import MongoClient
def example():
client = MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false')
db = client.test
# Expression usage: last element of a filtered array
collection = db.collection
collection.insert_many([
{
"_id": 1,
"name": "John",
"scores": [
{ "subject": "math", "score": 82 },
{ "subject": "english", "score": 85 },
{ "subject": "science", "score": 90 }
]
},
{
"_id": 2,
"name": "Jane",
"scores": [
{ "subject": "math", "score": 92 },
{ "subject": "english", "score": 88 },
{ "subject": "science", "score": 87 }
]
},
{
"_id": 3,
"name": "Bob",
"scores": [
{ "subject": "math", "score": 75 },
{ "subject": "english", "score": 80 },
{ "subject": "science", "score": 85 }
]
}
])
expression_pipeline = [
{ "$match": { "name": "John" } },
{
"$project": {
"name": 1,
"lastScienceScore": {
"$last": {
"$filter": {
"input": "$scores",
"as": "score",
"cond": { "$eq": ["$$score.subject", "science"] }
}
}
}
}
}
]
expression_result = list(collection.aggregate(expression_pipeline))
print('Expression result:', expression_result)
# Window operator usage: last value within 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_pipeline = [
{
"$setWindowFields": {
"partitionBy": "$ticker",
"sortBy": { "hour": 1 },
"output": {
"lastPrice": {
"$last": "$price",
"window": { "documents": ["unbounded", "unbounded"] }
}
}
}
}
]
window_result = list(stock_prices.aggregate(window_pipeline))
print('Window result:', window_result)
client.close()
example()