日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

ES更新嵌套数组(使用Java API)

發布時間:2024/2/28 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ES更新嵌套数组(使用Java API) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近在做一個需求,一開始的時候以為用es腳本能搞定,耽擱了一天半時間。

后來用了Java client 的api來做,效率快多了。

package com.XXX.XXXX.XXX;import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.exception.ExceptionUtils; import org.assertj.core.util.Arrays; import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptType; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;import javax.annotation.Resource; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.Map;@Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class HestiaApplicationTests {@Resourceprotected RestHighLevelClient client;@Testpublic void contextLoads() {}/*** *先檢索、再更新文檔**/@Testpublic void search() throws IOException {try {SearchRequest searchRequest = new SearchRequest("zm_prod");SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();// 第幾頁searchSourceBuilder.from(0);Map<String, Object> params = new HashMap<>();//課程標簽:1.大班課;2.小班課;3.AI課;4.磨課 // Script script = new Script(ScriptType.INLINE, "painless", "ctx._source.values.base_info.course_mark == 2", params); // searchSourceBuilder.query(QueryBuilders.scriptQuery(script)); // searchSourceBuilder.query(QueryBuilders.matchQuery("_source.values.base_info.course_mark",2));searchSourceBuilder.query(QueryBuilders.termQuery("_id", 55074)); // searchSourceBuilder.query(QueryBuilders.matchAllQuery());// 每頁多少條數據searchSourceBuilder.size(1000);// 設置超時時間為2ssearchSourceBuilder.timeout(new TimeValue(2000));// 設置request要搜索的索引和類型 // searchRequest.indices("zm_prod").types("news");// 設置SearchSourceBuilder查詢屬性searchRequest.source(searchSourceBuilder);SearchResponse searchResponse = client.search(searchRequest);SearchHit[] searchHits = searchResponse.getHits().getHits();if (ArrayUtils.isEmpty(searchHits)) {log.info("searchHits = 666666666666666666666");}for (SearchHit hit : searchHits) {//文檔的主鍵String id = hit.getId();String index = hit.getIndex();String type = hit.getType();String sourceAsString = hit.getSourceAsString();if(!sourceAsString.contains("course_mark")){continue;}//源文檔內容Map<String, Object> sourceAsMap = hit.getSource(); // String s = JSON.toJSONString(sourceAsMap);Map<String, Object> values = (Map)sourceAsMap.get("values");Map<String, Object> base_info = (Map)values.get("base_info");Integer course_mark = (Integer) base_info.get("course_mark");String base_infostr = JSON.toJSONString(base_info);if(null!=course_mark){if(course_mark==1||course_mark==2||course_mark==3){log.info(" base_infostr = " + base_infostr);//TODO 這個地方反向的在map里面添加字段,然后重新組裝,然后更新當前的數據base_info.put("BBB",7777);values.put("base_info",base_info);UpdateRequest uRequest = new UpdateRequest().index(index).type(type).id(id).doc(XContentFactory.jsonBuilder().startObject().field("values", values).endObject());BulkRequest blkRequest = new BulkRequest();blkRequest.add(uRequest);// 執行BulkResponse bulkResponse = client.bulk(blkRequest); // for (UpdateRequest uprequest : list) { // bulkResponse.add(uprequest); // }// BulkResponse bulkResponse = bulkResponse.execute().actionGet();if (bulkResponse.hasFailures()) {System.out.println("批量錯誤!");}}}}} catch (IOException e) {e.printStackTrace();log.error(ExceptionUtils.getMessage(e));}}}

-------------------------------------------------------------------------------------------------------------------

以下是參考別的博主的內容;

最近在學習ElasticSearch,前些天在工作中遇到一個難以解決的問題,問題正如標題所示在使用Java TransportClient更新ES復雜數據結構數組,最后請教大佬問題得以解決。此文章將詳細描述問題并提供解決辦法。

博主要更新的數據格式大致如下:?

原數據:一個嵌套類型的數組
更新后的數據:將商場01對應的數據從數組刪除

"list":[{"code":?"9111364","name":?"企業01"},{"code":?"900662","name":?"智能01"},{"code":?"9000300","name":?"商場01"} ]


博主是ES小白,對于此類型的數據不知道如何正確使用?UpdateRequest進行更新。

于是乎使用如下方法,value表示更新的數據(也就是沒有"商場01"的list數據),對于value的類型博主嘗試過Object和List<>,甚至將list轉成Json格式結果都不可以。

// XXXXXXXXX表示要更新的數據
// List value = XXXXXXXXX;
// XXXXXXXXX表示要更新的數據
// Object value = XXXXXXXXX;
List> value = XXXXXXXXX; // 這個好用
updateRequest.doc(XContentFactory.jsonBuilder()
? ? ? ? ? ? ? ? ? ? .startObject()
? ? ? ? ? ? ? ? ? ? .field("name", value)
? ? ? ? ? ? ? ? ? ? .field(flag, 1)
? ? ? ? ? ? ? ? ? ? .endObject()); ? ?
最后大佬告訴我要將List value轉成List> value,也就是當使用updateRequest的時候,對于字段類型是對象數組的,ES是無法正常更新的,要將List中的泛型專程Map類型,Es才會識別。

?// 將嵌套數組對象轉Set格式(List也可以),否則無法進行更新(會報錯)
? ? ? ? List> set = Lists.newArrayList();
? ? ? ? Map map = Maps.newHashMap();
? ? ? ? Class clazz;
? ? ? ? // 使用反射動態將Set中的屬性值放入Map中
? ? ? ? for (Object obj : setArry) {
? ? ? ? ? ? clazz = obj.getClass();
? ? ? ? ? ? // 遍歷當前對象的屬性值
? ? ? ? ? ? for (Field field : clazz.getDeclaredFields()) {
? ? ? ? ? ? ? ? field.setAccessible(true);
? ? ? ? ? ? ? ? String name = field.getName();
? ? ? ? ? ? ? ? Object value = field.get(obj);
? ? ? ? ? ? ? ? map.put(name, value);
? ? ? ? ? ? }
? ? ? ? ? ? set.add(map);
? ? ? ? ? ? map = Maps.newHashMap();
由于此種數組類型較多,博主使用反射,可以兼容每種數組類型。最后成功更新數據。

---------------------------------------------------------------------------------------------------------------

同時參考了

如果更新一條文檔,而且知道文檔id的前提下可以使用UpdateRequest即可實現,代碼如下:

/*** 根據文檔id更新* @throws IOException*/@Testpublic void test() throws IOException {UpdateRequest request = new UpdateRequest("sub_bank1031","sub_bank","SvjgP24BndtcmnpzbiuL");request.doc("{\"aliasName\":\"中國農業發展銀行林州市支行444\",\"bankType\":\"ADB\",\"bankTypeName\":\"中國農業發展銀行\",\"cityId\":\"410500\",\"cityName\":\"安陽市\",\"createTime\":1515719190000,\"createUser\":\"system\",\"id\":\"000238a326b044e9ae10cfe4298f4c44\",\"isEnabled\":\"1\",\"name\":\"中國農業發展銀行林州市支行\",\"provinceId\":\"410000\",\"provinceName\":\"河南省\",\"unionNumber\":\"203496100010\"}", XContentType.JSON);UpdateResponse resp = highLevelClient.update(request, RequestOptions.DEFAULT);println(resp.getResult());}


但是如果不知道文檔id的情況如果還想使用UpdateRequest更新文檔就需要先使用SearchRequest根據某個條件查詢符合條件的文檔,然后再循環更新文檔即可。

/****先檢索、再更新文檔**/@Testpublic void search() throws IOException{SearchRequest searchRequest = new SearchRequest("sub_bank1031");SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.matchQuery("_id", "SvjgP24BndtcmnpzbiuL"));searchSourceBuilder.size(2);searchRequest.source(searchSourceBuilder);SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT); SearchHit[] searchHits = searchResponse.getHits().getHits();for(SearchHit s:searchHits){String docId = s.getId();UpdateRequest request = new UpdateRequest("sub_bank1031","sub_bank",docId);request.doc("{\"aliasName\":\"中國農業發展銀行林州市支行444\",\"bankType\":\"ADB\",\"bankTypeName\":\"中國農業發展銀行\",\"cityId\":\"410500\",\"cityName\":\"安陽市\",\"createTime\":1515719190000,\"createUser\":\"system\",\"id\":\"000238a326b044e9ae10cfe4298f4c44\",\"isEnabled\":\"1\",\"name\":\"中國農業發展銀行林州市支行\",\"provinceId\":\"410000\",\"provinceName\":\"河南省\",\"unionNumber\":\"203496100010\"}", XContentType.JSON);UpdateResponse resp = highLevelClient.update(request, RequestOptions.DEFAULT);println(resp.getResult()); }}


上面操作略顯麻煩,需要多條http請求才能完成,要更新的文檔數量很多時將大大降低系統響應速度,這時候我們可以使用es的UpdateByQueryRequest來實現該功能。

/*** 通過腳本更新文檔* @throws IOException*/@Testpublic void updateByQueryRequest() throws IOException {UpdateByQueryRequest request = new UpdateByQueryRequest("sub_bank1031");request.setDocTypes("sub_bank");request.setQuery(new TermQueryBuilder("cityId", "511000"));request.setSize(2);request.setScript(new Script(ScriptType.INLINE, "painless","if (ctx._source.bankType == 'BOC') {ctx._source.aliasName='hello'}",Collections.emptyMap()));?? ?BulkByScrollResponse resp = highLevelClient.updateByQuery(request, RequestOptions.DEFAULT);}

PS:

pom文件es相關依賴如下:

??<dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>6.8.0</version></dependency><!-- elasticsearch high level --> ???<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><exclusions><exclusion><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId>????????????????</exclusion></exclusions><version>6.8.0</version></dependency>

總結

以上是生活随笔為你收集整理的ES更新嵌套数组(使用Java API)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。