-
-
Save mattweber/1947215 to your computer and use it in GitHub Desktop.
This is an example how to perform multi-select faceting in ElasticSearch. | |
Selecting multiple values from the same facet will result in an OR filter between each of the values: | |
(facet1.value1 OR facet1.value2) | |
Faceting on more than one facet will result in an AND filter between each facet: | |
(facet1.value1 OR facet1.value2) AND (facet2.value1) | |
I have chosen to update the counts for each facet the selected value DOES NOT belong to since we are performing an AND between each facet. I have included an example that shows how to keep the counts if you don't want to do this (filter0.sh). | |
docs.sh - the example documents | |
query.sh - the initial query | |
filter0.sh - filter on tag "tag2", keeping counts | |
filter1.sh - filter on tag "tag2", update counts | |
filter2.sh - filter on tags "tag2" and "tag4", update counts | |
filter3.sh - filter on tags "tag2" and "tag4", keyword "keyword0", update counts | |
filter4.sh - filter on tags "tag2" and "tag4", keywords "keyword0" and "keyword2", update counts | |
curl -XPUT 'http://localhost:9200/multiselect/demo/1' -d '{ | |
"title": "One", | |
"tags": ["tag1"], | |
"keywords": ["keyword1","keyword2","keyword3"] | |
}' | |
curl -XPUT 'http://localhost:9200/multiselect/demo/2' -d '{ | |
"title": "Two", | |
"tags": ["tag1","tag2"], | |
"keywords": ["keyword1","keyword2"] | |
}' | |
curl -XPUT 'http://localhost:9200/multiselect/demo/3' -d '{ | |
"title": "Three", | |
"tags": ["tag1","tag2","tag3"], | |
"keywords": ["keyword1"] | |
}' | |
curl -XPUT 'http://localhost:9200/multiselect/demo/4' -d '{ | |
"title": "Four", | |
"tags": ["tag4"], | |
"keywords": ["keyword0"] | |
}' |
curl -XGET 'http://localhost:9200/multiselect/demo/_search?pretty=true' -d '{ | |
"query": { | |
"match_all": {} | |
}, | |
"filter": { | |
"terms": { | |
"tags": ["tag2"] | |
} | |
}, | |
"facets": { | |
"tagFacet": { | |
"terms": { | |
"field": "tags", | |
"all_terms": true | |
} | |
}, | |
"keywordFacet": { | |
"terms": { | |
"field": "keywords", | |
"all_terms": true | |
} | |
} | |
} | |
}' |
curl -XGET 'http://localhost:9200/multiselect/demo/_search?pretty=true' -d '{ | |
"query": { | |
"match_all": {} | |
}, | |
"filter": { | |
"terms": { | |
"tags": ["tag2"] | |
} | |
}, | |
"facets": { | |
"tagFacet": { | |
"terms": { | |
"field": "tags", | |
"all_terms": true | |
} | |
}, | |
"keywordFacet": { | |
"terms": { | |
"field": "keywords", | |
"all_terms": true | |
}, | |
"facet_filter":{ | |
"terms": { | |
"tags": ["tag2"] | |
} | |
} | |
} | |
} | |
}' |
curl -XGET 'http://localhost:9200/multiselect/demo/_search?pretty=true' -d '{ | |
"query": { | |
"match_all": {} | |
}, | |
"filter": { | |
"terms": { | |
"tags": ["tag2","tag4"] | |
} | |
}, | |
"facets": { | |
"tagFacet": { | |
"terms": { | |
"field": "tags", | |
"all_terms": true | |
} | |
}, | |
"keywordFacet": { | |
"terms": { | |
"field": "keywords", | |
"all_terms": true | |
}, | |
"facet_filter":{ | |
"terms": { | |
"tags": ["tag2","tag4"] | |
} | |
} | |
} | |
} | |
}' |
curl -XGET 'http://localhost:9200/multiselect/demo/_search?pretty=true' -d '{ | |
"query": { | |
"match_all": {} | |
}, | |
"filter": { | |
"and": [ | |
{ | |
"terms": { | |
"tags": ["tag2","tag4"] | |
} | |
}, | |
{ | |
"terms": { | |
"keywords": ["keyword0"] | |
} | |
} | |
] | |
}, | |
"facets": { | |
"tagFacet": { | |
"terms": { | |
"field": "tags", | |
"all_terms": true | |
}, | |
"facet_filter": { | |
"terms": { | |
"keywords": ["keyword0"] | |
} | |
} | |
}, | |
"keywordFacet": { | |
"terms": { | |
"field": "keywords", | |
"all_terms": true | |
}, | |
"facet_filter":{ | |
"terms": { | |
"tags": ["tag2","tag4"] | |
} | |
} | |
} | |
} | |
}' |
curl -XGET 'http://localhost:9200/multiselect/demo/_search?pretty=true' -d '{ | |
"query": { | |
"match_all": {} | |
}, | |
"filter": { | |
"and": [ | |
{ | |
"terms": { | |
"tags": ["tag2","tag4"] | |
} | |
}, | |
{ | |
"terms": { | |
"keywords": ["keyword0","keyword2"] | |
} | |
} | |
] | |
}, | |
"facets": { | |
"tagFacet": { | |
"terms": { | |
"field": "tags", | |
"all_terms": true | |
}, | |
"facet_filter": { | |
"terms": { | |
"keywords": ["keyword0","keyword2"] | |
} | |
} | |
}, | |
"keywordFacet": { | |
"terms": { | |
"field": "keywords", | |
"all_terms": true | |
}, | |
"facet_filter":{ | |
"terms": { | |
"tags": ["tag2","tag4"] | |
} | |
} | |
} | |
} | |
}' |
curl -XGET 'http://localhost:9200/multiselect/demo/_search?pretty=true' -d '{ | |
"query": { | |
"match_all": {} | |
}, | |
"facets": { | |
"tagFacet": { | |
"terms": { | |
"field": "tags", | |
"all_terms": true | |
} | |
}, | |
"keywordFacet": { | |
"terms": { | |
"field": "keywords", | |
"all_terms": true | |
} | |
} | |
} | |
}' |
thanks for examples!
I was trying to find concrete examples of and OR terms filter . Thanks!
I'm still trying to figure out how to counts working properly for the "OR" case. This provides the correct facets, but the counts are based on just that one selected, instead of "tag1 or tag2". The only way I can think to do this is to create a facet for each possible value of the field, which isn't ideal.
I have posted an interactive multi-select faceting demo at http://demo.fullscale.co/multiselect/
What about if for example we have keywords: k1 and k2; and tags: t1 and t2; Regarding this example, if I select k1 and k2, and then t1, the t2 will be left in the result, but the k2 will be removed from the facet result. How do I remove t2 from the facets at the same query? I can provide more detailed explanation, if it's required.
Anyone know how to do this with the new elasticsearch aggregations instead of facets?
Great examples, thanks for putting them together!