0

Je suis nouveau à ElasticsearchTemplate. Je veux obtenir 1000 documents d'Elasticsearch en fonction de ma requête. J'ai utilisé QueryBuilder pour créer ma requête, et cela fonctionne parfaitement. J'ai parcouru les liens suivants, qui indiquent qu'il est possible de réaliser de gros ensembles de données en utilisant scan et scroll.

link one
link twoElasticsearchTemplate récupère de gros ensembles de données

Je suis en train de mettre en œuvre cette fonctionnalité dans la section suivante du code, que j'ai une copie collée de l'un des liens, mentionné ci-dessus. Mais je reçois l'erreur suivante:

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

MyInputDto est une classe avec l'annotation @Document dans mon projet. Fin de la journée, je veux juste récupérer 1000 documents d'Elasticsearch. J'ai essayé de trouver le paramètre size mais je pense que ce n'est pas supporté.

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

Quel est le problème ici? Existe-t-il d'autres alternatives pour y parvenir? Je serais reconnaissant si quelqu'un pouvait me dire comment cela (code) fonctionne dans le backend.

Répondre

0

Solution 1

Si vous souhaitez utiliser ElasticsearchTemplate, il serait beaucoup plus simple et lisible à utiliser CriteriaQuery, car il permet de définir la taille de la page avec la méthode setPageable. Avec le défilement, vous pouvez obtenir prochaines séries de données:

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

Solution 2

Si vous souhaitez utiliser org.elasticsearch.client.Client au lieu de ElasticsearchTemplate, puis SearchResponse permet de définir le nombre de retourner de résultats :

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