Search code examples
javaelasticsearchspring-data-elasticsearch

Is there any way that I could use 'countBy' prefix with my custom query in spring-data-elasticsearch?


I'm now using spring-boot and spring-data-elasticsearch for my java project.

I have to count the number of users who reports some data per day, so I created a custom query for it,

public interface UserInfoRepository extends ElasticsearchRepository<UserInfo, String> {
    @Query("{\"bool\": {\"must\": [{\"match\": {\"username\": \"?0\"}},{\"range\": {\"createdTime\": {\"gt\": \"now-1d/d\",\"lt\": \"now+1d/d\"}}}]}}")
    List<UserInfo> findByUserNameWithinDayRange(String username);
}

and get the number of the user by below code.

private long numberOfUser (String username) {
    List<UserInfo> userInfoWithinADay = suggestionRepository.findByUserNameWithinDayRange(ip);

    return userInfoWithinADay.size();
}

However, I thought this way is quite inefficient; I don't need the whole list of the UserInfo, just the "hit" info of them.

Could I know is there any way that I could use countBy prefix with my custom query, or send Count API by using spring-data-elasticsearch? Or are there any way that I could achieve a query that could find a list of data within a day range without defining a custom query?

Thanks!


Solution

    1. You can use @CountQuery instead of @Query (or add the parameter count = true to the @Query annotation) - and change the return value of the repository method to long.
    2. This should work with query derivation and a method name like long countByUsernameAndCreatedTimeBetween(String username, Instant from, Instant two) - I have not tested this. And you would need to calculate the date parameters

    I would create a custom repository fragment with a method long userWithinADay(String user) and in the implementation I would create a CriteriaQuery for the name and the dates and pass that to one of the ElasticsearchOperations.count() methods.

    Edit:

    @CountQuery was added in Spring Data Elasticsearch 4.2.