The only thing I can think of is to do the following on the client:
Let's say you search for elasticsearch potatoes
:
- Split the text (you can use
_analyze
endpoint for that)
- For each generated token, here:
elasticsearch
, potatoes
, generate a should clause using named queries.
- As a response, you will get for each doc, the list of queries which matched,. So you can on client side know which queries did not match.
Full example
Tested on 5.0.1
Index some data
DELETE index
POST index/doc
{
"content": "elasticsearch you know for search"
}
POST index/doc
{
"content": "potatoes you know for lunch"
}
Analyze the text
GET _analyze
{
"text": "elasticsearch potatoes"
}
it gives back 2 tokens:
{
"tokens": [
{
"token": "elasticsearch",
"start_offset": 0,
"end_offset": 13,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "potatoes",
"start_offset": 14,
"end_offset": 22,
"type": "<ALPHANUM>",
"position": 1
}
]
}
Create the search
Iterate over the tokens and create the should clause for them:
GET index/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"content": {
"query": "elasticsearch",
"_name": "elasticsearch"
}
}
},
{
"match": {
"content": {
"query": "potatoes",
"_name": "potatoes"
}
}
}
]
}
}
}
It gives:
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 0.2824934,
"hits": [
{
"_index": "index",
"_type": "doc",
"_id": "AViRm-3jWVDw7QDfjwKn",
"_score": 0.2824934,
"_source": {
"content": "elasticsearch you know for search"
},
"matched_queries": [
"elasticsearch"
]
},
{
"_index": "index",
"_type": "doc",
"_id": "AViRm_VGWVDw7QDfjwKo",
"_score": 0.2824934,
"_source": {
"content": "potatoes you know for lunch"
},
"matched_queries": [
"potatoes"
]
}
]
}
}
So you know that for the first doc, potatoes
is missing and for the second doc elasticsearch
is missing.
Using a template
You can also use a template like this:
GET index/_search/template
{
"inline": "{\"query\":{\"bool\":{\"should\":[{{#term}}{\"match\":{\"content\":{\"query\": \"{{.}}\",\"_name\": \"{{.}}\"}}},{{/term}}{}]}}}",
"params": {
"term": [ "elasticsearch", "potatoes" ]
}
}
The template part is actually the following but it needs to be wrapped here in a string as it's not a valid JSON otherwise:
{
"query": {
"bool": {
"should": [
{{#term}}
{
"match": {
"content": {
"query": "{{.}}",
"_name": "{{.}}"
}
}
},
{{/term}}
{}
]
}
}
}
I hope this helps.