MySQL’s built-in full-text search is surprisingly capable, but it often falls short when your search needs get even a little bit complex.

Let’s see how MySQL Full-Text Search (FTS) handles a common search scenario. Imagine a table articles with a title and body column, both indexed for FTS.

CREATE TABLE articles (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    body TEXT NOT NULL,
    FULLTEXT (title, body)
) ENGINE=InnoDB;

INSERT INTO articles (title, body) VALUES
('The Quick Brown Fox', 'The quick brown fox jumps over the lazy dog.'),
('Agile Development Methodologies', 'Agile methodologies emphasize iterative development and collaboration.'),
('MySQL Performance Tuning', 'Tuning MySQL for optimal performance involves indexing and query optimization.'),
('Brown Dog Adventures', 'A brown dog chased a squirrel through the park.'),
('Foxes in the Wild', 'Wild foxes are known for their cunning and adaptability.');

Now, let’s search for articles containing "fox" and "brown":

SELECT id, title
FROM articles
WHERE MATCH(title, body) AGAINST('fox brown' IN BOOLEAN MODE);

This query returns articles with both "fox" and "brown" (or their variations), ordered by relevance. It’s a good start for basic keyword matching.

However, the real power and complexity lie in how Elasticsearch approaches search, and why it’s often the better choice for anything beyond simple keyword matching. Elasticsearch is built from the ground up for search, treating text not as raw strings but as structured data that can be analyzed, tokenized, and scored in incredibly granular ways.

Consider a more nuanced search: finding articles related to "development" but not "agile," and where "iterative" appears close to "collaboration."

With Elasticsearch, this becomes a structured query:

GET /articles/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "body": "development" } },
        { "match": { "body": "iterative" } },
        { "match": { "body": "collaboration" } }
      ],
      "must_not": [
        { "match": { "body": "agile" } }
      ]
    }
  }
}

This query, when executed against an Elasticsearch index mirroring the articles table, would leverage Elasticsearch’s inverted index and powerful query DSL to precisely match these conditions. The bool query allows combining multiple criteria with must, should, and must_not clauses. The match query handles the actual text search, and Elasticsearch’s analyzers break down the text into searchable tokens.

The core problem Elasticsearch solves that MySQL FTS struggles with is scalability and complexity of search logic. MySQL FTS is an add-on to a relational database, designed to speed up LIKE '%keyword%' queries. It uses a secondary index structure, but it’s fundamentally tied to the RDBMS’s architecture. When you need to:

  • Rank results by relevance dynamically: Elasticsearch’s scoring (TF-IDF, BM25) is sophisticated and configurable.
  • Handle synonyms and stemming effectively: Elasticsearch has built-in analyzers for this.
  • Perform fuzzy matching or typo tolerance: Elasticsearch excels here.
  • Facilitate complex boolean logic across multiple fields with varying weights: Elasticsearch’s Query DSL is designed for this.
  • Scale search infrastructure independently of your database: Elasticsearch clusters are built for this.

MySQL FTS, on the other hand, is best for:

  • Simple keyword searches within a single application database.
  • When you absolutely cannot introduce a separate search service.
  • When your search needs are limited to basic matching and relevance ranking.

The internal mechanism that makes Elasticsearch so powerful for complex search is its inverted index. Unlike a traditional database index that maps a value to rows, an inverted index maps terms (individual words after analysis) to the documents (or rows) that contain them. For each term, it stores a list of document IDs and positional information. This structure allows for extremely fast lookups of documents containing specific terms and efficient combination of these term occurrences for complex queries.

The one thing most people don’t realize is how much control you have over the analysis process in Elasticsearch. It’s not just about putting text in; it’s about defining how that text is broken down into searchable tokens. You can choose specific tokenizers (how to split text into words), character filters (to clean text before tokenization, like removing HTML), and token filters (to modify tokens, like adding synonyms, stemming, or converting to lowercase). This fine-grained control over analysis is what enables highly accurate and nuanced search results, something far beyond MySQL’s capabilities.

The next hurdle you’ll encounter is understanding Elasticsearch’s aggregation framework for building dashboards and performing analytics on your search data.

Want structured learning?

Take the full Express course →