Elasticsearch получить все данные с фильтрами
Я хочу получить все данные из asticsearch с фильтрами без возможности постраничного просмотра. Каким способом лучше всего его получить? У меня установлен предел по умолчанию 2000. Я прочитал, что должен использовать сканирование, но я не знаю, как его использовать. Как мне использовать сканирование и прокрутку, чтобы получить все данные?
public Map searchByIndexParams(AuctionIndexSearchParams searchParams, Pageable pageable) {
final List<FilterBuilder> filters = Lists.newArrayList();
final NativeSearchQueryBuilder searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery());
Optional.ofNullable(searchParams.getCategoryId()).ifPresent(v -> filters.add(boolFilter().must(termFilter("cat", v))));
Optional.ofNullable(searchParams.getCurrency()).ifPresent(v -> filters.add(boolFilter().must(termFilter("curr", v))));
Optional.ofNullable(searchParams.getTreeCategoryId()).ifPresent(v -> filters.add(boolFilter().must(termFilter("tcat", v))));
Optional.ofNullable(searchParams.getUid()).ifPresent(v -> filters.add(boolFilter().must(termFilter("uid", v))));
//access for many uids
if(searchParams.getUids() != null){
Optional.ofNullable(searchParams.getUids().split(",")).ifPresent(v -> {
filters.add(boolFilter().must(termsFilter("uid", v)));
});
}
//access for many categories
if(searchParams.getCategories() != null){
Optional.ofNullable(searchParams.getCategories().split(",")).ifPresent(v -> {
filters.add(boolFilter().must(termsFilter("cat", v)));
});
}
final BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
if (Optional.ofNullable(searchParams.getTitle()).isPresent()) {
boolQueryBuilder.should(queryStringQuery(searchParams.getTitle()).analyzeWildcard(true).field("title"));
}
if (Optional.ofNullable(searchParams.getStartDateFrom()).isPresent()
|| Optional.ofNullable(searchParams.getStartDateTo()).isPresent()) {
filters.add(rangeFilter("start_date").from(searchParams.getStartDateFrom()).to(searchParams.getStartDateTo()));
}
if (Optional.ofNullable(searchParams.getEndDateFrom()).isPresent()
|| Optional.ofNullable(searchParams.getEndDateTo()).isPresent()) {
filters.add(rangeFilter("end_date").from(searchParams.getEndDateFrom()).to(searchParams.getEndDateTo()));
}
if (Optional.ofNullable(searchParams.getPriceFrom()).isPresent()
|| Optional.ofNullable(searchParams.getPriceTo()).isPresent()) {
filters.add(rangeFilter("price").from(searchParams.getPriceFrom()).to(searchParams.getPriceTo()));
}
searchQuery.withQuery(boolQueryBuilder);
FilterBuilder[] filterArr = new FilterBuilder[filters.size()];
filterArr = filters.toArray(filterArr);
searchQuery.withFilter(andFilter(filterArr));
final FacetedPage<AuctionIndex> search = auctionIndexRepository.search(searchQuery.build());
response.put("content", search.map(index ->auctionRepository
.findAuctionById(Long.valueOf(index.getId())))
.getContent());
return response;
}
редактировать:
Я получил:
String scrollId = searchTemplate.scan(searchQuery.build(), 1000, false);
Page<AuctionIndex> page = searchTemplate.scroll(scrollId, 15000L, AuctionIndex.class);
Integer i = 0;
if (page != null && page.hasContent()) {
while(page.hasContent()){
page = searchTemplate.scroll(scrollId, 15000L, AuctionIndex.class);
if(page.hasContent()){
System.out.println(i);
i++;
}
}
}
но итерация перейти к 166 и остановить, что не так?
1 ответ
Scroll API - лучший способ наиболее эффективно просмотреть все документы. С использованием scroll_id
вы можете найти сеанс, который хранится на сервере для вашего конкретного запроса прокрутки.
Вот пример того, как вы можете использовать java scroll api упругого поиска в своем коде, чтобы получить все результаты, соответствующие вашему запросу.
SearchResponse searchResponse = client.prepareSearch(<INDEX>)
.setQuery(<QUERY>)
.setSearchType(SearchType.SCAN)
.setScroll(SCROLL_TIMEOUT)
.setSize(SCROLL_SIZE)
.execute()
.actionGet();
while (true) {
searchResponse = client
.prepareSearchScroll(searchResponse.getScrollId())
.setScroll(SCROLL_TIMEOUT)
.execute().actionGet();
if (searchResponse.getHits().getHits().length == 0) {
break; //Break condition: No hits are returned
}
for (SearchHit hit : searchResponse.getHits()) {
// process response
}
}
Образец с использованием Spring-data -asticsearch
@Autowired
private ElasticsearchTemplate searchTemplate;
String scrollId = searchTemplate.scan(<SEARCH_QUERY>, 1000, false);
Page<ExampleItem> page = searchTemplate.scroll(scrollId, 5000L, ExampleItem.class);
if (page != null && page.hasContent()) {
// process first batch
while (page != null && page.hasContent()) {
page = searchTemplate.scroll(scrollId, 5000L, ExampleItem.class);
if (page != null && page.hasContent()) {
// process remaining batches
}
}
}
Вот, ExampleItem
указывает объект, который должен быть выбран.