Analyzer and inverted-index playground
Build an Elasticsearch analyzer from char filters, a tokenizer and token filters and watch the token stream change stage by stage — terms, positions, offsets, types and position lengths, drawn as a token graph — then index documents to see the postings, field-length norms and phrase/slop matching, and copy the _analyze request and index settings.
Added
How to use it
How to use it
Pick a preset (standard, english, simple, whitespace, keyword, stop, autocomplete,
synonyms, product codes, paths, HTML, shingles) or edit the chain: add, reorder and configure
char filters, the tokenizer and token filters. Everything re-runs as you type.
Analyze. Each stage shows its tokens as chips (or a table: term, position, start and end
offset, type, positionLength), with new or changed tokens tinted and the change in count. Hover
or tap a token to highlight the characters it came from in the original text — offsets survive
char filters, so a token from <b>happy</b> points into the HTML. The last card draws the
token graph: positions are nodes and each token is an arc; synonyms that span several
positions (ny ↔ new york) show why synonym_graph and positionLength exist.
Index & postings. Documents (one per line) are indexed with the analyzer. The inverted index
lists every term with its document frequency, total term frequency, BM25 idf and postings
(d3: 2 @ [1, 5] = document 3, frequency 2, at positions 1 and 5; hover for offsets). The norms
table shows each field’s length, the length Lucene counts (stacked tokens at the same position
are not counted: discount_overlaps), the one-byte norm and the length it decodes to.
Phrase & slop. Type a phrase and drag the slop. Each document’s positions are drawn as cells; query terms are outlined and matched windows filled, with the sloppy frequency Σ 1/(1 + distance) and the BM25 score and explanation. Holes left by stop words stay holes, so "fox on a box" matches "fox in the box".
Elasticsearch JSON. The index settings (analysis with named definitions for anything
configured) and the equivalent _analyze request, with the response Elasticsearch would give.
Paste settings or an _analyze body to load an analyzer; with several analyzers, pick one.
Components
Char filters |
|
Tokenizers |
|
Token filters |
|
The tests check the tokenizers against the examples in the Elasticsearch reference (the
standard and classic tokenizers on "The 2 QUICK Brown-Foxes jumped over the lazy dog’s bone.",
max_token_length: 5, the ngram and edge_ngram examples, path_hierarchy, the html_strip,
mapping and pattern_replace examples, word_delimiter_graph on
"Neil’s-Super-Duper-XL500—42+AutoCoder", shingles), Porter’s stemmer against the examples in
M. F. Porter, An algorithm for suffix stripping (1980), and Porter2 against the Snowball
English sample vocabulary.
Limits
-
This is a model of the Lucene analyzers in JavaScript, not Lucene. UAX #29 is implemented for the cases above (letters, digits, mid-word punctuation, underscores, scripts, emoji); obscure rules (Hebrew quotes, some Extend/Format cases) may differ.
-
ASCII folding uses Unicode decomposition plus a table for letters without one (æ, ø, ł, ß, þ…) and typographic punctuation; Lucene’s own table has about 1,400 entries and covers more symbols.
-
kstem(light_english) needs its 30,000-word dictionary and is not included; neither are the non-English stemmers, ICU, the Kuromoji/Nori/SmartCN analyzers, or stop lists other thanenglish(give your own words instead). -
word_delimiter(the legacy, non-graph filter) is modelled like the graph one but stacks parts at one position.synonym_graphfollows Lucene’s layout of side paths; very complex rule sets (overlapping multi-word rules) may be laid out differently. -
Phrase matching follows Lucene’s sloppy matcher without its special handling of repeated terms ("to be or not to be"), so slop with repeated words can count matches differently.
Related: Relevance and scoring explainer (BM25 on these postings), Query DSL builder (run match, phrase and fuzzy queries over a sample index), Regex tester (for pattern tokenizers and char filters), Unicode inspector, TF-IDF and BM25 basics.
Linking to an example
Links can be written by hand. Add the tab after #: analyze, index, phrase or json.
| Parameter | Meaning | Example |
|---|---|---|
|
An analyzer preset: |
|
|
The text to analyze |
|
|
The phrase on the Phrase tab |
|
|
Its slop, 0–10 |
|
|
One of the presets below; parameters given with it override it |
|
example= |
Shows |
|---|---|
|
The english analyzer: possessives, stop words and Porter stems (open) |
|
Multi-word synonyms with synonym_graph: "ny" spans two positions (open) |
|
html_strip then ASCII folding, with offsets mapped back into the HTML (open) |
|
Edge n-grams for search-as-you-type (open) |
|
word_delimiter_graph splitting product codes, with catenations (open) |
|
UAX #29 on CJK, emoji, Greek final sigma, Turkish İ, Hangul and Thai (open) |
|
path_hierarchy: every ancestor path at one position (open) |
|
Word bigrams (shingles) with their position lengths (open) |
|
"quick fox" with slop 1 against four documents (open) |
|
"fox quick" needs slop 2: swapping two terms costs two moves (open) |
Feedback is a gift. Something to improve, a feature to add, or a bug? Tell me.
Runs entirely in your browser; nothing you type leaves this page.