Reputation: 2882
I have an elasticsearch index with document mappings that look like:
{
"properties": {
"tags": {"type": "keyword"}
}
}
where the document looks like
{
"_source": {
"tags": ["one", "two"]
}
}
I am trying to query it in such a way that it will be excluded from the search results if (and only if) it has ALL of the tags submitted with the request.
Examples:
searched with tags ["one"]
: included
searched with tags ["one", "three"]
: included
searched with tags ["one", "two"]
: excluded
searched with tags ["one", "two", "three"]
: excluded
I'm having a hard time getting this to work with bool queries. The closest I have gotten is with this query:
{
"query": {
"bool": {
"filter": {
"bool": {
"must": [
{
"bool": {
"must_not": [{
"terms": {"tags": ["one", "two"]}
}]
}
}
]
}
}
}
}
}
but it is still filtering out results when only one of the tags matches. i.e. if I only submit ["one"]
. Any guidance on this would be greatly appreciated.
Upvotes: 0
Views: 801
Reputation: 2882
Major thanks to @ESCoder for helping me figure this out. By his/her answer, I figured out that I need a terms_set
query because it's based on the should
logic. This looks like it works for my use case:
{
"query": {
"bool": {
"must_not": {
"terms_set": {
"tags": {
"terms": ["one", "two"],
"minimum_should_match_script": {
"source": "doc['tags'].length"
}
}
}
}
}
}
}
It calculates the should match for each specific doc in the index. So that it can make sure all of the submitted tags match.
Upvotes: 0
Reputation: 16192
You can use a combination of bool should clause. Try out this below query
{
"query": {
"bool": {
"must_not": [
{
"bool": {
"should": [
{
"match": {
"tags": "one"
}
},
{
"match": {
"tags": "two"
}
}
],
"minimum_should_match": 2
}
}
]
}
}
}
The search result will be
"hits": [
{
"_index": "66033399",
"_type": "_doc",
"_id": "1",
"_score": 0.0,
"_source": {
"tags": [
"one"
]
}
},
{
"_index": "66033399",
"_type": "_doc",
"_id": "2",
"_score": 0.0,
"_source": {
"tags": [
"one",
"three"
]
}
}
]
Upvotes: 1