Search code examples
javaspring-bootelasticsearch

How to add should clause inside filters in functions in ElasticQuery


I have an elastic query which has a filter inside functions. I need to add a condition like either it should match the departments filter or it should match with any of the product_ids so that the recall must contain the product_ids passed. Below is the product_ids i want to see in elastic recall which needs to be added in functions in ES query.

{
    "terms": {
        "product_ids": [
            "166168",
            "753547",
            "156835",
            "90112"
         ]
     }
}

Below is the actual ES query

  "track_total_hits": true,
  "_source": {},
  "query": {
    "boosting": {
      "positive": {
        "function_score": {
          "query": {},
          "boost_mode": "avg",
          "score_mode": "sum",
          "functions": [
            {
              "filter": {
                "match": {
                  "Departments": {
                    "query": "1/lipstick",
                    "operator": "OR",
                    "fuzzy_transpositions": true,
                    "auto_generate_synonyms_phrase_query": true,
                    "boost": 1
                  }
                }
              },
              "weight": 99
            }

//I need to add the product_ids terms here

          ]
        }
      },
      "negative": {},
      "negative_boost": "1.0E-4"
    }
  },

Solution

  • You can create bool query inside filter clause.

    {
      "query": {
        "boosting": {
          "positive": {
            "function_score": {
              "query": {
                "match_all": {}
              },
              "boost_mode": "avg",
              "score_mode": "sum",
              "functions": [
                {
                  "filter": {
                    "bool": {
                      "should": [
                        {
                          "match": {
                            "Departments": {
                              "query": "1/lipstick",
                              "operator": "OR",
                              "fuzzy_transpositions": true,
                              "auto_generate_synonyms_phrase_query": true,
                              "boost": 1
                            }
                          }
                        },
                        {
                          "terms": {
                            "product_ids": [
                              "166168",
                              "753547",
                              "156835",
                              "90112"
                            ]
                          }
                        }
                      ]
                    }
                  },
                  "weight": 99
                }
              ]
            }
          },
          "negative": {},
          "negative_boost": "1.0E-4"
        }
      }
    }
    

    You can also add multipul functions and only one can optionally choose to apply the function only if a document matches a given filtering query as mentioned here.

    GET /_search
    {
      "query": {
        "function_score": {
          "query": {
            "match_all": {}
          },
          "functions": [
            {
              "filter": {
                "match": {
                  "Departments": {
                    "query": "1/lipstick",
                    "operator": "OR",
                    "fuzzy_transpositions": true,
                    "auto_generate_synonyms_phrase_query": true,
                    "boost": 1
                  }
                }
              },
              "weight": 99
            },
            {
              "filter": {
                "terms": {
                  "product_ids": [
                    "166168",
                    "753547",
                    "156835",
                    "90112"
                  ]
                }
              },
              "weight": 42
            }
          ],
          "boost_mode": "avg",
          "score_mode": "sum"
        }
      }
    }