0

Ich möchte alle Daten von elasticsearch mit Filtern ohne seitenwechsel bekommen. Welcher Weg ist der beste, um es zu bekommen? Ich habe das Default-Limit auf 2000 gesetzt. Ich lese, ich sollte scannen, aber ich weiß nicht, wie ich es benutzen soll. Wie soll ich scannen und scrollen um alle Daten zu bekommen?Elasticsearch bekomme alle Daten mit Filtern

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

edit:

I`v bekam:

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


      } 

     } 

aber auf 166 gehen ITERATE und what`s falsch stoppen?

+0

Irgendeine Idee was ist falsch damit? – rad11

Antwort

1

Scroll API ist der beste Weg, um alle Dokumente auf die effizienteste Weise zu durchlaufen. Mit der scroll_id können Sie eine Sitzung finden, die für Ihre spezifische Scroll-Anfrage auf dem Server gespeichert ist.

Hier ist ein Beispiel, wie Sie elasticsearch java scroll api in Ihrem Code verwenden können, um alle Ergebnisse abzurufen, die Ihrer Suchanfrage entsprechen.

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

Beispielfeder-data-Elasticsearch

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

Hier ExampleItem gibt die Einheit verwendet, die abgerufen werden soll.

+0

Ok, aber wie benutze ich es mit NativeSearchQueryBuilder? Es ist möglich? – rad11

+0

while (page! = Null && page.hasNext()) aber die Seite ist noch nicht definiert, daher weiß ich nicht, was es sein soll und in meinem Projekt = searchQuery.build()? ExampleItem = Auktionsindex? – rad11

+0

Sie mussten es nur vor der while-Schleife deklarieren. aktualisiert. – Rahul