Home > database >  Facet filtering against search results
Facet filtering against search results

Time:08-30

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"
            }
          }
        }
      ]
    }
  }
}
  • Related