ExecuteStoredProcedureAsync跨分区键运行它

时间:2016-10-20 17:26:48

标签: azure-cosmosdb

我需要一个存储过程,我需要在不同的分区键上运行。我的集合在一个关键实体名称上进行了分区,我想在分区中的每个实体上执行存储过程。

sproc = await client.CreateStoredProcedureAsync(collectionLink, sproc,
    new RequestOptions { PartitionKey = new PartitionKey(partitionkey) });

StoredProcedureResponse<int> scriptResult = await client.ExecuteStoredProcedureAsync<int>(
    sproc.SelfLink,
    new RequestOptions { PartitionKey = new PartitionKey(partitionkey) },
    args);

我得到以下异常:

  

源自脚本的请求不能引用除提交客户端请求的分区密钥之外的分区密钥

  1. 是否有必要根据密钥在每个分区中创建存储过程?
  2. 是否可以有一个可以执行所有键的存储过程?

2 个答案:

答案 0 :(得分:1)

当从客户端执行存储过程时,RequestOptions指定分区键,存储过程将在此分区的上下文中运行,并且无法在具有不同分区键值的文档上运行(例如,创建)。

您可以做的是从客户端为每个分区键执行sproc。例如,如果要批量创建文档,则可以按分区键对文档进行分组,并将每个组(可以并行完成)发送到提供RequestOptions中的分区键值的sproc。这会有帮助吗?

您不必为每个分区键创建sproc,只需创建一次而不提供分区键。

答案 1 :(得分:0)

我在Java中开发了上述内容。

使用Java SDK和存储过程时我们的实现方式有所不同。

请注意使用'string'并需要根据分区键分隔记录。

使用批量导入存储过程:https://docs.microsoft.com/en-us/azure/documentdb/documentdb-programming

以下是调用商店程序的客户

public void CallStoredProcedure(Map <String, List<String>> finalMap)
{
    for ( String key : finalMap.keySet() ) {
        try
        {
            ExecuteStoredProcedure(finalMap.get(key),key);
        }
        catch(Exception ex)
        {
            LOG.info(ex.getMessage());
        }
    }       
}
public void ExecuteStoredProcedure(List<String> documents, String partitionKey)
{

    try {

        if (documentClient == null) {
            documentClient = new DocumentClient(documentDBHostUrl, documentDBAccessKey, null, ConsistencyLevel.Session);
        }

        options = new RequestOptions();
        options.setPartitionKey(new PartitionKey(partitionKey));

        Object[] sprocsParams = new Object[2] ;
        sprocsParams[0] = documents;
        sprocsParams[1] = null;

        StoredProcedureResponse rs = documentClient.executeStoredProcedure(selflink, options, sprocsParams);

    } catch (Exception ex) {

    }
}