0

我是ElasticsearchTemplate的新手。我想根據我的查詢從Elasticsearch獲取1000個文檔。 我已經使用QueryBuilder創建我的查詢,並且它工作正常。 我已經通過以下鏈接,其中指出可以使用掃描和滾動來實現大數據集。

link one
link twoElasticsearchTemplate檢索大數據集

我想實現在下面的代碼段這個功能,我有一份來自鏈路的一個貼,上面提到的。 但我收到以下錯誤:

The type ResultsMapper is not generic; it cannot be parameterized with arguments <myInputDto>.

MyInputDto是在我的項目@Document註解的類。 一天結束,我只想從Elasticsearch中檢索1000個文檔。 我試圖找到size參數,但我認爲它不受支持。

String scrollId = esTemplate.scan(searchQuery, 1000, false); 
     List<MyInputDto> sampleEntities = new ArrayList<MyInputDto>(); 
     boolean hasRecords = true; 
     while (hasRecords) { 
      Page<MyInputDto> page = esTemplate.scroll(scrollId, 5000L, 
        new ResultsMapper<MyInputDto>() { 
         @Override 
         public Page<MyInputDto> mapResults(SearchResponse response) { 
          List<MyInputDto> chunk = new ArrayList<MyInputDto>(); 
          for (SearchHit searchHit : response.getHits()) { 
           if (response.getHits().getHits().length <= 0) { 
            return null; 
           } 
           MyInputDto user = new MyInputDto(); 
           user.setId(searchHit.getId()); 
           user.setMessage((String) searchHit.getSource().get("message")); 
           chunk.add(user); 
          } 
          return new PageImpl<MyInputDto>(chunk); 
         } 
        }); 
      if (page != null) { 
       sampleEntities.addAll(page.getContent()); 
       hasRecords = page.hasNextPage(); 
      } else { 
       hasRecords = false; 
      } 
     } 

這裏有什麼問題? 有沒有其他的選擇來實現這一目標? 如果有人能告訴我這個(代碼)是如何在後端工作的,我會很感激。

回答

0

解決方案1 ​​

如果你想使用ElasticsearchTemplate,這將是更簡單,可讀的使用CriteriaQuery,因爲它允許與setPageable方法設置頁面大小。隨着滾動,你可以得到的數據的下一集:

CriteriaQuery criteriaQuery = new CriteriaQuery(Criteria.where("productName").is("something")); 
criteriaQuery.addIndices("prods"); 
criteriaQuery.addTypes("prod"); 
criteriaQuery.setPageable(PageRequest.of(0, 1000)); 

ScrolledPage<TestDto> scroll = (ScrolledPage<TestDto>) esTemplate.startScroll(3000, criteriaQuery, TestDto.class); 
while (scroll.hasContent()) { 
    LOG.info("Next page with 1000 elem: " + scroll.getContent()); 
    scroll = (ScrolledPage<TestDto>) esTemplate.continueScroll(scroll.getScrollId(), 3000, TestDto.class); 
} 
esTemplate.clearScroll(scroll.getScrollId()); 

解決方案2

如果您想使用org.elasticsearch.client.Client代替ElasticsearchTemplate,然後SearchResponse允許設置數量的搜索點擊返回:

QueryBuilder prodBuilder = ...; 

SearchResponse scrollResp = client. 
     prepareSearch("prods") 
     .setScroll(new TimeValue(60000)) 
     .setSize(1000) 
     .setTypes("prod") 
     .setQuery(prodBuilder) 
     .execute().actionGet(); 

ObjectMapper mapper = new ObjectMapper(); 
List<TestDto> products = new ArrayList<>(); 

try { 
    do { 
     for (SearchHit hit : scrollResp.getHits().getHits()) { 
      products.add(mapper.readValue(hit.getSourceAsString(), TestDto.class)); 
     } 
     LOG.info("Next page with 1000 elem: " + products); 
     products.clear(); 
     scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()) 
       .setScroll(new TimeValue(60000)) 
       .execute() 
       .actionGet(); 
    } while (scrollResp.getHits().getHits().length != 0); 
} catch (IOException e) { 
    LOG.error("Exception while executing query {}", e); 
}