Hi i am new to a Elasticsearch and i have a question. Is it possible to make a aggregation filtration against search results ? Currently i have 4 keyboard items (with titles: klaviatura1, klaviatura2, klaviatura3, klaviatura4) and each item has price and size .
Example:
Title : klaviatura1
Price : 100
Size : large
--------------------
Title : klaviatura2
Price : 100
Size : medium
--------------------
Title : klaviatura3
Price : 120
Size : medium
--------------------
Title : klaviatura4
Price : 60
Size : small
After doing a search for keyboard with size : "large", elasticsearch returns the result. But the problem is that the Aggregations still return all the results.
Below I have written what it returns and what I want i want to return
Request:
{
"aggs":{
"price":{
"terms":{
"field":"price.keyword"
}
},
"size":{
"terms":{
"field":"size.keyword"
}
}
},
"from":0,
"post_filter":{
"bool":{
"must":[
{
"bool":{
"should":[
{
"term":{
"language":{
"value":"en"
}
}
},
{
"term":{
"language":{
"value":"nullvalue"
}
}
}
]
}
},
{
"term":{
"size":{
"value":"large"
}
}
}
]
}
},
"query":{
"bool":{
"should":[
{
"match_phrase_prefix":{
"title":{
"query":"klavi"
}
}
},
{
"match_phrase_prefix":{
"content":{
"query":"klavi"
}
}
}
]
}
}
}
Responce:
{
"took": 10,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 6.7367506,
"hits": [
{
"_index": "klaviaturaindex",
"_type": "_doc",
"_score": 6.7367506,
"_source": {
"language": "en",
"title": "klaviatura1",
"price": "100",
"size": "large",
}
}
]
},
"aggregations": {
"size": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "medium",
"doc_count": 2
},
{
"key": "large",
"doc_count": 1
},
{
"key": "small",
"doc_count": 1
}
]
},
"price": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "100",
"doc_count": 2
},
{
"key": "120",
"doc_count": 1
},
{
"key": "50",
"doc_count": 1
}
]
}
}
}
What i want to return
{
"took": 10,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 6.7367506,
"hits": [
{
"_index": "klaviaturaindex",
"_type": "_doc",
"_score": 6.7367506,
"_source": {
"language": "en",
"title": "klaviatura1",
"price": "100",
"size": "large",
}
}
]
},
"aggregations": {
"size": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "medium",
"doc_count": 0
},
{
"key": "large",
"doc_count": 1
},
{
"key": "small",
"doc_count": 0
}
]
},
"price": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "100",
"doc_count": 1
},
{
"key": "120",
"doc_count": 0
},
{
"key": "50",
"doc_count": 0
}
]
}
}
}
Any ideas ?
CodePudding user response:
Instead of using post_filter
, which executes after aggregations, you should be adding your filters into the main query section, like this:
{
"aggs": {
"price": {
"terms": {
"field": "price.keyword"
}
},
"size": {
"terms": {
"field": "size.keyword"
}
}
},
"from": 0,
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"term": {
"language": {
"value": "en"
}
}
},
{
"term": {
"language": {
"value": "nullvalue"
}
}
}
]
}
},
{
"term": {
"size": {
"value": "large"
}
}
}
],
"should": [
{
"match_phrase_prefix": {
"title": {
"query": "klavi"
}
}
},
{
"match_phrase_prefix": {
"content": {
"query": "klavi"
}
}
}
]
}
}
}