Key technologies
Elasticsearch
A distributed inverted index for search: how queries actually run, and why it should not be your source of truth.
Elasticsearch (and OpenSearch) shard an inverted index. Text is analyzed into tokens, tokens point at documents, and a query is a fast set operation over those postings plus a score, usually BM25. Use it when users type a query and you need relevance, facets, and typo tolerance. Do not use it as the system of record for money or inventory.
The shape of a cluster
An index has shards. Each shard is a Lucene index on one node, with replicas for reads and for survival. You choose shard count up front more than you wish you had to; too few and you cannot parallelize, too many and a small index drowns in overhead. Replicas add read capacity and a copy. They do not add write capacity on the primary shard of a document.
Documents have a mapping. The mapping is a schema even though people call the engine schemaless. Changing a field from text to keyword is a reindex, not an alter. Say that before you promise flexible documents.
Feeding it
The application writes Postgres, including an outbox row. A consumer indexes the document. Failures retry. A periodic reconcile compares counts or checksums. Dual writes from the request handler will miss, and you will not notice until a search demo.
Deletes and updates are soft at the segment level. Segments merge in the background. A document you just indexed may be briefly invisible (refresh interval, often a second). For a search box that is fine. For “I just created it and the next screen is a search” you may need a refresh or a read from the database.
Queries
Put exact constraints (tenant, status, time range) in a filter context so they can be cached and do not affect score. Put the user’s words in the scored query. Page with search_after on a unique sort, not with a large from. Aggregations are how you build facets; they cost heap, so bound them.
If you also have embeddings, a hybrid query runs BM25 and a vector search and merges ranks (reciprocal rank fusion is the simple version). Say which one you trust when they disagree. For a people search, lexical match on a name should beat a vague embedding neighbor.
Security is a filter you cannot forget: every query is constrained to the tenant in the token. Index-per-tenant isolates noisy neighbors and makes deletion easy, at the cost of thousands of small indexes. A shared index with a strict filter is the other way. Pick one.
Further reading
Check yourself
Answer the questions. Multiple choice is scored on this device only.
1. Why is Elasticsearch a poor source of truth?
2. from=10000, size=10 is a problem because:
3. What is BM25 doing?