Elasticsearch Query: Final Result of Multiplication Using Evaluating Nested Objects and Functions

I have docs with some data and a specific list to skip in it (see mapping and data examples ):

I would like to write an ES request that does the following:

  • Calculate some "baseline" scores for documents (query 1):

    {
      "explain": true,
      "query": {
        "bool": {
          "should": [
            {
              "constant_score": {
                "filter": {
                  "term": {
                    "type": "TYPE1"
                  }
                }
              }
            },
            {
              "function_score": {
                "linear": {
                  "number": {
                    "origin": 30,
                    "scale": 20
                  }
                }
              }
            }
          ]
        }
      }
    }
    
          

  • At the end, multiply the score according to the missing percent of the specific id (In the example I used, omit the valut for A "omit.id": "A"

    ). As a demonstration in Query 2, I computed this factor.

    {
      "query": {
        "nested": {
          "path": "omit",
          "query": {
            "function_score": {
              "query": {
                "filtered": {
                  "query": {
                    "match_all": {}
                  },
                  "filter": {
                    "term": {
                      "omit.id": "A"
                    }
                  }
                }
              },
              "functions": [
                {
                  "linear": {
                    "omit.percent": {
                      "origin": 0,
                      "scale": 50,
                      "offset": 0,
                      "decay": 0.5
                    }
                  }
                }
              ],
              "score_mode": "multiply"
            }
          }
        }
      }
    }
    
          

To achieve this final multiplication, I ran into the following problems:

  • If I compute the evaluation of a linear function inside a nested query (as per my interpretation), I cannot use any other field in the query function_score

    .
  • I cannot multiply the computed score by any other function_score

    that is encapsulated in a subquery.

I would like to ask for advice for solving this problem.

Note that perhaps I should get rid of this nested type and use key-value pairs instead. For example:

{
  "omit": {
    "A": {
      "percent": 10
    },
    "B": {
      "percent": 100
    }
  }
}

      

but unfortunately there will be a lot of keys, which will result in a huge (ever-growing) display, so I don't prefer this option.

+3


source to share


1 answer


At least I figured out a possible solution based on a "non-nested path". The complete script can be found here .

I changed the skip list as described in the question:

"omit": {
  "A": {
    "percent": 10
  },
  "B": {
    "percent": 100
  }
}

      

In addition, I set the flag enabled

on the false

that do not have these items in the map:



"omit": {
  "type" : "object",
  "enabled" : false
}

      

The last trick was to use script_score

as a function function_score

, because that's the only way I could use the value percent

on the _source.omit.A.percent

script:

{
  "query": {
    "function_score": {
      "query": {
        ...
      },
      "script_score": {
        "lang": "groovy",
        "script": "if (_source.omit.A){(100-_source.omit.A.percent)/100} else {1}"
      },
      "score_mode": "multiply"
    }
  }
}

      

+2


source







All Articles