Spring Boot Cosmos DB 实现中的动态查询
Dynamic queries in Spring Boot Cosmos DB implementation
我正在为 Spring.
使用 Azure Cosmos DB 开发应用程序
我有一个包含模型 classes 和 ReactiveCosmosRepository 的结构,我用它来进行查询。
我通常在我的存储库中注释我的查询 class:
@Repository
public interface ArchivedDocumentRepository extends ReactiveCosmosRepository<ArchivedDocument, String> {
@Query("SELECT * FROM c)
Flux<ArchivedDocument> findAllArchivedDocuments();
@Query("SELECT * FROM c where c.document_id = @documentId")
Mono<ArchivedDocument> findArchivedDocument(@Param("documentId") String documentId);
}
但是现在我需要使用一些逻辑来创建 SQL,并且不能像这样注释它。
我该怎么做?
我也直接用过Azure Cosmos SDK,你是这样的:
client = new CosmosClientBuilder().endpoint("SOMEURL")
.key("SOMEKEY")
.preferredRegions(Collections.singletonList("SOMELOCATION"))
.consistencyLevel(ConsistencyLevel.EVENTUAL).buildClient();
database = client.getDatabase("DBNAME");
String containerName = "CONTAINERNAME";
CosmosContainer container = database.getContainer(containerName);
String sql = "SELECT * FROM c";
CosmosPagedIterable<DocumentMetadata> filteredDocumentMetadata = container.queryItems(sql, new CosmosQueryRequestOptions(), DocumentMetadata.class);
...
}
如果我在我的服务中将我现有的存储库代码与类似的代码结合起来,我可以检索我喜欢的数据并按照我喜欢的方式构建查询,但这似乎有点不必要,例如当我已经有连接时实例化“客户端”对象?
有什么建议吗?我如何才能将 SDK 直接与 Spring 层结合起来,以便能够创建基于逻辑的查询?
我认为你走在正确的道路上。您可能需要使用 CosmosAsyncClient
在较低级别上工作
如果您使用的配置 extends AbstractCosmosConfiguration
那么您甚至不需要创建 CosmosAsyncClient
因为它在 AbstractCosmosConfiguration class.
中定义
自定义存储库
package com.vob.reactive.webflux.service;
import com.azure.cosmos.CosmosAsyncClient;
import com.azure.cosmos.models.SqlParameter;
import com.azure.cosmos.models.SqlQuerySpec;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
@Component
@Slf4j
public class CustomRepository {
private final CosmosAsyncClient cosmosAsyncClient;
@Autowired
public CustomRepository(CosmosAsyncClient cosmosAsyncClient) {
this.cosmosAsyncClient = cosmosAsyncClient;
}
public <T> Mono<T> getSomethingFrom(String database, String container, String id, Class<T> classType){
return this.cosmosAsyncClient
.getDatabase(database)
.getContainer(container)
.queryItems(new SqlQuerySpec("select * from c where c.document_id = @documentId", new SqlParameter("documentId", id)), classType)
.single();
}
}
您可能需要改进 getDatabase 和 getContainer,将它们存储在 Map 中,这样您就不需要每次都检查它们是否存在
我正在为 Spring.
使用 Azure Cosmos DB 开发应用程序我有一个包含模型 classes 和 ReactiveCosmosRepository 的结构,我用它来进行查询。
我通常在我的存储库中注释我的查询 class:
@Repository
public interface ArchivedDocumentRepository extends ReactiveCosmosRepository<ArchivedDocument, String> {
@Query("SELECT * FROM c)
Flux<ArchivedDocument> findAllArchivedDocuments();
@Query("SELECT * FROM c where c.document_id = @documentId")
Mono<ArchivedDocument> findArchivedDocument(@Param("documentId") String documentId);
}
但是现在我需要使用一些逻辑来创建 SQL,并且不能像这样注释它。 我该怎么做?
我也直接用过Azure Cosmos SDK,你是这样的:
client = new CosmosClientBuilder().endpoint("SOMEURL")
.key("SOMEKEY")
.preferredRegions(Collections.singletonList("SOMELOCATION"))
.consistencyLevel(ConsistencyLevel.EVENTUAL).buildClient();
database = client.getDatabase("DBNAME");
String containerName = "CONTAINERNAME";
CosmosContainer container = database.getContainer(containerName);
String sql = "SELECT * FROM c";
CosmosPagedIterable<DocumentMetadata> filteredDocumentMetadata = container.queryItems(sql, new CosmosQueryRequestOptions(), DocumentMetadata.class);
...
}
如果我在我的服务中将我现有的存储库代码与类似的代码结合起来,我可以检索我喜欢的数据并按照我喜欢的方式构建查询,但这似乎有点不必要,例如当我已经有连接时实例化“客户端”对象?
有什么建议吗?我如何才能将 SDK 直接与 Spring 层结合起来,以便能够创建基于逻辑的查询?
我认为你走在正确的道路上。您可能需要使用 CosmosAsyncClient
如果您使用的配置 extends AbstractCosmosConfiguration
那么您甚至不需要创建 CosmosAsyncClient
因为它在 AbstractCosmosConfiguration class.
自定义存储库
package com.vob.reactive.webflux.service;
import com.azure.cosmos.CosmosAsyncClient;
import com.azure.cosmos.models.SqlParameter;
import com.azure.cosmos.models.SqlQuerySpec;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
@Component
@Slf4j
public class CustomRepository {
private final CosmosAsyncClient cosmosAsyncClient;
@Autowired
public CustomRepository(CosmosAsyncClient cosmosAsyncClient) {
this.cosmosAsyncClient = cosmosAsyncClient;
}
public <T> Mono<T> getSomethingFrom(String database, String container, String id, Class<T> classType){
return this.cosmosAsyncClient
.getDatabase(database)
.getContainer(container)
.queryItems(new SqlQuerySpec("select * from c where c.document_id = @documentId", new SqlParameter("documentId", id)), classType)
.single();
}
}
您可能需要改进 getDatabase 和 getContainer,将它们存储在 Map 中,这样您就不需要每次都检查它们是否存在