Developing Search Applications
What to know
An application talks to Elasticsearch over the REST API or a client library: index, update and delete documents, then search them. Core mechanics: writes become visible to search only after a refresh (near-real-time, default 1s), while a GET by ID is real-time - use refresh=wait_for when a test must observe its own write. Optimistic concurrency uses if_seq_no plus if_primary_term (or version), and a conflict returns 409. Pagination choices are from/size for shallow paging, search_after with a tiebreaker sort and a point-in-time for deep paging, and scroll for exports. Supporting APIs you are expected to reach for: _analyze to debug an analyzer chain, highlighting, term/phrase/completion suggesters, aliases for zero-downtime reindex, and index templates.
Traps
- A search issued immediately after an index call may return stale results. That is refresh latency, not a bug.
search_afterrequires a stable, unique sort; add a tiebreaker (_idor_shard_doc) or documents can be skipped or repeated.- A scroll context snapshots the index, ignores new writes, and holds resources until it expires or is explicitly cleared.
- A
completionsuggester needs a field mapped ascompletion, notkeyword. - An alias pointing at multiple indices breaks writes; keep exactly one write index behind a search alias.
- Index names must be lowercase and avoid reserved characters; document IDs are strings with length limits.
Rule of thumb
For a UI, use from/size for the first few pages and search_after beyond that; never use scroll for interactive paging. Verify any analyzer change with _analyze before touching a mapping.