Elasticsearch 追加更新文档(即不覆盖原来的数据)

最近一直在研究怎么对es 数据库进行追加更新,因为无论是整个文档更新还是局部的更新,都是先找到旧的,然后标记删除,然后再添加新的文档,显然这不能满足需要对文档追加更新的需求,即不覆盖之前的记录进行更新。以下分情况进行研究:
一. 需要更新的字段为list类型

  1. 对list的元素进行追加更新,即增加list元素数量,list长度变化
    不管是对列表还是对字符串的追加更新,都需要利用脚本来进行,script比较灵活可以自己定义你想实现的逻辑,如下,首先判断文档中有没有vuln_label这个字段(filed),没有的话添加一个这个字段,数据结构定为列表,如果有这个字段则追加更新params.tag
body = {
      "script": {
          "lang": "painless",
          "source": "if(ctx._source.vuln_label==null){ctx._source.vuln_label=[];ctx._source.vuln_label.add(params.tag)}"
         	 		"else{ctx._source.vuln_label.add(params.tag)}",
          "params": {
               "tag":{
                  "CVE_ID": item['CVE_ID'],
                  "creates_time": item['created_time'],
                  "risk_level": item['risk_level'],
                  "Description": item['Description'],
                  "vulnerable_type": item['vulnerable_type']
                                }

                            }
                        }
                    }
  1. 对list元素的key:value进行追加更新,即增加list元素的键值对数量,list长度不变
    思路:将需要更新的字段赋给一个空的列表对象,后根据字段的index也就是下标去遍历list种的元素,更新脚本可写为:
query = {"query": {"bool": {"must": {"exists": {"field": "vulns"}}}}}
# print(es.count(index='2021-10_cn_asset', doc_type='iot_asset',  body=query))
a = es.search(index='2021-10_cn_asset', doc_type='iot_asset', scroll='5m', body=query, size=1000)
result = a['hits']['hits']

total = a['hits']['total']
scroll_id = a['_scroll_id']

for item4 in range(0, int(total / 1000) + 1):
    query_scroll = es.scroll(scroll_id=scroll_id, scroll='5m')['hits']['hits']
    result += query_scroll
s = []

for item in result:
	ll = item['_source']['vulns']
	r = range(len(ll))
	for item1 in r:
		if item1 == 0:
			body2 = {
	                    "script": {
	                        "lang": "painless",
	                        "source": "if(ctx._source.vulns!=null){ctx._source.vulns=[];ctx._source.vulns.add(params.tag)}",
	                        "params": {
	                            "tag": {}}}}
		 else:
		 	body2 = {
	                  "script": {
	                        "lang": "painless",
	                        "source": "ctx._source.vulns.add(params.tag)",
	                        "params": {
	                            "tag": {}}}}

以此为例,其中ll为空的列表对象,vulns为需要更新的字段,其type 为list,其中区别就是第一个元素和后面元素的更新脚本不一样。如此,即可完成列表元素种键值对的追加更新,不改变原来的结构,当然,tag中要将原来的键值对一一罗列,再加上需要增加的键值对。
二. 对字符串的追加更新
对字符串的追加更新更新和列表类似:

body={"script": {"source":"ctx._source.name+=params.tag","params":{"tag":"黄晓明"}}}
  1. 对字典的追加更新(这种情况建议新增一个字段),例如情况1
    注意**:用source而不是inline,使用inline会有警告!**
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值