MongoDB $indexOfArray Operator

Beginner
⏱️ 8 min read
📚 Updated: Jul 2026
🎯 4 Examples
Array

What You’ll Learn

The $indexOfArray operator finds the position of a value inside an array. It returns a zero-based index (like JavaScript’s indexOf) or -1 when the value is not found. Use it in aggregation pipelines to locate tags, statuses, or items in embedded arrays.

01

Array Index

Find a value’s position.

02

Syntax

Array, search, start, end.

03

$project Stage

Add computed index fields.

04

Not Found

Returns -1 on miss.

05

Use Cases

Tags, priorities, lookups.

06

Search Range

Optional start and end.

Definition and Usage

In MongoDB’s aggregation framework, the $indexOfArray operator searches an array for the first occurrence of a value and returns its zero-based index. For example, searching [ "js", "mongodb", "node" ] for "mongodb" returns 1. If the value is absent, the result is -1.

You can optionally pass start and end indexes to search only part of the array. This is useful when you need the position of a value after a certain point, or when working with sliced data.

💡
Beginner Tip

Think of $indexOfArray as MongoDB’s version of JavaScript’s array.indexOf(value). Use it inside aggregation expression stages like $project and $addFields, not as a standalone query filter operator.

📝 Syntax

The $indexOfArray operator takes an array expression, a search value, and optional range bounds:

mongosh
{
  $indexOfArray: [
    <array expression>,
    <search expression>,
    <start>,   // optional, default 0
    <end>      // optional, default array length
  ]
}

Common Patterns

mongosh
// Basic search in a field array
{ $indexOfArray: [ "$tags", "mongodb" ] }

// Search from index 2 onward
{ $indexOfArray: [ "$scores", 90, 2 ] }

// Check if value exists (index >= 0)
{ $gte: [
    { $indexOfArray: [ "$tags", "featured" ] },
    0
] }

Syntax Rules

  • First argument — the array to search (field path like "$tags" or a literal array).
  • Second argument — the value to find (literal, field reference, or expression).
  • start — optional zero-based index where the search begins (default 0).
  • end — optional index before which the search stops (default array length).
  • Returns -1 when the search value is not found in the specified range.
  • Use inside stages like $project, $addFields, $set, and $cond.

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation expression operator
Syntax{ $indexOfArray: [ array, search, start?, end? ] }
FoundZero-based index (0, 1, 2, …)
Not found-1
Common stages$project, $addFields, $cond
Basic
{
  $indexOfArray: [
    "$tags",
    "mongodb"
  ]
}

Index of "mongodb"

Not found
{
  $indexOfArray: [
  ["a", "b"],
  "z"
  ]
}

Returns -1

With start
{
  $indexOfArray: [
    "$items",
    "apple",
    2
  ]
}

Search from index 2

Exists check
{
  $gte: [
    { $indexOfArray: [
      "$tags", "sale"
    ]},
    0
  ]
}

true if found

Examples Gallery

Walk through sample article data, find tag positions with $project, and combine $indexOfArray with other operators for practical patterns.

📚 Find a Tag Position

Start with an articles collection and locate where a specific tag appears in each document’s tags array.

Sample Input Documents

Suppose you have an articles collection where each document has a tags array:

mongosh
[
  { "_id": ObjectId("609c26812e9274a86871bc6a"), "title": "Intro to MongoDB", "tags": ["database", "mongodb", "nosql"] },
  { "_id": ObjectId("609c26812e9274a86871bc6b"), "title": "Node Basics", "tags": ["javascript", "node", "backend"] },
  { "_id": ObjectId("609c26812e9274a86871bc6c"), "title": "CSS Grid", "tags": ["css", "layout", "frontend"] }
]

Example 1 — Basic $indexOfArray on a Field

Find the index of the "mongodb" tag in each article:

mongosh
db.articles.aggregate([
  {
    $project: {
      title: 1,
      tags: 1,
      mongoTagIndex: {
        $indexOfArray: [ "$tags", "mongodb" ]
      }
    }
  }
])

How It Works

  • Indexes are zero-based: "database" is 0, "mongodb" is 1.
  • When the tag is missing, MongoDB returns -1 instead of throwing an error.
  • Only the first matching index is returned if duplicates exist.

📈 Practical Patterns

Combine $indexOfArray with range bounds, existence checks, and conditional logic.

Example 2 — Search with a Start Index

Find the first "pending" status starting from index 2 in an order’s status history:

mongosh
db.orders.aggregate([
  {
    $project: {
      orderId: 1,
      statusHistory: 1,
      pendingAfterStep2: {
        $indexOfArray: [
          "$statusHistory",
          "pending",
          2
        ]
      }
    }
  }
])

How It Works

The third argument (start) tells MongoDB to ignore elements before that index. This is helpful when you only care about occurrences after a certain step in a timeline or workflow.

Example 3 — Check Whether a Value Exists

Convert the index into a boolean hasFeaturedTag field:

mongosh
db.articles.aggregate([
  {
    $project: {
      title: 1,
      hasFeaturedTag: {
        $gte: [
          { $indexOfArray: [ "$tags", "featured" ] },
          0
        ]
      }
    }
  }
])

How It Works

When the index is -1, $gte returns false. When the value is found (index 0 or higher), the result is true. For simple membership tests in aggregation, query $in filters documents; this pattern adds a boolean field per document.

Example 4 — $indexOfArray Inside $cond

Label articles based on whether "mongodb" appears in their tags:

mongosh
db.articles.aggregate([
  {
    $project: {
      title: 1,
      category: {
        $cond: [
          {
            $gte: [
              { $indexOfArray: [ "$tags", "mongodb" ] },
              0
            ]
          },
          "database",
          "general"
        ]
      }
    }
  }
])

How It Works

If $indexOfArray finds "mongodb", the index is >= 0 and $cond outputs "database". Otherwise the article is labeled "general". Pair this with $arrayElemAt when you need the element at the found index.

Bonus — Combine with $arrayElemAt

After finding an index, retrieve the neighboring element:

mongosh
db.articles.aggregate([
  {
    $addFields: {
      mongoIndex: {
        $indexOfArray: [ "$tags", "mongodb" ]
      }
    }
  },
  {
    $project: {
      title: 1,
      tagAfterMongo: {
        $arrayElemAt: [
          "$tags",
          { $add: [ "$mongoIndex", 1 ] }
        ]
      }
    }
  }
])

How It Works

First compute the index of "mongodb", then use $arrayElemAt with index + 1 to get the next tag. If "mongodb" is last or missing, $arrayElemAt returns null.

🚀 Use Cases

  • Tag and category lookup — find where a label appears in a document’s tag array.
  • Workflow timelines — locate the first "pending" or "approved" step in a status history.
  • Existence checks in aggregation — convert index >= 0 into boolean flags for reporting.
  • Array navigation — combine with $arrayElemAt to read elements before or after a found position.

🧠 How $indexOfArray Works

1

MongoDB reads the array and search value

The pipeline evaluates the array (e.g. "$tags") and the value to find (e.g. "mongodb").

Input
2

$indexOfArray scans the range

MongoDB walks from start to end, comparing each element to the search value until a match is found.

Search
3

The index is stored in the pipeline

A zero-based index is written to your output field, or -1 if no match exists in the range.

Output
=

Precise array positions

You get index data ready for boolean checks, conditional labels, and paired array lookups.

Conclusion

The $indexOfArray operator is a focused but powerful tool for working with arrays in MongoDB aggregation pipelines. It tells you where a value lives inside an array — not just whether it exists — which unlocks navigation, categorization, and timeline analysis patterns.

For beginners, the key idea is simple: wrap your array and search value in { $indexOfArray: [ ... ] } inside a stage like $project. A result of -1 means “not found”; any index 0 or higher means the value was located.

💡 Best Practices

✅ Do

  • Check for -1 before using the index with $arrayElemAt
  • Use $gte: [ { $indexOfArray: ... }, 0 ] for existence booleans
  • Pass start and end when you only need a partial search
  • Remember indexes are zero-based (first element is 0)
  • Pair with $cond for category or status labeling

❌ Don’t

  • Use $indexOfArray as a query filter outside expressions
  • Confuse it with query operator $in (different purpose)
  • Assume it finds all occurrences (only the first match is returned)
  • Forget that missing values return -1, not null
  • Use it on strings directly — use $indexOfBytes or $indexOfCP for strings

Key Takeaways

Knowledge Unlocked

Five things to remember about $indexOfArray

Use these points when locating values inside arrays.

5
Core concepts
📝 02

Four Arguments

array, search, start, end.

Syntax
🛠 03

Pipeline Stages

$project, $addFields, $cond.

Usage
🔍 04

Not Found

Returns -1.

Edge case
📦 05

Pair Operators

$arrayElemAt, $cond.

Pattern

❓ Frequently Asked Questions

$indexOfArray returns the zero-based index of the first occurrence of a search value inside an array. It is an aggregation expression operator used inside stages like $project and $addFields.
The syntax is { $indexOfArray: [ <array>, <search>, <start>, <end> ] }. The start and end arguments are optional and limit the search range within the array.
It returns -1 when the search value is not present in the array (within the optional start/end range). This matches JavaScript Array.indexOf() behavior.
$in is a query operator that filters documents when a field matches any value in a list. $indexOfArray is an aggregation expression that returns the numeric position of a value inside an array field.
Yes. start is the index to begin searching (default 0). end is the index before which searching stops (default array length). This lets you search only part of an array.

Continue the Operator Series

Move on to $indexOfBytes for string searches, or review $arrayElemAt to read elements by index.

Next: $indexOfBytes →

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.

5 people found this page helpful