Reputation: 81
I'd like check if a field exists in my custom scoring script when searching in elasticsearch.
This search works:
{
"query": {
"custom_score": {
"script": "((doc['region'].value == '1') ? 1 : 0)",
"query": {
"constant_score": {
"filter": {
"and": [
{
"term": {
"id": "100"
}
}
]
}
}
}
}
},
"size": 1
}
It will score the result as 1 if the region field value is 1.
However this query will not work: it will not score the document as 1 if the region field does not exist in the document:
{
"query": {
"custom_score": {
"script": "((doc['region'].value == null) ? 1 : 0)",
"query": {
"constant_score": {
"filter": {
"and": [
{
"term": {
"id": "100"
}
}
]
}
}
}
}
},
"size": 1
}
How do I check for missing values in a script?
Upvotes: 4
Views: 4664
Reputation: 514
This post addresses a similar issue. Long story short, you should use doc['fieldName'].size() == 0
to check if a field exists in an Elasticsearch script. Here's an example implementation that I have working to apply a Gaussian function to a date field only when that field is populated:
GET /items/_search
{
"size": 10,
"from": 0,
"query": {
"function_score": {
"_name": "favorNewItems",
"query": {
"bool": {
"must": [
"match": {"color": "blue"}
]
}
},
"functions": [
{
"gauss": {
"firstReceivedDate": {
"origin": "now",
"scale": "180d"
}
},
"weight": 2
},
{
"script_score": {
"script": "if (doc['publishDate'].size() == 0) return 0; return 1;"
}
}
],
"score_mode": "multiply",
"boost_mode": "sum"
}
}
}
Upvotes: 0
Reputation: 30163
If this field has a numeric type, which includes dates that are indexed as long, the missing value is represented by 0.
Upvotes: 14