How to combine suggest query?

Hello,

I have the following mapping for address suggestion:

PUT /autocomplete
{
  "mappings": {
    "address" : {
      "properties" : {
        "city":     { "type" : "string" },
        "district": { "type" : "string" },
        "street":   { "type" : "string" },
        "city_suggest": {
          "type":   "completion"
        },
        "district_suggest": {
          "type":   "completion"
        },
        "street_suggest": {
          "type":  "completion"
        }
      } 
    }
  }
}

The idea is to get matching cities, districts, and streets with their parents included, i.e. considering the following dataset

POST /autocomplete/address/1
{
  "city":           "Kiev",
  "district":       "Shevchenkovsky",
  "street":         "Shevhenko",
  "city_suggest": {
    "input":    ["Kiev"],
    "weight":   "1"  
  },
  "district_suggest": {
      "input":  ["Shevchenkovsky"],
      "output": "Kiev, Shevchenkovsky",
      "weight": 10
  },
  "street_suggest": {
      "input":  ["Shevchenko"],
      "output": "Kiev, Shevchenkovsky, Shevchenko",
      "weight": 100
  }
}

POST /autocomplete/address/2
{
  "city":               "Kiev",
  "district":           "Shevchenkovsky",
  "street":             "Pobedy ave",
   "city_suggest": {
    "input":    ["Kiev"],
    "weight":   "1"  
  },
  "district_suggest": {
      "input":  ["Shevchenkovsky"],
      "output": "Kiev, Shevchenkovsky",
      "weight": 10
  },
  "street_suggest": {
      "input":  ["Pobedy ave"],
      "output": "Kiev, Shevchenkovsky, Pobedy ave",
      "weight": 100
  }
}

And user input "sh" the suggestion output should be:

Kiev, Shevchenkovsky, Shevchenko
Kiev, Shevchenkovsky

where both district and street matches. I tried to use "bool" query as described in https://www.elastic.co/guide/en/elasticsearch/guide/current/multi-query-strings.html

GET /autocomplete/_suggest
{
    "query": {
        "bool": {
            "should": {
                "match": {
                    "district_suggest": "sh",
                    "street_suggest": "sh"   
                }     
            }
        }
    }

}

but got an error in response

{
   "_shards": {
      "total": 5,
      "successful": 0,
      "failed": 5,
      "failures": [
         {
            "shard": 0,
            "index": "autocomplete",
            "status": "INTERNAL_SERVER_ERROR",
            "reason": {
               "type": "exception",
               "reason": "failed to execute suggest",
               "caused_by": {
                  "type": "illegal_argument_exception",
                  "reason": "Suggester[bool] not supported"
               }
            }
         }
      ]
   }
}

Try something like;

GET /autocomplete/_suggest
{
  "suggestion-district" : {
    "text" : "sh",
    "term" : {
      "field" : "district_suggest"
    }
  },
  "suggestion-street" : {
    "text" : "sh",
    "term" : {
      "field" : "street_suggest"
    }
  }
}

As per https://www.elastic.co/guide/en/elasticsearch/reference/2.3/search-suggesters.html#search-suggesters

I don't think you can do multiple fields like this, you may want ngrams instead.

Thank you @warkolm,

I replaced term with completion and it worked like a charm (at least I can't see downsides ATM)!

GET /autocomplete/_suggest
{
  "suggest_district": {
    "text" : "sh",
    "completion" : {
      "field" : "district_suggest"
    }
  },
  "suggest_street" : {
    "text" : "sh",
    "completion" : {
      "field" : "street_suggest"
    }
  }
}

RESPONSE

{
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "suggest_district": [
      {
         "text": "sh",
         "offset": 0,
         "length": 2,
         "options": [
            {
               "text": "Kiev, Shevchenkovsky",
               "score": 10
            }
         ]
      }
   ],
   "suggest_street": [
      {
         "text": "sh",
         "offset": 0,
         "length": 2,
         "options": [
            {
               "text": "Kiev, Shevchenkovsky, Shevchenko",
               "score": 100
            }
         ]
      }
   ]
}

I will take a look at edge ngrams as well :smiley: