# Snowball stemming (European languages)

Stemming reduces words to a common stem, so `running` matches `run` and German `Häuser` matches
`Haus`. The `snowball` filter stems with the Snowball algorithms. Each language also has a
ready-made `snowball_<language>` analyzer, such as `snowball_german` or `snowball_english`:

```json
{"fields": {"title_de": {"type": "text", "analyzer": "snowball_german"}}}
```

The analyzers run `unicode_word`, `nfkc_cf`, the language's stop words and `snowball`.

## Languages

`arabic`, `armenian`, `basque`, `catalan`, `danish`, `dutch`, `dutch_porter`, `english`
(Porter2), `esperanto`, `estonian`, `finnish`, `french`, `german`, `greek`, `hindi`,
`hungarian`, `indonesian`, `irish`, `italian`, `lithuanian`, `nepali`, `norwegian`, `porter`
(the original English Porter stemmer), `portuguese`, `romanian`, `russian`, `serbian`, `spanish`,
`swedish`, `tamil`, `turkish` and `yiddish`.

`esperanto`, `nepali`, `serbian`, `tamil` and `yiddish` have no stop list, so their analyzers only
stem. For Arabic, the [`arabic`](arabic.md) analyzer also normalizes spelling and usually works
better than `snowball_arabic`.

## In your own chain

Set the filter's required `language` parameter:

```json
{
  "type": "text",
  "analyzer": {
    "tokenizer": "unicode_word",
    "filters": ["nfkc_cf", {"name": "snowball", "params": {"language": "french"}}]
  }
}
```

- Put `nfkc_cf` or `lowercase` before `snowball`: it expects lowercase input.
- Leave `fold` out for languages whose stemmer reads accents, such as German or French, unless
  you want accented and unaccented forms to match.
- Prefix, wildcard and fuzzy terms are not stemmed: `häuser*` matches terms that start with
  `häuser`, and the index holds `haus`.

## English

For English, the `_t` suffix's KStem stemming is gentler than Porter2: `snowball_english` matches
more word forms, and also more unrelated words. Use `_t` unless recall matters more than
precision.

## Through the compatible APIs

Elasticsearch and OpenSearch language analyzers such as `german` or `french`, the `snowball` and
`stemmer` filters, and Solr's `text_<language>` types and `SnowballPorterFilterFactory` map to
these components. Elasticsearch's light and minimal stemmers use the Snowball stemmer of the
language, with a warning. See [Through the compatible APIs](text-analysis.md#through-the-compatible-apis).
