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腳本還可以給我們解決更多問題,后續再繼續跟蹤記錄。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM