Skip to content

Use Case 13: Declaring Indexes (Single‑field, Composite, Unique)

Scenario: You want to ensure your collection has the right indexes for fast queries and data integrity. This doc shows how to register models with different index configurations using ModelRegistry.register and have them created automatically during startup.


šŸ“¦ What’s New?

Component Description
ModelRegistry.register (indexes argument) Accepts a list of index specifications. Each spec can be a tuple (field, direction) or a full dict with keys and optional options (e.g., unique).
ModelRegistry.initialize_all Scans all registered collections and creates the defined indexes on application start‑up.

šŸš€ Example

Python
from mongo_ops import ModelRegistry, BaseDocument
from pymongo import ASCENDING, DESCENDING

# ----------------------------------------------------------------------
# 1ļøāƒ£ Simple single‑field index (e.g., email lookup)
# ----------------------------------------------------------------------
class User(BaseDocument):
    username: str
    email: str

ModelRegistry.register(
    collection_name="users",
    model=User,
    indexes=[("email", ASCENDING)],  # creates an index on "email"
)

# ----------------------------------------------------------------------
# 2ļøāƒ£ Composite index (e.g., queries filtering by user and creation date)
# ----------------------------------------------------------------------
class BlogPost(BaseDocument):
    author_id: str
    created_at: str
    title: str

ModelRegistry.register(
    collection_name="posts",
    model=BlogPost,
    indexes=[[("author_id", ASCENDING), ("created_at", DESCENDING)]],  # compound index
)

# ----------------------------------------------------------------------
# 3ļøāƒ£ Unique index (e.g., enforce unique usernames)
# ----------------------------------------------------------------------
ModelRegistry.register(
    collection_name="users",
    model=User,
    indexes=[
        {
            "keys": [("username", ASCENDING)],
            "options": {"unique": True, "name": "uq_username"},
        }
    ],
)

# ----------------------------------------------------------------------
# 4ļøāƒ£ Initialise all indexes during FastAPI startup
# ----------------------------------------------------------------------
from mongo_ops import MongoConnectionManager
from contextlib import asynccontextmanager

@asynccontextmanager
async def lifespan(app):
    async with MongoConnectionManager.lifespan(
        uri="mongodb://localhost:27017",
        db_name="mydb",
    ):
        # This will create every index declared above (if it does not already exist)
        await ModelRegistry.initialize_all()
        yield

šŸ’” Tips

  • Idempotence: initialize_all uses create_index, which is safe to run multiple times – MongoDB will skip creation if the index already exists.
  • Index options: You can also set expireAfterSeconds for TTL indexes, sparse for sparse indexes, etc., by adding them to the options dict.
  • Verification: After the app starts, you can verify indexes with the Mongo shell:
    JavaScript
    db.<collection>.getIndexes()