I understand that you are trying to create a xor filter on the location field. There is no xor shortcut in the boolean query of Elasticsearch but xor can be constructed with OR, AND and NOT operators.
must -> and
should -> or
must_not -> not
So there are two ways to construct a xor filter with these operators (pseudocode):
must( (should(uk, us), must_not( must(uk, us))
should( must( uk, must_not(us)), must(must_not(uk), us))
There is also the more readable Query_String query which supports boolean syntax.
Below is an example for bool and match query combination and an example for the query string query that both act as exclusive OR, you can test these queries in Kibana dev tools:
PUT /test_xor
PUT /test_xor/_doc/1
{
"type": "neither uk nor us",
"location": [
{
"title": "Something that happened in germany",
"location": "Germany, Berlin"
},
{
"title": "Something that happened in the France",
"location": "France, Paris"
}
]
}
PUT /test_xor/_doc/2
{
"type": "only us",
"location": [
{
"title": "Something that happened in germany",
"location": "Germany, Berlin"
},
{
"title": "Something that happened in the US",
"location": "United States, London"
}
]
}
PUT /test_xor/_doc/3
{
"type": "only uk",
"location": [
{
"title": "Something that happened in germany",
"location": "Germany, Berlin"
},
{
"title": "Something that happened in the US",
"location": "United States, London"
}
]
}
PUT /test_xor/_doc/4
{
"type": "uk and us",
"location": [
{
"title": "Something that happened in the US",
"location": "United States, London"
},
{
"title": "Something that happened in the UK",
"location": "United Kingdom, London"
}
]
}
GET /test_xor/_search
{
"query": {
"query_string" : {
"query": "(\"United States, London\" OR \"United Kingdom, London\") AND NOT (\"United States, London\" AND \"United Kingdom, London\")",
"fields": ["location.location"]
}
}
}
GET /test_xor/_search
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"match": {
"location.location": {
"query": "United States, London",
"operator": "and"
}
}
},
{
"match": {
"location.location": {
"query": " OR \"United Kingdom, London\"",
"operator": "and"
}
}
}
]
}
},
{
"bool": {
"must_not": [
{
"bool": {
"must": [
{
"match": {
"location.location": {
"query": "United States, London",
"operator": "and"
}
}
},
{
"match": {
"location.location": {
"query": "United Kingdom, London",
"operator": "and"
}
}
}
]
}
}
]
}
}
]
}
}
}
locationfield is of typetextand its analyzed. What I want to achieve is to get an ES query that would return only results from theunited statesorunited kingdom. But using thematchquery for this does not work because the wordunitedis present in bothlocationfields.