Reputation: 278
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:
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
}
}
}
}
]
}
}
}
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:
function_score
query. 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.
Upvotes: 3
Views: 1923
Reputation: 278
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"
}
}
}
Upvotes: 2