1

I would like to get aggregate results from ES like avgSize (avg of a field with name 'size'), totalhits for documents that match a term, and some other aggregates in future, for which I don't think ElasticsearchRepository has any methods to call. I built Query and Aggregate Builders as below. I want to use my Repository interface but I am not sure of what should the return ObjectType be ? Should it be a document type in my DTOs ? Also I have seen examples where the searchQueryis passed directly to ElasticsearchTemplate but then what is the point of having Repository interface that extends ElasticsearchRepository

Repository Interface

public interface CCFilesSummaryRepository extends ElasticsearchRepository<DataReferenceSummary, UUID> {

}

Elastic configuration

@Configuration
@EnableElasticsearchRepositories(basePackages = "com.xxx.repository.es")
public class ElasticConfiguration {
    @Bean
    public ElasticsearchOperations elasticsearchTemplate() throws UnknownHostException {
        return new ElasticsearchTemplate(elasticsearchClient());
    }
    @Bean
    public Client elasticsearchClient() throws UnknownHostException {
        Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build();
        TransportClient client = new PreBuiltTransportClient(settings);
        client.addTransportAddress(new TransportAddress(InetAddress.getLocalHost(), 9200));
        return client;
    }
}

Service Method

  public DataReferenceSummary createSummary(final DataSet dataSet) {
    try {


      QueryBuilder queryBuilder = QueryBuilders.matchQuery("type" , dataSet.getDataSetCreateRequest().getContentType());
      AvgAggregationBuilder avgAggregationBuilder =  AggregationBuilders.avg("avg_size").field("size");
      ValueCountAggregationBuilder valueCountAggregationBuilder = AggregationBuilders.count("total_references")
              .field("asset_id");

      SearchQuery searchQuery = new NativeSearchQueryBuilder()
              .withQuery(queryBuilder)
              .addAggregation(avgAggregationBuilder)
              .addAggregation(valueCountAggregationBuilder)
              .build();


      return ccFilesSummaryRepository.search(searchQuery).iterator().next();


    } catch (Exception e){
      e.printStackTrace();
    }
    return null;

  }

DataReferernceSummary is just a POJO for now and for which I am getting an error during my build that says Unable to build Bean CCFilesSummaryRepository, illegalArgumentException DataReferernceSummary. is not a amanged Object

1 Answer 1

2

First DataReferenceSummary must be a class annotated with @Document.

In Spring Data Elasticsearch 3.2.0 (the current version) you need to define the repository return type as AggregatedPage<DataReferenceSummary>, the returned object will contain the aggregations.

From the upcoming version 4.0 on, you will have to define the return type as SearchHits<DataReferenceSummary> and find the aggregations in this returned object.

Sign up to request clarification or add additional context in comments.

2 Comments

Sure, but why does the return type have to be of @Document type? can't it just be a POJO? annotating it to a @Document type requires the object to have a mandatory id field and the document mapping is created in Elasticsearch cluster during application boot up. Which I don't see any use for.
That's the basic concept of Spring Data (not only for elasticsearch but for the other modus as well). Managing and persisting entities by either using the template or repository methods. The information from the entity is used for mapping the data, building the queries etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.