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 中,这样您就不需要每次都检查它们是否存在