MongoDB $year Operator

Beginner
5 min read
Updated: Oct 2026
3 examples
Live preview

What Is $year?

$year is a MongoDB aggregation expression that returns the calendar year from a BSON Date as an integer (for example 2024). Use it to label documents, build yearly reports, or filter by year inside a pipeline.

Remember
$year = calendar year for aggregation

{ $year: <dateExpression> }

ISODate("2024-03-15...") → 2024
default timezone → UTC components
null / missing → null

Pair with $month / $week for finer buckets
ISO week year → $isoWeekYear (different near Dec/Jan)
UsePrefer
Calendar year$year
Month within a year$month
ISO week-numbering year$isoWeekYear

How to Use $year in MongoDB

Pass a date field, get an integer year, then project, group, or filter with it.

  1. Choose an expression stage ($addFields, $project, or $group).
  2. Pass a date field (or date expression) to $year.
  3. Use the result as a label, a group key, or inside $expr for year filters.
  4. Add a timezone when midnight boundaries matter in local time.
PieceRequired?Role
$yearYesDate → calendar year integer
Date expressionYesField, literal date, or nested date expr
TimezoneNoOptional local-year extraction

Pseudocode

Pseudocode
for each document:
    d = evaluate(dateExpression)
    if d is null or missing:
        result = null
    else:
        result = calendarYear(d)   // e.g. 2024
    emit { ..., year: result }

Cheat Sheet

Keep these facts handy while extracting years in a pipeline.

TopicDetail
TypeAggregation expression (not a find filter alone)
Syntax{ $year: <dateExpression> }
OutputInteger calendar year (e.g. 2024)
Default zoneUTC date components
Group pattern_id: { $year: "$orderDate" }
Filter pattern$expr: { $eq: [ { $year: "$d" }, 2024 ] }
Nullnull / missing → null

Live Preview

Watch $year pull the calendar year from a date. Pick a sample order date (UTC).

Simulates MongoDB $year using UTC calendar components.

Result
date = 2023-11-20 (UTC)

$year → 2023

{ orderYear: 2023 }

Worked Walkthrough — One Order Date

One order is dated 2024-03-15T14:30:00Z. Goal: get the calendar year for a yearly report label.

Calculation
Document:
  { orderDate: ISODate("2024-03-15T14:30:00Z") }

UTC parts:
  year  = 2024
  month = 3
  day   = 15

$year("$orderDate") → 2024

Use in a report:
  orderYear: 2024

MongoDB Examples

We use a small orders collection across two years. First extract the year, then group revenue by year. Run these in mongosh after inserting the sample data once.

Example 1 — Sample Data

Imagine three orders: one in 2023 and two in 2024. That mix makes yearly grouping easy to see.

mongosh
db.orders.insertMany([
  {
    _id: 1,
    customer: "Alice",
    orderDate: ISODate("2023-11-20T10:00:00Z"),
    amount: 450
  },
  {
    _id: 2,
    customer: "Bob",
    orderDate: ISODate("2024-03-15T14:30:00Z"),
    amount: 320
  },
  {
    _id: 3,
    customer: "Carol",
    orderDate: ISODate("2024-12-01T09:00:00Z"),
    amount: 890
  }
]);

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps three documents in orders. Run find() to see them:

mongosh
db.orders.find()

Read each document like this:

Field in MongoDBExamplePlain English
_id1Document id (row number for this lesson)
customer"Alice"Who placed the order
orderDate2023-11-20Order timestamp (BSON Date)
amount450Order total

How It Works

  1. Insert once. insertMany adds three order documents to orders.
  2. Dates are BSON Dates. ISODate(...) stores a real date, not a string.
  3. find() shows the same shape. Ready for $year in the next examples.

Example 2 — Extract Year

Goal: add an orderYear field with the calendar year from orderDate.

mongosh
db.orders.aggregate([
  {
    $addFields: {
      orderYear: { $year: "$orderDate" }
    }
  }
]);

How It Works

  1. Read the stored date. Alice’s orderDate is 2023-11-20 from Example 1.
  2. Extract the year. $year returns the UTC calendar year as an integer.
  3. Keep all fields. $addFields adds orderYear without removing the original date.

Example 3 — Group by Year

Same orders, but build a yearly revenue summary using $year as the group key.

mongosh
db.orders.aggregate([
  {
    $group: {
      _id: { $year: "$orderDate" },
      orderCount: { $sum: 1 },
      totalRevenue: { $sum: "$amount" }
    }
  },
  { $sort: { _id: 1 } }
]);

How It Works

  1. Same stored documents. Still using Alice, Bob, and Carol from Example 1.
  2. Bucket by year. _id: { $year: "$orderDate" } creates one group per calendar year.
  3. Sum the amounts. 2023 has Alice only (450); 2024 has Bob + Carol (320 + 890 = 1210).
  4. Easy check. 2024 should show orderCount: 2.

Edge Cases & Pitfalls

Check these before using $year in production pipelines.

tz

UTC vs local near midnight

A late-evening local time can still be the next UTC day/year. Pass a timezone when local calendar year matters.

iso

$year ≠ $isoWeekYear

Near Dec/Jan, ISO week years can differ from the wall calendar. Use $isoWeekYear only for ISO week reports.

null

Null and missing become null

Missing date fields return null, not an error. Guard with $ifNull if you need a default.

range

Prefer date-range $match when possible

For large collections, filter with orderDate between Jan 1 and Dec 31 so indexes can help before extracting $year.

Performance Notes

ApproachCostBest for
$year alonePer-document date mathLabels / display fields
$group by $yearConvert + groupAnnual revenue reports
Date-range $match firstFewer docs to convertLarge collections with indexes

Year extraction is cheap compared with large sorts or joins. Prefer a $match on a date range before grouping by year on big collections.

Key Takeaways

  • Role: date → calendar year integer.
  • Reports: great as a $group key for yearly totals.
  • Finer buckets: pair with $month or $week.
  • Timezone: default is UTC; set timezone when local year matters.

One line: $year answers “which calendar year is this date?”—usually for labels and yearly groups.

Frequently Asked Questions

$year returns the calendar year for a BSON Date as an integer, such as 2024. Use it inside aggregation expression stages like $project, $addFields, and $group.
Use { $year: <dateExpression> }. Pass a field like "$orderDate", a literal date, or a date expression. You can also pass { date: <dateExpression>, timezone: <tzExpression> }.
$year is the wall-calendar year. $isoWeekYear is the ISO week-numbering year, which can differ near year boundaries when a date belongs to week 1 or 52/53 of an adjacent ISO year.
By default $year uses the UTC calendar components of the date. Pass a timezone when you need the year in a local zone near midnight boundaries.
$year returns null when the input is null or the field is missing. It does not throw an error for null input.
Yes for finer reports. Use $year alone for annual totals, or combine it with $month / $week so buckets from different years do not collide.

Next: $zip

Merge multiple arrays element-wise inside an aggregation pipeline.

$zip tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

9 people found this page helpful