Elasticsearch使用scrpit + pipeline更新join类型的文档

Elasticseach中可以使用在update和update_by_query中使用script来更新文档,一般情况下使用简单的赋值语句编写script就可以使用,例如:

ctx._source.txt = 'update info';

但是如果mapping中定义了join类型的父子关系的文档,使用script直接更新是有问题的,以painless脚本为例,首先,ctx._source在脚本中充当的是一个map,
如果我们脚本中直接使用‘ctx._source.map.key = value’ 当文档中map字段为空时,这时脚本找不到map,再去get(key)时会报出我们开发非常常见Null Pointer Exception,所以这时我们需要使用新建一个map去进行赋值,如下:

{
  "script": {
    "lang": "painless",
    "source": """
              HashMap map = new HashMap();
              map.name = 'child';
              map.parent = 'id';
              ctx._source.joinMap = map;
              """
  }
}

使用这样一个脚本更新就避免了NPE。
脚本其实这样就可以了,但是如果是更新join类型的文档,执行会报错:需要制定路由[_routing],原因如下
父子文档需要在同一个分片上,然后调整下脚本’ctx._routing = id;’,继续执行发现其实脚本不能更改_routing,
在这里插入图片描述
在painless的文档中也提到了_routing是只读的在这里插入图片描述
所以这时候需要考虑下使用新的方式,ingest pipeline,pipeline中的script可以更改索引文档的信息在这里插入图片描述
这样的话就可以定义一个pipeline,去更新_routing

PUT _ingest/pipeline/set_routing
{
  "processors": [
    {
      "script": {
        "source": """
              ctx._routing = 'id';
              """
      }
    }
  ]
}

这样以后就可以在update_by_query中更新join类型的文档了,完整的语句为

PUT _scripts/init_lines
{
  "script": {
    "lang": "painless",
    "source": """
              HashMap map = new HashMap();
              map.name = 'line';
              map.parent = params.characterId;
              ctx._source.character_or_line = map;
              """
  }
}
PUT _ingest/pipeline/set_routing
{
  "processors": [
    {
      "script": {
        "source": """
              ctx._routing = 'C0';
              """
      }
    }
  ]
}
POST hamlet_3/_update_by_query?pipeline=set_routing
{
  "script": {
    "id": "init_lines",
    "params": {
      "characterId": "C0"
    }
  },
  "query": {
    "match": {
      "speaker": "HAMLET"
    }
  }
}

因为在做ECE考试的一道题强制要求创建一个script,所以这里使用了script + pipeline的方式,最好是全部写到pipeline的script中,这里问了下ES的员工为什么普通的script和pipeline中的script不一样,一个可以更新索引的元数据一个不可以呢,回答我贴一下
在这里插入图片描述
果然官方还是一针见血,具体的实现的逻辑需要有空看下源码了。
参考:

  • https://www.elastic.co/guide/en/elasticsearch/reference/7.2/parent-join.html
  • https://www.elastic.co/guide/en/elasticsearch/reference/7.2/script-processor.html
  • https://www.elastic.co/guide/en/elasticsearch/painless/7.2/painless-update-context.html
  • https://discuss.elastic.co/t/the-difference-between-using-script-in-pipeline-and-using-normal-script-to-update-document/239951
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值