# Fuzzy Phrase Suggester

The `fuzzy` suggester provides a very convenient API to access word alternatives on token
basis within a certain string distance. The API allows accessing each token in the stream
individually while suggest-selection is left to the API consumer. Yet, often already ranked
/ selected suggestions are required in order to present to the end-user.
Inside ElasticSearch we have the ability to access way more statistics and information quickly
to make better decision which token alternative to pick or if to pick an alternative at all.

This `fuzzy_phrase` suggester adds some logic on top of the `fuzzy` suggester to select entire
corrected phrases instead of individual tokens weighted based on a *bigram-model*. In practice it
will be able to make better decision about which tokens to pick based on co-occurence and frequencies.
The current implementation is kept quite general and leaves room for future improvements.

# API Example

The `fuzzy_phrase` request is defined along side the query part in the json request:

```json
curl -s -XPOST 'localhost:9200/_search' -d {
  "suggest" : {
    "text" : "Xor the Got-Jewel",
    "simple_phrase" : {
      "fuzzy_phrase" : {
        "field" : "body",
        "size" : 2,
        "min_word_len" : 1,
        "bigram_field" : "bigram",
        "lambda" : 2.0,
        "real_word_error_likelyhood" : 0.95,
        "confidence_only" : false,
        "error_fraction" : 0.5
      }
    }
  }
}
```

The response contains suggested sored by the most likely spell correction first. In this case we got the expected correction
`xorr the god jewel` first while the second correction is less conservative where only one of the errors is corrected. Note, the request
is executed with `error_fraction` set to `0.5` so 50% of the terms can contain misspellings (See parameter descriptions below).

```json
  {
  "took" : 37,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 2938,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "suggest" : {
    "simple_phrase" : [ {
      "text" : "Xor the Got-Jewel",
      "offset" : 0,
      "length" : 17,
      "options" : [ {
        "text" : "xorr the god jewel",
        "freq" : 0,
        "score" : 5.4857018E-18
      }, {
        "text" : "xor the god jewel",
        "freq" : 0,
        "score" : 4.885703E-19
      } ]
    } ]
  }
}
````

# API Parameters

This suggester supports all `fuzzy` suggester parameters as well as the following additional parameters:

* `bigram_field` -the name of the field used to do bi-gram lookups for the bigram language model. If this is not set the suggester will use a unigram langugage model to score corrections.
* `lambda` - weight parameter for the language model propability applied as a `power of` to the word propability. <big>P(W|X) * P(W)<sup>&#955;</sup></big>
* `real_word_error_likelyhood` - the likelyhood of a term being a missspelled even if the term exists in the dictionary. The default it `0.95` corresponding to 5% or the real words are missspelled.
* `confidence_only` - if `true` only suggestions that score higher than the origina phrase are returned.
* `error_fraction` - the fraction of the terms that at most considered to be misspellings in order to form a correction. This method accepts a float value in the range `[0..1)` as a fraction of the actual query terms a number `>=1` as an absolut number of query terms. The default is set to `1.0` which corresponds to that only corrections with at most 1 missspelled term are returned.
* `separator` - the separator that is used to separate terms in the bigram field. If not set the whitespce character is used as a separator.
* `candidate_size` - the number of candidates that are generated for each individual query term Low numbers like `3` or `5` typically produce good results. Raising this can bring up terms with higher edit distances. The default is `3`.
* `score_scale` - A factor to scale the suggest scores, the default is <big>10<sup>9</sup></big>.