ElasticsearchTemplate获取大数据集(ElasticsearchTemplate

2019-10-29 11:57发布

我是新来ElasticsearchTemplate。 我想根据我的查询从Elasticsearch 1000个文档。 我用的QueryBuilder创建我的查询,并且它可以正常使用。 我已经通过以下链接,其中指出,有可能实现使用扫描和滚动大数据集了。

一个链接
连接两个

我想实现在下面的代码段这个功能,我有一份来自链路的一个贴,上面提到的。 但我得到以下错误:

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

什么是这里的问题? 是否有任何其他的替代实现这一目标? 我会感激,如果有人能告诉我如何(代码)在后台工作。

Answer 1:

解决方法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);
}


文章来源: ElasticsearchTemplate retrieve big data sets