问题描述:
项目中通过查询ES中某个字段,并更新某个值的字段,当量比较大的时候报错:
upsert associated failed: elastic: Error 500 (Internal Server Error): Failed to compile inline script [ctx._source.pcap_filename = ] using lang [painless] [type=general_script_exception]
问题解析:
1. 通过查询某个字段并更新这条数据中某个值的时候,如果是通过Script的方式更新,需要先阅读ES的官方Script撰写界面:How to write scripts | Elasticsearch Guide [8.11] | Elastic
2. 我是使用硬编码的方式直接撰写的ES的script,我写的代码(Go),
script := "ctx._source.pcap_filename = '" + fileName + "'"
fileName 是一个变量,script 在编译的时候直接就硬编码,所以每一次更新的时候都要重新compile这个script,当量比较大的时候,就超过下面如图所示的限制了。ES的script是有次数限制的,当你触发先至的时候,就会报这个错误
3. 问题解决方式:
通过官方script 介绍的方式,
script := "ctx._source.pcap_filename = params['fileName']"
通过上面的方式写,每次script都是一样的,但是params不一样,就不用es重新编译这个script,直接在script 中的cache中取出已经编译的script,替换param中的数据就可以了。
通过参数的方式进行传递,在go中
res, err := es.client.UpdateByQuery().Index(index).Query(match_query).Script(elastic.NewScript(script).Param("fileName", fileName)).Do(es.ctx)
使用上面的代码,查询、撰写script,并且设置参数fileName。
这样应该就不会报这个错误了。
其余参考网站:1. https://github.com/elastic/elasticsearch-net/issues/29612
2. https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting.html
3. Understanding and fixing “too many script compilations” errors in Elasticsearch