Skip to content
ExponaBLOG
ELASTICSEARCH & SEARCH ENGINEERING · DAY 001 / 100

Why Elasticsearch for search: what developers should know

Fast, relevant full-text search that SQL LIKE queries cannot match.

Expona Admin7 min read

Introduction

Most developers start with SQL LIKE queries when they need to search user data, product catalogs, or log messages. Those queries work for exact matches and simple patterns, but they fail the moment your users expect fast, relevant results ranked by quality rather than insertion order. Why Elasticsearch for search: what developers should know comes down to a single difference: Elasticsearch was built from the ground up for search, while relational databases were built for transactions. In this first article of our 100-day series, we'll explore the core reasons why Elasticsearch has become the industry standard for search and analytics across e-commerce, SaaS, and content platforms.

Inverted indexes make text search fast

The foundation of Elasticsearch's speed is the inverted index. Unlike a traditional database that stores rows and scans through them to find matching text, an inverted index works like the index of a book: it maps every unique word to the documents that contain it, along with metadata like position and frequency.

Imagine you're building a product search for an e-commerce platform with 10 million items. A SQL query like SELECT * FROM products WHERE name LIKE '%laptop%' OR description LIKE '%laptop%' must scan millions of rows, check each one against your pattern, and return results. On a busy system, this query will lock tables and timeout regularly.

Elasticsearch inverts that relationship. When you index a product, every word in its name and description is extracted and stored in a lookup table. The word "laptop" points directly to all documents containing it, with no full-table scan required. This is why Elasticsearch can return millions of results in milliseconds.

Here's a simplified mental model of how inverted index storage differs from row storage:

Approach Storage Search Query Speed
SQL Database (row-based) Row 1, Row 2, Row 3, … Scan all rows, check each against LIKE pattern O(n) — scales with data size
Elasticsearch (inverted index) Word → [Doc1, Doc5, Doc12], Word → [Doc3, Doc8] Look up word in index, return documents directly O(1) to O(log n) — independent of total data

When you index a document in Elasticsearch, the text analysis pipeline breaks it into tokens, removes stop words, applies stemming (so "running," "runs," and "run" all map to "run"), and stores the result. This preprocessing enables both speed and fuzzy matching. Queries execute against this preprocessed index, not the original text.

Relevance scoring ranks the best results first

Speed alone is worthless if your top result is irrelevant. A database can return all rows matching a WHERE clause, but it has no built-in concept of "best match." Elasticsearch solves this with relevance scoring, using algorithms like BM25 (best matching 25, the industry standard) to rank results by quality.

BM25 considers:

  • Term frequency — how often the search term appears in a document
  • Inverse document frequency — how rare the term is across all documents
  • Field length normalization — penalizing very long documents that naturally contain more terms
  • Field boosts — giving extra weight to matches in, say, a product title versus a long description

Let's say you're building a travel platform and a user searches for "luxury beach resort in Bali." A naive database might return all properties with "beach" in the description, sorted by date added. Elasticsearch instead scores each property based on how well it matches the entire query, considering term rarity and field importance. A property with "luxury," "beach," and "resort" in the title ranks higher than one mentioning "beach" once in paragraph seven of the description.

You can further tune relevance through function queries and custom scoring. Here's a basic example that boosts recent listings:

json
{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "luxury beach resort",
            "fields": ["title^3", "description^1", "amenities^2"]
          }
        }
      ],
      "functions": [
        {
          "exp": {
            "created_at": {
              "origin": "now",
              "scale": "30d",
              "decay": 0.5
            }
          }
        }
      ]
    }
  }
}

The ^ syntax boosts title matches by 3x and amenities by 2x. The function query decays relevance over 30 days, so older listings gradually drop in rank. This combination gives you control over what "best result" means for your domain, without writing custom ranking logic.

Aggregations power filters and analytics

Most modern search interfaces aren't just about returning a list of results; they're about letting users drill down into subsets. E-commerce sites show faceted search: "Filters: Brand (Apple, Samsung, Sony), Price ($100–$500, $500–$1000), Rating (4+, 3+)." Behind the scenes, that's powered by Elasticsearch aggregations, which compute statistics on matching documents in a single pass.

Aggregations let you bucket documents by field values, compute metrics like average price or total sales, and nest aggregations for hierarchical analysis. This is why Elasticsearch is popular not just for search but for analytics dashboards and business intelligence.

Imagine a ride-hailing platform where a user searches for rides in a city. You want to show available driver ratings, car types, and estimated prices as interactive filters. Here's an aggregation that computes these buckets:

json
{
  "query": {
    "match": {
      "destination_city": "San Francisco"
    }
  },
  "aggs": {
    "by_rating": {
      "terms": {
        "field": "driver_rating",
        "size": 5
      }
    },
    "by_car_type": {
      "terms": {
        "field": "car_type.keyword",
        "size": 10
      }
    },
    "price_ranges": {
      "range": {
        "field": "estimated_price",
        "ranges": [
          { "to": 20 },
          { "from": 20, "to": 50 },
          { "from": 50 }
        ]
      }
    }
  }
}

In a single query, you get search results and counts for each filter option, letting your frontend render an interactive facet panel without making separate database calls. This reduces latency and simplifies your application code.

Scales horizontally across nodes

As your search volume and data size grow, you can't just buy a bigger server forever. Elasticsearch is designed for horizontal scaling: you add more nodes to the cluster, and the cluster automatically distributes shards (partitions) across them.

Each index is split into shards; each shard is an independent Lucene index. A search query hits all shards in parallel, retrieves top-N results from each, and merges them. This parallelism means search latency stays low even as data grows, as long as you provision enough nodes and shards.

For example, a CRM platform with billions of customer records and interactions might use:

  • One shard per node, so a 10-node cluster has 10 shards
  • Replicas for fault tolerance; each shard has 1–2 copies on different nodes
  • A search query spreads across all 10 shards, each scanning its local index in parallel
  • Total search time ≈ time for slowest shard (network overhead), not sum of all shards

This is fundamentally different from a single SQL database, which either bottlenecks on I/O or requires complex sharding logic in your application layer. Elasticsearch handles sharding transparently.

Adding a new node is as simple as starting an Elasticsearch process configured to join your cluster. The cluster automatically rebalances shards, and search queries immediately benefit from the extra capacity. This makes Elasticsearch ideal for growing platforms where you can't predict peak load months in advance.

Common mistakes

Before we wrap up, here are pitfalls we see teams hit repeatedly:

  • Over-indexing every field — not every field needs full-text analysis. Boolean flags, IDs, and numeric values should use simpler field types to save disk space and indexing time.
  • Ignoring relevance tuning — deploying Elasticsearch with default settings and wondering why results feel "off." Spend time understanding your domain and adjusting field boosts, analyzers, and scoring functions.
  • Sharding too aggressively early — each shard adds overhead. Start with fewer, larger shards and split only when a shard grows too large or search latency increases noticeably.
  • Treating Elasticsearch as a database replacement — it's not ACID-compliant and doesn't replace transactional storage. Use it alongside your primary database, not instead of it.
  • Skipping cluster planning — deploying a single-node cluster in production and hoping nothing fails. Plan for replication, backup, and failover from day one.

Key takeaways

  • Inverted indexes let Elasticsearch execute text searches in milliseconds, independent of data size, compared to O(n) table scans in SQL databases.
  • Relevance scoring via BM25 ensures the top results are the best matches, not arbitrary or insertion-order based.
  • Aggregations compute facets, filters, and analytics in a single pass, eliminating the need for separate database queries or application-side bucketing.
  • Horizontal scaling across nodes and shards means you can grow search performance linearly by adding hardware, without rewriting application code.
  • Elasticsearch excels at search and analytics but works best as a complement to your primary transactional database, not a replacement for it.
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles

Why Elasticsearch for search | Elasticsearch | Expona