Skip to main content

Overview

The OpenSearch migration system provides a zero-downtime approach to reindexing products (courses and consultations) into new index versions. It uses an alias-based architecture where applications query aliases instead of direct indices, allowing seamless index swaps.

Architecture Components

1. OpenSearchController (opensearch.controller.ts)

The main API entry point for triggering migrations and reindexing operations. Key Endpoints:

One-Click Product Migration

Response:

Other Useful Endpoints

  • GET /opensearch/index-status - View current index versions and alias mappings
  • POST /opensearch/reindex-batch - Batch reindex without creating new versions
  • POST /opensearch/reindex-document - Reindex a single document by ID
  • POST /opensearch/migrate/:index/:version - Migrate a specific index to a version
  • POST /opensearch/drop-all - Development only: drop all indices

Migration Process Flow

Step-by-Step: What Happens When You Click “Migrate”


Detailed Component Breakdown

2. ProductIndexMigrationService (product-index-migration.service.ts)

Purpose: Enqueues migration jobs into BullMQ queue. Key Method:

3. ProductMigrationWorker (product-migration.worker.ts)

Purpose: Background worker that orchestrates the entire migration process. Key Responsibilities:
  1. Version Resolution
  2. Create New Index
  3. Batch Processing
  4. Verification
  5. Alias Switch (Zero-Downtime)

4. ElasticService (elastic.service.ts)

Core Methods:

createNewIndexVersion(index, version)

Creates a new versioned index with proper mappings.

switchAliasToNew(alias, newIndex, context)

Atomically switches alias from old index to new index.

verifyReindex(sourceIndex, destIndex)

Ensures document counts match between old and new indices.

Index Naming Convention

Application Code: Always queries the alias (e.g., course), never the versioned index directly.

Migration Strategies

Strategy 1: Full Migration (All Products)

What happens:
  • Auto-increments version for both courses and consultations
  • Creates course_v2 and consultation_v2
  • Reindexes all documents
  • Switches aliases atomically

Strategy 2: Incremental Migration (Updated Products Only)

What happens:
  • Only migrates products updated after the specified date
  • Useful for quick updates without full reindex

Strategy 3: Single Product Type

What happens:
  • Only migrates courses to version 3
  • Consultations remain unchanged

Monitoring Migration Progress

Check Index Status

Response:

Safety Features

1. Verification Before Alias Switch

The system verifies document counts match before switching aliases:

2. Atomic Alias Updates

OpenSearch’s updateAliases API ensures atomic operations—no downtime.

3. Job Tracking

All migrations are tracked via BullMQ jobs with progress updates and logs.

4. Metadata Tracking

The ElasticIndexMetadataService records:
  • Current active version per environment
  • Migration timestamps
  • Document counts
  • Job IDs

Common Use Cases

Use Case 1: Schema Change

You updated the OpenSearch mapping for courses. Solution:

Use Case 2: Data Corruption

Some documents are corrupted in the current index. Solution:

Use Case 3: Performance Optimization

You want to reindex with better settings (shards, replicas). Solution:
  1. Update mapping in code
  2. Trigger migration
  3. Old index remains until you manually delete it

Configuration

Alias Mapping (Config)

Environment Variables


Best Practices

  1. Always Use Aliases in Application Code
  2. Monitor Job Progress Use BullMQ dashboard or logs to track migration jobs.
  3. Test in Staging First Always test migrations in staging before production.
  4. Clean Up Old Indices After verifying new index works, manually delete old versions:
  5. Use Incremental Updates for Large Datasets For millions of documents, use updatedSince to avoid full reindex.

Troubleshooting

Issue: “Reindex verification failed”

Cause: Document counts don’t match between old and new indices. Solution:
  • Check for errors in child reindex jobs
  • Verify database queries aren’t filtered incorrectly
  • Retry migration

Issue: “Index already exists”

Cause: Trying to create a version that already exists. Solution:
  • Increment version number manually
  • Or delete the existing versioned index first

Issue: Migration stuck

Cause: Child jobs failing or queue issues. Solution:
  • Check BullMQ queue health
  • Review worker logs
  • Restart workers if needed

Summary: One-Click Migration Flow

  1. Client sends POST /elastic/products/migrate { "type": "all" }
  2. Controller enqueues job and returns jobId
  3. Worker creates new versioned indices (course_v2, consultation_v2)
  4. Worker dispatches batch reindex jobs (parallel processing)
  5. Worker waits for all batches to complete
  6. Worker verifies document counts match
  7. Worker atomically switches aliases to new indices
  8. Worker records metadata and completes job
  9. Application continues querying aliases with zero downtime
Result: Products are now in new indices with updated mappings/data, and users experienced no downtime! 🎉