View a markdown version of this page

$first - Amazon DocumentDB

$first

New from version 5.0.

Not supported by Elastic cluster.

The $first operator in Amazon DocumentDB returns the first document from a grouped set of documents. It is commonly used in aggregation pipelines to retrieve the first document that matches a specific condition.

Parameters

  • expression: The expression to return as the first value in each group.

Example (MongoDB Shell)

The following example demonstrates the use of the $first operator to retrieve the first item value encountered for each category during the aggregation.

Note: $first returns the first document based on the current order of documents in the pipeline. To ensure a specific order (e.g., by date, price, etc.), a $sort stage should be used before the $group stage.

Create sample documents

db.products.insertMany([ { _id: 1, item: "abc", price: 10, category: "food" }, { _id: 2, item: "jkl", price: 20, category: "food" }, { _id: 3, item: "xyz", price: 5, category: "toy" }, { _id: 4, item: "abc", price: 5, category: "toy" } ]);

Query example

db.products.aggregate([ { $group: { _id: "$category", firstItem: { $first: "$item" } } } ]);

Output

[ { "_id" : "food", "firstItem" : "abc" }, { "_id" : "toy", "firstItem" : "xyz" } ]

Window operator usage example (MongoDB Shell)

New from version 8.0.2.

The $first 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 first document in each window. You specify the operator under the output field, and optionally define the window boundaries with a window document.

Note

When used as a window operator in $setWindowFields, $first 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 first (earliest) price recorded in each partition.

db.stockPrices.aggregate([ { $setWindowFields: { partitionBy: "$ticker", sortBy: { hour: 1 }, output: { firstPrice: { $first: "$price", window: { documents: ["unbounded", "current"] } } } } } ]);

Output

[ { "_id": 1, "ticker": "ABC", "hour": 1, "price": 50, "firstPrice": 50 }, { "_id": 2, "ticker": "ABC", "hour": 2, "price": 45, "firstPrice": 50 }, { "_id": 3, "ticker": "ABC", "hour": 3, "price": 60, "firstPrice": 50 }, { "_id": 4, "ticker": "ABC", "hour": 4, "price": 40, "firstPrice": 50 }, { "_id": 5, "ticker": "XYZ", "hour": 1, "price": 30, "firstPrice": 30 }, { "_id": 6, "ticker": "XYZ", "hour": 2, "price": 35, "firstPrice": 30 }, { "_id": 7, "ticker": "XYZ", "hour": 3, "price": 25, "firstPrice": 30 } ]

Each document is augmented with firstPrice, the price from the first document in its window (the earliest hour in the partition).

Code examples

To view a code example for using the $first operator, choose the tab for the language that you want to use. The following examples show both accumulator usage (in $group) and window operator usage (in $setWindowFields):

Node.js
const { MongoClient } = require('mongodb'); async function example() { const uri = 'mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false'; const client = new MongoClient(uri); try { await client.connect(); const db = client.db('test'); // Accumulator usage: first value per group const products = db.collection('products'); await products.insertMany([ { _id: 1, item: "abc", price: 10, category: "food" }, { _id: 2, item: "jkl", price: 20, category: "food" }, { _id: 3, item: "xyz", price: 5, category: "toy" }, { _id: 4, item: "abc", price: 5, category: "toy" } ]); const accumulatorResult = await products.aggregate([ { $group: { _id: "$category", firstItem: { $first: "$item" } } } ]).toArray(); console.log('Accumulator result:', accumulatorResult); // Window operator usage: first 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: { firstPrice: { $first: "$price", window: { documents: ["unbounded", "current"] } } } } } ]).toArray(); console.log('Window result:', windowResult); } catch (error) { console.error('Error:', error); } finally { await client.close(); } } example();
Python
from pymongo import MongoClient from pprint import pprint def example(): client = None try: client = MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false') db = client['test'] # Accumulator usage: first value per group products = db['products'] products.insert_many([ { '_id': 1, 'item': 'abc', 'price': 10, 'category': 'food' }, { '_id': 2, 'item': 'jkl', 'price': 20, 'category': 'food' }, { '_id': 3, 'item': 'xyz', 'price': 5, 'category': 'toy' }, { '_id': 4, 'item': 'abc', 'price': 5, 'category': 'toy' } ]) accumulator_result = list(products.aggregate([ { '$group': { '_id': '$category', 'firstItem': { '$first': '$item' } } } ])) pprint(accumulator_result) # Window operator usage: first 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_result = list(stock_prices.aggregate([ { '$setWindowFields': { 'partitionBy': '$ticker', 'sortBy': { 'hour': 1 }, 'output': { 'firstPrice': { '$first': '$price', 'window': { 'documents': ['unbounded', 'current'] } } } } } ])) pprint(window_result) except Exception as e: print(f"An error occurred: {e}") finally: if client: client.close() example()