An index scan traverses index keys to find matches for a query condition. In a MongoDB execution plan, it appears as IXSCAN. A typical plan passes matching keys to FETCH, which retrieves the documents; a collection scan appears as COLLSCAN instead. section 7.1.1 section 7.2.1
To check whether a query benefits from an index:
- Create an index that matches the field being queried, such as db.movies.createIndex({ runtime: 1 }). section 7.2.1
- Run db.movies.find({ runtime: 100 }).explain("executionStats"). Look for IXSCAN and its indexName under winningPlan. section 7.2.1
- Compare nReturned with totalKeysExamined and totalDocsExamined. Examining few keys and documents relative to the results can indicate an efficient scan; also check executionTimeMillis. section 7.1.1
An index scan need not fetch documents. If an index contains the fields needed by both the filter and projection, a covered query can return results directly from index entries. Its plan shows IXSCAN beneath PROJECTION_COVERED and can report zero documents examined. Exclude _id when it is not in the index; a multikey index cannot cover a query that returns an array field. section 7.6.8
Index scans across an $or query
For db.movies.find({ $or: [{ year: 1914 }, { "imdb.rating": { $gt: 7 } }] }), each clause can use its own index—but every clause must have index support. A compound index beginning with year does not effectively support the rating clause on its own. Add db.movies.createIndex({ "imdb.rating": 1 }) to avoid the collection scan in this case. section 7.6.4
Listing 7.2 Execution-plan output structure
{
"winningPlan": {
"stage": "FETCH",
"inputStage": {
"stage": "IXSCAN",
"indexName": "yourField_1",
"keyPattern": {
"yourField": 1
},
"indexBounds": {
"yourField": [
"[\"value\", \"value\"]"
]
}
}
},
"executionStats": {
"nReturned": 1,
"executionTimeMillis": 3,
"totalKeysExamined": 1,
"totalDocsExamined": 1
}
}
Inspect how IXSCAN supplies keys to FETCH and how the plan reports index bounds and examined-key counts. section 7.1.1
db.movies.find(
{ year: 1914, "imdb.rating": { $gte: 7 } },
{ title: 1, year: 1, _id: 0 }
).explain("executionStats")
……
winningPlan: {
stage: 'PROJECTION_COVERED',
transformBy: { title: 1, year: 1, _id: 0 },
inputStage: {
stage: 'IXSCAN',
keyPattern: { year: 1, title: 1, 'imdb.rating': 1 },
indexName: 'year_1_title_1_imdb.rating_1'
……
executionStats: {
executionSuccess: true,
nReturned: 2,
executionTimeMillis: 0,
totalKeysExamined: 4,
totalDocsExamined: 0
Compare the covered-query plan: IXSCAN feeds PROJECTION_COVERED, with four keys examined and no documents examined. section 7.6.8


