Use built-in text and geospatial index families with their exact restrictions while separating them from MongoDB Search/Vector Search and recording 8.3 geospatial compatibility.
Text and Geospatial Index Families: Capabilities, Restrictions, and Dedicated Search Alternatives
Batch heterogeneous writes safely, interpret partial success, compare ordered and unordered execution, and use modern cross-namespace bulk APIs without assuming all-or-nothing behavior.
Learning objectives
Use self-managed text indexes for basic $text search while understanding their one-index, storage, hint, sort, and language limitations.
Differentiate built-in text indexes from MongoDB Search and Vector Search rather than treating them as interchangeable names.
Create a 2dsphere index on GeoJSON and use longitude/latitude order correctly for spherical proximity queries.
Explain why 2d indexes belong to legacy flat-plane coordinate pairs and should not be used for GeoJSON spherical workloads.
Record the MongoDB 8.3 2dsphereIndexVersion 4 compatibility boundary in upgrade/downgrade planning.
This lesson pins MongoDB Community Server
8.3.8 with
mongodb/mongodb-community-server:8.3.8-ubuntu2204-slim
and mongosh 2.10.0. The server is a disposable
standalone published only on loopback
127.0.0.1:27071. Authentication and TLS are
disabled only for this isolated lab. Feature Compatibility
Version (FCV) is observed but never changed. Default read/write
concern and primary read preference apply. Atlas, KMS, and
Enterprise Advanced are not mandatory. MongoDB Search and Vector
Search are discussed as separate modern search capabilities, but
they are not required for the mandatory local lab. The local lab
uses the built-in self-managed text and
2dsphere index families only. Runtime output shown
as “expected” is documentation-derived because this generation
environment has no Docker/mongod/mongosh runtime.
Specialized indexes are useful only when their eligibility rules match the workload. Every lab therefore inspects index metadata, matching and non-matching query shapes, explain evidence, and state transitions. Tiny fixtures prove semantics—not production latency, cache behavior, or sharded-cluster distribution.
1. “Search index” can mean different subsystems
The built-in text index supports the
$text operator on string content in self-managed
MongoDB. It performs language-aware tokenization/stemming and
has important limits: only one text index per collection (though
it may contain multiple fields), text queries cannot be hinted,
text indexes cannot cover queries, and they add an entry per
unique stemmed term. Current MongoDB documentation recommends
MongoDB Search or MongoDB Vector Search for richer full-text,
semantic, hybrid, and generative-search workloads. Those use a
different search subsystem and are taught later in Chapter 21.
| Capability | Built-in text | MongoDB Search / Vector Search |
|---|---|---|
| Mandatory local availability | Yes on Community self-managed | Separate deployment/service capability; not required here. |
| Query API | $text / textScore |
Search/vector aggregation operators and dedicated search indexes. |
| Index count | At most one text index per collection | Multiple dedicated search indexes are supported depending on deployment. |
| Semantic/vector retrieval | No | Vector Search is designed for vector similarity; Search offers richer full-text features. |
2. Build and query a basic self-managed text index
docker rm -f atlasmart-mongo-ch11-l5 2>/dev/null || truedocker volume rm atlasmart-mongo-ch11-l5-data 2>/dev/null || truedocker run -d --name atlasmart-mongo-ch11-l5 \ -p 127.0.0.1:27071:27017 \ -v atlasmart-mongo-ch11-l5-data:/data/db \ mongodb/mongodb-community-server:8.3.8-ubuntu2204-slimmongosh "mongodb://127.0.0.1:27071/atlasmart?directConnection=true" --quiet --eval \'printjson({server:db.version(),hello:db.hello().isWritablePrimary}); printjson(db.getSiblingDB("admin").runCommand({getParameter:1,featureCompatibilityVersion:1}))'
const p=db.products_ch11_l5;p.drop();p.insertMany([ {_id:1,sku:"P1",name:"Travel USB Charger",description:"compact fast charger for travel and phone",category:"electronics"}, {_id:2,sku:"P2",name:"USB-C Cable",description:"durable braided charging cable",category:"electronics"}, {_id:3,sku:"P3",name:"Travel Backpack",description:"lightweight carry-on backpack for travel",category:"bags"}, {_id:4,sku:"P4",name:"Desk Lamp",description:"adjustable warm desk light",category:"home"}]);print(p.createIndex({name:"text",description:"text"},{name:"txt_name_description",weights:{name:5,description:1},default_language:"english"}));printjson(p.getIndexes());
const p=db.products_ch11_l5;printjson(p.find( {$text:{$search:"travel charger"}}, {_id:0,sku:1,name:1,score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}}).toArray());try{ printjson(p.find({$text:{$search:"usb"}}).hint({category:1}).toArray());}catch(e){ printjson({name:e.name,code:e.code,message:e.message}); }
Text indexes can be substantially larger and more expensive to update than ordered scalar indexes because tokenized/stemmed terms create many index entries. Do not add a wildcard text index simply because “search everything” sounds convenient.
3. Geospatial families encode a geometry model
A 2dsphere index supports GeoJSON and spherical
calculations appropriate to Earth-like surfaces. A
2d index is intended for legacy coordinate
pairs and flat Euclidean calculations. Choosing the wrong family
is a semantic error, not merely a performance issue. For GeoJSON
longitude/latitude data, coordinates must be listed as
[longitude, latitude].
const s=db.stores_ch11_l5;s.drop();s.insertMany([ {_id:1,name:"AtlasMart Central",location:{type:"Point",coordinates:[-73.9857,40.7484]}}, {_id:2,name:"AtlasMart Park",location:{type:"Point",coordinates:[-73.9712,40.7831]}}, {_id:3,name:"AtlasMart Downtown",location:{type:"Point",coordinates:[-74.0060,40.7128]}}, {_id:4,name:"Warehouse no map"}]);print(s.createIndex({location:"2dsphere"},{name:"geo_location"}));printjson(s.getIndexes());printjson(s.find({location:{$near:{$geometry:{type:"Point",coordinates:[-73.9851,40.7589]},$maxDistance:7000}}},{_id:0,name:1,location:1}).toArray());
Expected semantic facts:- GeoJSON Point coordinates are [longitude, latitude], not [latitude, longitude].- $near with GeoJSON requires a 2dsphere index and returns nearest-to-farthest order.- 2d indexes are for legacy coordinate pairs on a flat plane, not GeoJSON objects.- 2dsphere indexes are sparse with respect to the geospatial field; the unmapped warehouse is not indexed by that geo key.- MongoDB 8.3 creates 2dsphere index version 4 by default. A downgrade below FCV 8.3 requires removing version-4 2dsphere indexes first.
4. Deliberately wrong: reverse coordinates and mix 2d with GeoJSON
Reversing latitude/longitude can produce an invalid point or a
geographically wrong point. Likewise, a 2d index
does not index GeoJSON objects; use 2dsphere for
spherical GeoJSON workloads.
const s=db.stores_ch11_l5;try{ printjson(s.find({location:{$near:{$geometry:{type:"Point",coordinates:[40.7589,-73.9851]},$maxDistance:7000}}}).toArray());}catch(e){ printjson({name:e.name,code:e.code,message:e.message}); }try{ db.legacy_geo_ch11_l5.drop(); db.legacy_geo_ch11_l5.insertOne({_id:1,location:{type:"Point",coordinates:[-73.9857,40.7484]}}); db.legacy_geo_ch11_l5.createIndex({location:"2d"});}catch(e){ printjson({name:e.name,code:e.code,message:e.message}); }
5. MongoDB 8.3 compatibility: 2dsphere version 4
MongoDB 8.3 makes 2dsphereIndexVersion:4 the
default for newly created 2dsphere indexes. This is not just
metadata trivia: the current documentation states that before
downgrading FCV below 8.3, version-4 2dsphere indexes must be
dropped. Therefore geospatial index inventories belong in
upgrade/downgrade runbooks.
Use the default geospatial index version unless a documented compatibility requirement says otherwise. Pinning an older version without a reason can preserve old behavior and complicate future upgrades.
6. Verification, cleanup, and production judgment
Verification checklist
- The products collection has exactly one multi-field text index.
-
$textreturns scored results and the hint attempt is treated as unsupported. -
The stores collection uses GeoJSON
Pointvalues and a2dsphereindex. - The proximity query uses longitude first and meters for GeoJSON maxDistance.
- The lesson explicitly distinguishes 2d flat-plane legacy coordinates from 2dsphere GeoJSON.
- The 8.3 default 2dsphere index version and FCV downgrade consequence are recorded.
- MongoDB Search/Vector Search are described as separate capabilities, not silently substituted into the local lab.
Production judgment. Use built-in text indexes when their basic lexical semantics and self-managed simplicity are sufficient; move to MongoDB Search when analyzers, richer ranking/search features, or multiple search indexes justify the separate subsystem, and to Vector Search for semantic similarity workloads. Use 2dsphere for Earth-like GeoJSON geometry and validate coordinate order/types before indexing. Geospatial and text indexes have substantial storage/write costs and special planner restrictions. Monitor query quality, index size, build time, update latency, and compatibility during upgrades. This completes the specialized-index survey and leads to Chapter 12, where index existence is no longer the question—the focus becomes reading real query plans, candidate selection, plan cache behavior, profiling, and slow-query diagnosis.
docker rm -f atlasmart-mongo-ch11-l5docker volume rm atlasmart-mongo-ch11-l5-data
Check your understanding
- How many built-in text indexes can one collection have?
- Can a $text query use hint()?
- What coordinate order does GeoJSON use for longitude/latitude?
- When should you use 2d instead of 2dsphere?
- What new 2dsphere compatibility fact matters in MongoDB 8.3?
Review the answers
1. At most one, though that text index can include multiple string fields.
2. No. Text queries do not support hinting an index.
3. [longitude, latitude].
4. For legacy coordinate pairs and flat Euclidean-plane calculations, not GeoJSON spherical workloads.
5. Newly created 2dsphere indexes default to version 4, and downgrading FCV below 8.3 requires removing version-4 2dsphere indexes first.
Authoritative references
- MongoDB 8.3 release notes — Current 8.3 baseline and patch-sensitive behavior; re-check before reproduction.
- Index types — Current index-family overview and boundaries.
- Explain results — Planner and execution evidence used throughout this chapter.
- mongosh changelog — mongosh version used for chapter commands.
- Text indexes on self-managed deployments — Built-in $text capabilities, cost, and current recommendation toward Search/Vector Search.
- Text index restrictions — One-text-index, hint, and sort restrictions.
- 2dsphere indexes — GeoJSON/spherical semantics and MongoDB 8.3 index version 4.
- 2d indexes — Legacy coordinate pairs and flat-plane semantics.
- Geospatial queries — GeoJSON, coordinate order, operators, and geometry-model boundaries.