elasticsearch使用script判断字段是否为空null

最近在使用es进行如下更新操作时:

POST customer/customer_info/_update_by_query
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "filter": [
        {
    
    
          "term": {
    
    
            "data_type": {
    
    
              "value": 1
            }
          }
        },
        {
    
    
          "terms": {
    
    
            "customer_id": [
              "101320130050"
            ]
          }
        }
      ]
    }
  },
  "script": {
    
    
    "source": """
         if(!ctx._source.customer_group.contains(params.val)) {
    
    
              ctx._source.customer_group.add(params.val)
          }""",
    "params": {
    
    
      "val": "22347"
    }
  }
}

script说明:先查询出data_type是1并且customer_id是101320130050的文档,然后如果这个文档的数组customer_group里不包含22347则把22347加到customer_group里。

运行报错:
dynamic method [java.lang.String,add/1] not fond
在这里插入图片描述

后来排查原因是因为customer_group是空或者数组元素是0导致的。简单说就是data_type是1并且customer_id是101320130050的这个文档没有customer_group这个字段,或者customer_group数组里面一个元素也没有导致的,就像是样"customer_group":[ ]

查阅资料发现,es使用script来判断为空和元素等于0可以这样写:

ctx._source.customer_group==null||ctx._source.customer_group?.size() ==0
或者:
ctx._source.customer_group==null||ctx._source.customer_group.length==0

修改后的dsl语句如下:

POST customer_v2023/customer_info/_update_by_query
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "filter": [
        {
    
    
          "term": {
    
    
            "data_type": {
    
    
              "boost": 1,
              "value": 1
            }
          }
        },
        {
    
    
          "terms": {
    
    
            "boost": 1,
            "customer_id": [
              "101320130050"
            ]
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  },
  "script": {
    
    
    "source": """
 if(ctx._source.customer_group==null||ctx._source.customer_group?.size() ==0) {
    
    
        ctx._source.customer_group=[params.val]
      } else if(!ctx._source.customer_group.contains(params.val)) {
    
    
        ctx._source.customer_group.add(params.val)
      }
""",
    "params": {
    
    
      "val": "22347"
    }
  }
}

script说明: 如果customer_group为空或里面元素为0则将22347直接赋值给customer_group,否则如果customer_group不包含22347则将22347加入到customer_group。

网上其他的如通过doc[‘xxx’].length或doc[‘fieldname’].values.length来判断经过测试没能成功,可能和es的不同版本有关:

   "script": {
    
    
          "source": "doc['xxx'].length==0",
          "lang": "painless"
   }

关于elasticsearch的script判断字段是否为空以及元素的大小判断参考的其他网址:

elasticsearch filtering by the size of a field that is an array
elasticsearch filter by length of a string field
Script queryedit

猜你喜欢

转载自blog.csdn.net/qq_33697094/article/details/109684578