• ElasticSearch中更新数组字段中值


    背景:

           我们对es中,我们会对一些数组之类的字段进行存储,但是要更新里面数组中的某一个值,你必须得整个拉出来,在内存中处理之后再赋值修改,这样比较消耗内存,而且随着数据增多,这影响更大,因此特意研究了下怎么通过es去实现

    解决方案:

          首先想到的就是通过脚本来实现,参考了官网的文档之后,发现可以行,es脚本文档地址,链接 https://www.elastic.co/guide/en/elasticsearch/painless/current/painless-lang-spec.html 

        现在kibana上实现,比如我要对tags这个字段更新,脚本如下:

    POST /xx_index/_update_by_query
    {
      "query": {
        "term": {
          "_id": "111"
        }
      },
      "script": {
        "lang": "painless",
        "source": "def tags= ctx._source.tags;def newTag=params.tagInfo; if (tags == null) {  ctx._source.tags = [params.tagInfo];} else {tags.removeIf(item->item['tagId']==newTag['tagId']);tags.add(newTag);}",
        "params": {
          "tagInfo": {
    	"tagId": 1,
            "name": "标签",
            "des": "说明",
            "no": 1
          }
        }
      }
    }
    

     通过比较tagId,先移除再新增的方式实现更新替换,因为es也支持lambda的语法,实现起来比较方便

    接下来可以通过代码来实现 

    public void updateTag(String id, Class clz, Tag tag) {
        if(Objects.isNull(id) || Objects.isNull(encounterTag)){
             return;
        }
        UpdateRequest updateRequest = new UpdateRequest();
        String scriptStr = "def tags= ctx._source.tags;def newTag=params.tagInfo; if (tags == null) {  ctx._source.tags = [params.tagInfo];} else {tags.removeIf(item->item['tagId']==newTag['tagId']);tags.add(newTag);}";
        Map<String, Object> params = new HashMap<>();
        params.put("tagInfo", JSONObject.toJSON(tag));
        Script script = new Script( Script.DEFAULT_SCRIPT_TYPE,Script.DEFAULT_SCRIPT_LANG, scriptStr, params);
        updateRequest.script(script);
        UpdateQuery updateQuery = new UpdateQueryBuilder().withId(id).withClass(clz).withUpdateRequest(updateRequest).build();
        elasticsearchTemplate.update(updateQuery);
        elasticsearchTemplate.refresh(clz);
    }
    

     为了更方便使用,又增加了一个可以批量增加的,实现方式类似

    脚本如下:

    POST /enc_encounter_list/_update_by_query
    {
      "query": {
        "term": {
          "_id": "11122"
        }
      },
      "script": {
        "lang": "painless",
        "source": "def tags= ctx._source.tags;def newTag=params.tagInfo; if (tags == null) {  ctx._source.tags = params.tagInfo;} else {for(def t : newTag){tags.removeIf(item->item['tagId']==t['tagId']);tags.add(t);}}",
        "params": {
          "tagInfo": [
             {
    	    "tagId": 1,
            "name": "标签",
            "des": "说明",
    		"no": 1
          },
          {
    	    "tagId": 2,
            "name": "标签2",
            "des": "说明2",
    		"no": 2
          }
          ]
        }
      }
    }
    

      后端类似,此处就不在赘述了。

      es脚本还可以给我们解决更多问题,后续再继续跟踪记录。

     

  • 相关阅读:
    python的metaclass
    鱼和水的故事
    iOS的QuickTime Plugin
    二进制/十六进制转浮点数的编程(互转类似)
    Android开发常见错误及技巧
    Mac 热键大全
    Java动态程序设计:反射介绍
    注册asp.net 4.0 到iis
    javascript常用判断写法
    将存储过程执行的结果保存到临时表
  • 原文地址:https://www.cnblogs.com/xzshare/p/14215295.html
Copyright © 2020-2023  润新知