Updating elasticsearch entities with bulk

后端 未结 1 1691
借酒劲吻你
借酒劲吻你 2020-12-21 17:12

I have this database data as below (ES 7.xx) version

    {
   "id":"1234",
   "expirationDate":"17343234234",
   "         


        
1条回答
  •  半阙折子戏
    2020-12-21 17:35

    If you are using Elasticsearch 7.xx, I will assume that you have use Spring Data Elasticsearch version 4.0.x that comes with Spring boot 2.3.x. Since it's the version that support Elasticsearch 7.xx.

    There're many things that have change in this Spring Data Elasticsearch version. Update document by query is one of them. Unlike before that we autowired ElasticsearchTemplate, we now have to use ElasticsearchRestTemplate and RestHighLevelClient instead.

    In your case if you might want to use RestHighLevelClient to update document by query. Assume that you stored expirationDate as number mapping type in seconds unit then the code that you have asked for should look like this.

    public class ElasticsearchService {
    
        @Autowired
        private ElasticsearchRestTemplate elasticsearchRestTemplate;
    
        @Autowired
        private RestHighLevelClient highLevelClient;
    
        public void updateExpireDateDemo() throws IOException {
            String indexName = "test";
            Date currentDate = new Date();
            Long seconds = (Long) (currentDate.getTime() / 1000);
            UpdateByQueryRequest request = new UpdateByQueryRequest(indexName);
            request.setQuery(new RangeQueryBuilder("expirationDate").lte(seconds));
            Script updateScript = new Script(
                    ScriptType.INLINE, "painless",
                    "ctx._source.expirationDate=" + seconds + ";",
                    Collections.emptyMap());
            request.setScript(updateScript);
            highLevelClient.updateByQuery(request, RequestOptions.DEFAULT);
        }
    }
    

    I'm not quite get why you really need to use the bulkUpdate but if that's the case then. You have to query the record that need to be update from Elasticsearch to get and id of each document first. Then you can update with list of UpdateQuery. So your code will look like this.

    @Service
    public class ElasticsearchService {
        @Autowired
        private ElasticsearchRestTemplate elasticsearchRestTemplate;
    
        public void updateExpireDateByBulkDemo() throws IOException {
            String indexName = "test";
            Date currentDate = new Date();
            Long seconds = (Long) (currentDate.getTime() / 1000);
            List updateList = new ArrayList();
            RangeQueryBuilder expireQuery = new RangeQueryBuilder("expirationDate").lte(seconds);
            NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(expireQuery).build();
            SearchHits searchResult = elasticsearchRestTemplate.search(query, Data.class, IndexCoordinates.of(indexName));
            for (SearchHit hit : searchResult.getSearchHits()) {
                String elasticsearchDocumentId = hit.getId();
                updateList.add(UpdateQuery.builder(elasticsearchDocumentId).withScript("ctx._source.expirationDate=" + seconds + ";").build());
            }
            if (updateList.size() > 0) {
                elasticsearchRestTemplate.bulkUpdate(updateList, IndexCoordinates.of(indexName));
            }
        }
    }
    
    

    However, this only update first page of the search result. If you require to update every record matched your query then you have to use searchScroll method in oder to get every document id instead.

    0 讨论(0)
提交回复
热议问题