Migrating MySQL Data to Elasticsearch: A Practical Guide

07 / Sep / 2025 by Rajdeep Dabral 0 comments

Introduction

Elasticsearch has become a go-to choice for building fast, intelligent search experiences. But what if your source of truth is a relational database like MySQL? In this blog, we’ll walk through how we migrated structured relational data into Elasticsearch using Python — with company_registry as a working example.

Why Migrate from MySQL to Elasticsearch?

MySQL is great for transactional workloads (OLTP) but when it comes to full-text search, autocomplete, typo tolerance, or complex filtering, it struggles. Elasticsearch shines here with:

  • Flexible mappings for search fields
  • Support for text analysis (stemming, synonyms, phonetics)
  • Millisecond-level query performance
  • Easy scaling for large datasets
  • To bridge the gap, we need a migration pipeline that fetches data from MySQL, transforms it, and indexes it into Elasticsearch.
pipeline flow diagram

pipeline flow diagram

Setting Up the Basics

We’ll use:

  • MySQL as the data source
  • Elasticsearch (v8+) as the search engine
  • Python + official Elasticsearch client for migration
secure connections to both MySQL and Elasticsearch

Here we set up secure connections to both MySQL and Elasticsearch

Deleting Old Indices

Before creating new indices, it’s a good practice to remove any outdated ones. This prevents mapping conflicts or duplicate records.This ensures your migration always starts on a clean slate.

Delete index Data

Delete index Data

Creating Elasticsearch Mappings

Unlike MySQL, Elasticsearch requires you to define how fields should be indexed. For our company_registry, we use the following mapping:

company registry index

company registry index

This ensures that:

  • companyName supports both full-text and exact match queries.
  • excludeFromSearch is a boolean flag.
  • id is stored as a numeric long.

Transforming the Data

Raw MySQL data doesn’t always map directly to Elasticsearch. We normalize fields before indexing:

Transforming Data

Transforming Data

Fetching and Indexing Data

Here’s the migration logic for company_registry:

  • Fetch rows from MySQL
  • Apply transformations
  • Push them into Elasticsearch in bulk (faster than single inserts)
Fetching and Indexing Data

Fetching and Indexing Data

Running the Migration

Finally, execute the migration:

Running Migration

Running Migration

When run, this script will:

  • Delete any old index (if needed)
  • Recreate the index with proper mappings
  • Migrate rows from MySQL into Elasticsearch

Key Lessons Learned

  • Always define explicit mappings otherwise ES may misinterpret your fields.
  • Transform booleans & dates — MySQL often stores them as TINYINT or DATETIME, which ES won’t parse correctly without conversion.
  • Use bulk indexing for performance.
  • Index per table — each MySQL table can map to its own index (e.g., company_registry, user, etc.).

Conclusion

By building a simple migration pipeline with Python, we successfully moved company_registry data from MySQL into Elasticsearch. Once indexed, the data can be leveraged for autocomplete, fuzzy search, typo handling, and blazing-fast queries — things MySQL alone struggles with.This approach is flexible: just extend the transformation functions for other tables like user or company_order and you have a reusable ETL pipeline for all your entities.

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *