Text analysis and analyzers

Elasticsearch · Practical · 13 min

Whether a search finds 'running' for 'run' or 'café' for 'cafe' is decided by analysis.

When a text field is indexed, an analyzer turns it into terms in three steps:

  • character filters clean the raw text (strip HTML, map characters),
  • a tokenizer splits it into tokens (standard splits on word boundaries following Unicode rules, whitespace on spaces, keyword keeps one token),
  • token filters transform tokens: lowercase, asciifolding (café to cafe), stop words, stemmer (running to run), synonym_graph, edge_ngram for autocomplete.

The default standard analyzer is the standard tokenizer plus lowercase. Language analyzers like english add stop words and stemming.

The same analysis normally runs on the query text too, which is why match works. You can set a different search_analyzer, for example index with edge_ngram for prefix autocomplete but search with standard, so query text isn't also n-grammed.

The _analyze API shows exactly which terms an analyzer produces, and it's the first tool to use when a search mysteriously doesn't match.

Analyzers are defined in index settings and referenced from the mapping. Changing an analyzer on existing data requires reindexing, since terms were computed at index time. For keyword fields, a normalizer (e.g. lowercase) applies a light single-token cleanup.

Example

PUT /articles
{
  "settings": { "analysis": { "analyzer": {
    "folded_english": {
      "type": "custom",
      "char_filter": ["html_strip"],
      "tokenizer": "standard",
      "filter": ["lowercase", "asciifolding", "stop", "porter_stem"]
    } } } },
  "mappings": { "properties": {
    "body": { "type": "text", "analyzer": "folded_english" } } }
}

POST /articles/_analyze
{ "analyzer": "folded_english", "text": "<p>The Cafés are RUNNING late</p>" }
# tokens: "cafe", "run", "late"

Remember

  • Analyzer = char filters + tokenizer + token filters
  • Query text is analyzed with the same (or a search_) analyzer
  • _analyze shows the exact terms produced
  • Changing analysis means reindexing

Watch out for

  • Adding synonyms or stemming to the mapping of an existing index and expecting old documents to match differently without reindexing.

Check yourself

  1. Documents contain "running" but a match query for "run" finds nothing. What is the likely fix?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.elastic.co/guide/en/elasticsearch/reference/current/analysis.html