Search code examples
elasticsearchelasticsearch-dslsearch-suggestion

Is it possible to combine _msearch and a suggester in Elasticsearch?


I'm trying to bundle multi search api with a term suggester.

When I try to use a suggester on the search endpoint, it works:

POST my-index-000001/_search
{
  "query" : {
    "match": {
      "message": "tring out Elasticsearch"
    }
  },
  "suggest" : {
    "my-suggestion" : {
      "text" : "tring out Elasticsearch",
      "term" : {
        "field" : "message"
      }
    }
  }
}

Here's how to try to do the same with multi search:

GET my-index-000001/_msearch
{ }
{
  "query" : {
    "match": {
      "message": "tring out Elasticsearch"
    }
  },
  "suggest" : {
    "my-suggestion" : {
      "text" : "tring out Elasticsearch",
      "term" : {
        "field" : "message"
      }
    }
  }
}
{"index": "my-index-000002"}
{"query" : {"match_all" : {}}}

As a result, I get an error:

{
  "error" : {
    "root_cause" : [
      {
        "type" : "json_e_o_f_exception",
        "reason" : "Unexpected end-of-input: expected close marker for Object (start marker at [Source: (org.elasticsearch.common.bytes.AbstractBytesReference$MarkSupportingStreamInputWrapper); line: 1, column: 1])\n at [Source: (org.elasticsearch.common.bytes.AbstractBytesReference$MarkSupportingStreamInputWrapper); line: 1, column: 2]"
      }
    ],
    "type" : "json_e_o_f_exception",
    "reason" : "Unexpected end-of-input: expected close marker for Object (start marker at [Source: (org.elasticsearch.common.bytes.AbstractBytesReference$MarkSupportingStreamInputWrapper); line: 1, column: 1])\n at [Source: (org.elasticsearch.common.bytes.AbstractBytesReference$MarkSupportingStreamInputWrapper); line: 1, column: 2]"
  },
  "status" : 400
}

So my question is, is it even possible?

I found a similarly named question (Using Nest Phrase Suggester on MultiSearch query), but the question itself appears to be about multi-match queries, not multi search.

The version I'm using is 7.13.


Solution

  • Your queries are syntactically correct but the Multi Search API (_msearch) only supports newline-delimited json payloads (ndjson).

    As such, line breaks (\n) can only occur when separating the payload header from the payload body:

    header\n
    body\n
    header\n
    body\n
    ...
    

    So, adjust your line breaks to conform with the required structure:

    GET my-index-000001/_msearch
    {}
    {"query":{"match":{"message":"tring out Elasticsearch"}},"suggest":{"my-suggestion":{"text":"tring out Elasticsearch","term":{"field":"message"}}}}
    {"index":"my-index-000002"}
    {"query":{"match_all":{}}}
    

    Tip: if you're using Kibana (and it looks like you are), you can toggle between the expanded and the _msearch-valid mode with +i / ctrl+i.