3

I have documents with some data and a specific omit list in it (see mapping and example data):

I would like to write an ES query which does the following:

  1. Calculate some "basic" score for the documents (Query 1):

    {
      "explain": true,
      "query": {
        "bool": {
          "should": [
            {
              "constant_score": {
                "filter": {
                  "term": {
                    "type": "TYPE1"
                  }
                }
              }
            },
            {
              "function_score": {
                "linear": {
                  "number": {
                    "origin": 30,
                    "scale": 20
                  }
                }
              }
            }
          ]
        }
      }
    }
    
  2. At the end multiply the score according to the omit percent of a specific id (In the example I used omit valut for A"omit.id": "A"). As a demonstration in Query 2 I calculated this multiplier.

    {
      "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 faced with the following problems:

  • If I calculate linear function score inside of a nested query, (according to my interpretation) I cannot use any other field in function_score query.
  • I cannot multiply the calculated score with any other function_score which is encapsulated into a nested query.

I would like to ask for any advice to resolve this issue.

Note that maybe 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 would result a huge (continuously growing) mapping, so I not prefer this option.

1 Answer 1

2

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

I modified the omit list as described in the question:

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

In addition I set the enabled flag to false to not have these elements in the mapping:

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

The last trick was to use script_score as a function_score's function, because only there I could use the value of percent by _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"
    }
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.