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); 
}