Search code examples
spring-bootspring-data-jpacouchbasespring-data-couchbasecouchbase-java-api

Spring Data for Couchbase - Counting element in the DB


I am new using Spring Data for Couchbase, I defined this object

public class Building {

    @NotNull
    @Id
    private String id;

    @NotNull
    @Field
    private String name;

    @NotNull
    @Field
    private String companyId;
}

I want to count all the elements in the DB by Id, so I created this function:

@Repository
@N1qlPrimaryIndexed
@ViewIndexed(designDoc = "building")
public interface BuildingRepository extends CouchbaseRepository<Building, String> {

    @Query("SELECT COUNT(*) AS count FROM #{#n1ql.bucket} WHERE #{#n1ql.filter} and id = $1")
    Long countBuildings(String id);

}

but I am getting 0, just after the save an object

I also tried

@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} and id = $1")
Long countBuildings(String id);

but I got this Exception

org.springframework.data.couchbase.core.CouchbaseQueryExecutionException: Query returning a primitive type are expected to return exactly 1 result, got 0

Solution

  • Couchbase N1QL indexes are updated asynchronously by default, so if you query immediately after inserting an item, the index may not reflect that added item yet.

    Couchbase provides two optional levels of 'scan consistency', which wait for the index to reach a particular consistency point before returning the query results. These are:

    • at_plus: which lets you provide one or more specific mutations that you require to be in the index. This is very useful for 'Read Your Own Writes' scenarios.
    • request_plus: where the query will pause until all outstanding mutations at the time of the query are in the index.

    (There's more details on this here: https://docs.couchbase.com/server/5.5/indexes/performance-consistency.html)

    As for how to apply this in the world of Spring, you can specify the scan consistency like this:

    @WithConsistency(ScanConsistency.REQUEST_PLUS)
    @Query("SELECT COUNT(*) AS count FROM #{#n1ql.bucket} WHERE #{#n1ql.filter} and id = $1")
    Long countBuildings(String id);
    

    Please see https://docs.spring.io/spring-data/couchbase/docs/current/reference/html/#couchbase.repository.consistency for further details.