loom-search
Search
Overview
Full-text search on Lucene-based engines (Elasticsearch/OpenSearch) plus the leaner alternatives (Meilisearch/Typesense). The engine is easy to stand up and easy to get subtly wrong: analyzer mismatches, facet counts that fight their own filters, deep pagination that falls over at 10k, and relevance that looks fine on your three test queries and terrible in production. This skill targets those.
text (analyzed, full-text, scored) vs keyword (exact, aggregatable, sortable, filterable) is the decision under most of these. Get the mapping right first.
Analysis: the root of most bugs
An analyzer = optional char filters → one tokenizer → token filters. It runs at index time (on the stored field) and at query time (on the search string). The inverted index only ever contains analyzed tokens.
⚠ Index-time / query-time analyzer mismatch is the #1 silent search bug. If you index with an edge_ngram analyzer and also analyze the query with it, searching "cat" expands to c, ca, cat and matches "category", "catalog", "cathedral" — garbage relevance. The fix is almost always: aggressive analyzer at index time, plain analyzer at search time.