user697547
user697547

Reputation: 81

Elasticsearch custom scoring script -- check if field exists?

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

Answers (2)

Evan Kleiner
Evan Kleiner

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

imotov
imotov

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

Related Questions