Database Query Optimization Guide
Overview
This optimization eliminates unnecessary database queries when generating thumbnail URLs by implementing:
- Website configuration caching - Singleton data cached at startup
- Module slug denormalization - Store module_slug directly on items
Performance Impact
Before:
- 2 database queries per thumbnail generation (websiteManagement + module)
- Sequential execution (~100-200ms total)
After:
- 0 database queries in normal operation (cached + denormalized)
- Fallback: 1 query only if module_slug missing (~50ms)
- ~100-200ms faster per request
Implementation Details
1. Website Config Cache (src/utils/websiteConfig.util.ts)
Caches the website base URL at application startup:
import { getWebsiteBaseUrl, buildThumbnailUrl } from "../utils/websiteConfig.util";
// Get cached base URL
const baseUrl = getWebsiteBaseUrl();
// Build thumbnail URL
const url = buildThumbnailUrl(moduleSlug, thumbnailSlug);
Initialization: Automatically called in src/index.ts after DB connection
Cache refresh: Automatically refreshed when website settings are updated via websiteManagement.controller.ts
2. Module Slug Denormalization
Added module_slug field to:
ItemDocumentinterface (base.controller.ts)INewsinterface (interfaces/news.interface.ts)- News model schema (models/news.model.ts)
Auto-population:
- New items:
module_slugset during creation - Updated items: Fallback query if missing, then stored for future use
3. Migration for Existing Data
Run the migration script to populate module_slug for existing records:
npx ts-node src/scripts/migrateModuleSlug.ts
Important: Run this once after deploying the new code.
Adding module_slug to Other Models
If you have other models with module_id (e.g., Product, Event), add the field:
- Update the interface:
export interface IProduct extends Document {
module_id: Types.ObjectId;
module_slug?: string; // Add this
// ... other fields
}
- Update the schema:
const ProductSchema = new Schema<IProduct>({
module_id: {
type: Schema.Types.ObjectId,
required: true,
},
module_slug: { // Add this
type: String,
required: false,
},
// ... other fields
});
- Update the migration script (
src/scripts/migrateModuleSlug.ts) to include the new model.
Monitoring
The cache initialization logs to console on startup:
[WebsiteConfig] Initialized with base URL: example.com
If initialization fails, it falls back to localhost and logs a warning.
Troubleshooting
Error: "Website configuration not initialized"
- Ensure
initializeWebsiteConfig()is called insrc/index.tsafter DB connection - Check that websiteManagement collection has a document with
singleton: "singleton"
Thumbnail URLs showing wrong domain
- Cache may be stale - restart the server or update website settings to trigger refresh
- Manually refresh: Call
refreshWebsiteConfig()from websiteConfig.util
Missing module_slug on items
- Run the migration script for existing data
- New items should auto-populate the field
- Fallback query will populate it on next update