1. 程式人生 > 實用技巧 >Elasticsearch painless指令碼中空值的檢查

Elasticsearch painless指令碼中空值的檢查

最近在做指令碼重評分時,遇上了一個空值問題。查詢時painless指令碼中若遇到欄位中的值為空值就會報錯,本來想用 value == null 這種形式的判斷來判斷欄位值是否為空,然後過來掉,結果發現並不行,

以下時錯誤示範:

這個重評分的程式碼在defprice欄位全部都有值得時候執行正常,但是一旦出現沒有值得情況,就會報以下錯誤

{
  "error": {
    "root_cause": [{
      "type": "script_exception",
      "reason": "runtime error",
      "script_stack": [
        
"org.elasticsearch.index.fielddata.ScriptDocValues$Longs.get(ScriptDocValues.java:121)", "org.elasticsearch.index.fielddata.ScriptDocValues$Longs.getValue(ScriptDocValues.java:115)", "if(doc['cpinfo_youkewang.defprice'].value>0) {", " ^---- HERE" ],
"script": "if(doc['cpinfo_youkewang.defprice'].value>0) {return 1.0/doc['cpinfo_youkewang.defprice'].value;} else return 0;", "lang": "painless" }], "type": "search_phase_execution_exception", "reason": "all shards failed", "phase": "query", "grouped": true, "failed_shards": [{
"shard": 0, "index": "aiso_20q2v1_detail_gasstation", "node": "NE8IhhppQKalVXnjU-axBQ", "reason": { "type": "script_exception", "reason": "runtime error", "script_stack": [ "org.elasticsearch.index.fielddata.ScriptDocValues$Longs.get(ScriptDocValues.java:121)", "org.elasticsearch.index.fielddata.ScriptDocValues$Longs.getValue(ScriptDocValues.java:115)", "if(doc['cpinfo_youkewang.defprice'].value>0) {", " ^---- HERE" ], "script": "if(doc['cpinfo_youkewang.defprice'].value>0) {return 1.0/doc['cpinfo_youkewang.defprice'].value;} else return 0;", "lang": "painless", "caused_by": { "type": "illegal_state_exception", "reason": "A document doesn't have a value for a field! Use doc[<field>].size()==0 to check if a document is missing a field!" } } }] }, "status": 400 }

輾轉之後偶然看了下報錯資訊,發現報錯原因裡面有提示如何看是否為空值,

於是把程式碼改成以下就可以了:

"rescore": [{
    "window_size": 10000,
    "query": {
      "score_mode": "total",
      "rescore_query": {
        "function_score": {
          "script_score": {
            "script": "if(doc['cpinfo_youkewang.defprice'].size() > 0 && doc['cpinfo_youkewang.defprice'].value>0) {return 1.0/doc['cpinfo_youkewang.defprice'].value;} else return 0;"
          }
        }
      }
    }
  }],

就是用得提示中得doc[<field>].size()來判斷的。