簡體   English   中英

聚合 Spring 數據 Couchbase 存儲庫方法 - 如何查詢給定屬性的所有唯一值的列表?

[英]Aggregate Spring Data Couchbase repository methods - how do I query for a list of all unique values for a given property?

我無法弄清楚如何在 Spring-Data-Couchbase 的存儲庫中運行一個非常簡單的聚合查詢。 我正在使用org.springframework.data.spring-data-couchbase:3.2.0.RELEASE

假設我有一個名為 Organism 的存儲桶,其屬性如下:

SpeciesId  SpeciesName  SpeciesDesc     OrderId  OrderDesc  ClassId  ClassDesc
1          Human        H sapiens       21       Primates   31       Mammalia
2          Chimpanzee   P troglodytes   21       Primates   31       Mammalia
3          Fruit fly    D melanogaster  22       Diptera    32       Insecta

我想編寫一個查詢,允許我搜索唯一的訂單或類; 在 SQL 中,查詢如下所示:

SELECT OrderId, OrderDesc FROM Organism WHERE OrderDesc like 'Pri%' GROUP BY OrderId, OrderDesc
SELECT ClassId, ClassDesc FROM Organism WHERE ClassDesc like 'Mam%' GROUP BY ClassId, ClassDesc

我將如何在 spring-data-couchbase 存儲庫中創建這些查詢?


到目前為止,我已經嘗試了大約一千種不同的方法,但都沒有奏效。 首先,我嘗試向存儲庫添加不同的查詢:

public interface Order {
    public Integer getOrderId();
    public String getOrderDesc();
}

@N1qlPrimaryIndexed
@ViewIndexed(designDoc = "organism")
public interface OrganismRepository extends 
CouchbasePagingAndSortingRepository<Organism, String> {
    Optional<List<Order>> findDistinctByOrderDescStartingWith(String orderDesc);
}

接下來我嘗試使用@Query 注釋:

//Exception - Unable to retrieve enough metadata for N1QL to entity mapping, have you selected _ID and _CAS?
@Query("SELECT orderDesc FROM #{#n1ql.bucket} WHERE orderDesc like 'Pri%' AND #{#n1ql.filter}")
Optional<List<String>> cantSelectPropertyBecauseMissingMetadata();

//Exception - Unable to execute query due to the following n1ql errors:
//   {"msg":"Expression must be a group key or aggregate: (meta(`organism`).`id`)","code":4210}
@Query("#{#n1ql.selectEntity} where #{#n1ql.filter} AND orderDesc like 'pro%' group by orderId, orderDesc")
Optional<List<Order>> selectionsMustBeIncludedInGroupByClause();

//Exception - Unable to retrieve enough metadata for N1QL to entity mapping, have you selected _ID and _CAS?
@Query("SELECT orderId, orderDesc FROM #{#n1ql.bucket} where #{#n1ql.filter} AND orderDesc like 'Pri%' group by orderId, orderDesc")
Optional<List<Order>> cantGroupByJustTwoPropsBecauseMissingMetadata();

//Exception - Unable to retrieve enough metadata for N1QL to entity mapping, have you selected _ID and _CAS?
@Query("SELECT distinct orderDesc FROM #{#n1ql.bucket} WHERE orderDesc like 'pro%' AND #{#n1ql.filter}")
Optional<List<String>> cantSelectDistinctBecauseMissingMetadata();

//Exception - Unable to execute query due to the following n1ql errors:
//  {"msg":"Expression must be a group key or aggregate: (meta(`organism`).`id`)","code":4210}
@Query("SELECT orderId, orderDesc, META(#{#n1ql.bucket}).id as _ID, META(#{#n1ql.bucket}).cas as _CAS FROM #{#n1ql.bucket} where #{#n1ql.filter} AND orderDesc like 'Pri%' group by orderId, orderDesc")
Optional<List<Order>> cantGroupByJustTwoPropsBecauseStillMissingMetadata();

//Exception - Unable to execute query due to the following n1ql errors:
//  {"msg":"Expression must be a group key or aggregate: (meta(`organism`).`id`)","code":4210}
@Query("SELECT orderId, orderDesc, META(#{#n1ql.bucket}).id as _ID, META(#{#n1ql.bucket}).cas as _CAS FROM #{#n1ql.bucket} where #{#n1ql.filter} AND orderDesc like 'Pri%' group by orderId, orderDesc, _ID, _CAS")
Optional<List<Order>> cantGroupByMETA();

@Query("SELECT distinct orderDesc, META(#{#n1ql.bucket}).id as _ID, META(#{#n1ql.bucket}).cas as _CAS FROM #{#n1ql.bucket} WHERE orderDesc like 'Pri%' AND #{#n1ql.filter}")
Optional<List<Order>> resultsAreNotDistinct();

@Query("SELECT distinct orderId, orderDesc, META(#{#n1ql.bucket}).id as _ID, META(#{#n1ql.bucket}).cas as _CAS FROM #{#n1ql.bucket} WHERE orderDesc like 'Pri%' AND #{#n1ql.filter}")
Optional<List<Order>> resultsAreNotDistinct2();

@Query("SELECT orderId, orderDesc, META(#{#n1ql.bucket}).id as _ID, META(#{#n1ql.bucket}).cas as _CAS FROM #{#n1ql.bucket} where #{#n1ql.filter} AND orderDesc like 'Pri%' group by orderId, orderDesc, META(#{#n1ql.bucket}).id, META(#{#n1ql.bucket}).cas")
Optional<List<Order>> resultsAreNotDistinct3();

到目前為止,我們能夠使用此功能的唯一方法是使用com.couchbase.client.java.Bucket中的com.couchbase.client.java-client:2.7.9 但是如果在 Spring-Data-Couchbase 中沒有辦法做到這一點,我會感到震驚......

String queryString = "SELECT distinct orderId, orderDesc " + 
    "FROM `organisms` " + 
    "WHERE orderDesc LIKE $search"
Cluster cluster = CouchbaseCluster.create(hosts).authenticate(bucketUser, bucketPassword);
Bucket bucket = cluster.openBucket(bucketName);
JsonObject parameters = JsonObject.create().put("search", search);
ParameterizedN1qlQuery q = N1qlQuery.parameterized(queryString, parameters);
N1qlQueryResult result = bucket.query(q);

Couchbase Spring Data 的當前實現將始終嘗試獲取 CAS 和文檔 ID(因為元數據對於某些用例很重要),這就是您收到此錯誤的原因。

如果您只需要返回所需的屬性,我建議使用類似於以下的語法:

@Override
public List<KeyValueVO> listKeyValue(String companyId) {
    String bucketName = securityGroupRepository.getCouchbaseOperations().getCouchbaseBucket().name();
    String queryString = "SELECT meta().id as id, name FROM "+bucketName+
            " WHERE  _class = '"+SecurityGroup.class.getName() +"' and removed = false and companyId = '"+companyId+"' order by name ";
    N1qlParams params = N1qlParams.build().consistency(ScanConsistency.NOT_BOUNDED).adhoc(true);
    ParameterizedN1qlQuery query = N1qlQuery.parameterized(queryString, JsonObject.create(), params);
    return securityGroupRepository.getCouchbaseOperations().findByN1QLProjection(query, KeyValueVO.class);

}

PS:是的,我應該正確使用 ParameterizedN1qlQuery 而不是 concat 字符串中的參數,但你明白了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM