elasticsearch/elasticsearch — pull request #4044 by chilling (2013-11-01 14:31:11+00:00)
Title: ContextSuggester

This commit extends the `CompletionSuggester` by context
informations. In example such a context informations can
be a simple string representing a category reducing the
suggestions in order to this category.

Three base implementations of these context informations
have been setup in this commit.

- a Category Context
- a Geo Context
- a Field Context

All the mapping for these context informations are
specified within a context field in the completion
field that should use this kind of information.

## Mapping Example

The following example shows the mapping for a GeoContext.

{
"testType":{
"properties":{
"testField":{
"type":"completion",
"index_analyzer":"simple",
"search_analyzer":"simple",
"payloads":true,
"preserve_separators":false,
"preserve_position_increments":true,
"context":{
"geo":{
"separator":"|",
"precision":8,
"neighbors":true
}
}
}
}
}
}

## Indexing

During indexing a document the subfield `context` of the
completion field contains the data to be used in order
to provide suggestions.

{
"testField":{
"input":[["pizza - berlin","pizza","food"]],
"context":"u33dc1v0xupz"
}
}

## Suggestion Example

The Suggestion request is extended by a context value. The
suggest request for a geolocation looks like

{
"suggest":{
"text":"pizza",
"completion":{
"field":"testField",
"size":10,
"context":{
"geo":"u33dc0cpke4q"
}
}
}
}

The context objects contains a field with the same name as
defined in the mapping. According to the type of the context
this field contains the data associated with the suggestion
request. In this example the geohash of a location.

## Category Context

The simplest way to use this feature is a category context. It
supports a arbitrary name of a category to use with the completion
suggest API.

To set the context support to the category type this option must be
set to `true`:

"testField":{
"type":"completion",
"context":{
"category": true
}
}

The name of the context category then needs to be set within the
suggestion context during indexing:

{
"testField":{
"input":[["pizza - berlin","pizza","food"]],
"context":"delivery"
}
}

and can be used by setting the category value:

{
"suggest":{
"text":"pizza",
"completion":{
"field":"testField",
"size":10,
"context":{
"category":"delivery"
}
}
}
}

## Field Context

The Field Context works like the category context but the value of this
will context will not explicitly be set. It refers to another field in
the document. In example a `category` field.

{
"category":{
"type": "string"
},
"testField":{
"type":"completion",
"context":{
"field": "category"
}
}
}

for indexing the field context must be set to true:

{
"category":"delivery",
"testField":{
"input":[["pizza - berlin","pizza","food"]],
"context":true
}
}

and suggestions use the `context.field` value

{
"suggest":{
"text":"pizza",
"completion":{
"field":"testField",
"size":10,
"context": {
"field": "delivery"
}
}
}
}

## Geo Context

The last context feature is the GeoContext. It take a location into account.
For example if one searches for delivery services it might be use full to find
results around the location the query was sent. This context internally works
on geohashes only but the REST API allows any form defined for `geo_points`

In the mapping this kind of context is configured by two parameters:

- precision
- neighbors

The `precision` option is used to configure the range of result. If the
`neighbors` option is enabled not only the given geohash cell will be used
but also all it's neighbors.

"context":{
"geo":{
"separator":"|",
"precision":8,
"neighbors":true
}
}

The context during indexing is set to the location of the input:

{
"testField":{
"input":[["pizza - berlin","pizza","food"]],
"context": "u33dc1v0xupz"
}
}

To get a ist of suggestions around a specific area the `context.geo` field
must contain the position of this area:

{
"suggest":{
"text":"pizza",
"completion":{
"field":"testField",
"size":10,
"context": {
"geo": "u33dc0cpke4q"
}
}
}
}

Closes #3959