检查文档是不是存在并根据 CosmosDB 中的结果插入的最佳方法是啥?

Posted

技术标签:

【中文标题】检查文档是不是存在并根据 CosmosDB 中的结果插入的最佳方法是啥?【英文标题】:What is the optimal way to check if document exists and insert based on outcome in CosmosDB?检查文档是否存在并根据 CosmosDB 中的结果插入的最佳方法是什么? 【发布时间】:2021-12-30 17:19:44 【问题描述】:

我们使用 CosmosDB 中的跟踪表来识别 CosmosDB 中订单的状态。 TrackingID、OrderID、状态

当没有状态为 Completed/InProgress 的 Order 记录时,我们需要在跟踪表中创建一个新文档。

目前,我们在下面的代码中两次访问 Cosmos DB。是否可以在 CosmosDB 中创建存储过程并在插入新记录时返回跟踪 id 或在 Order 为 Completed/InProgress 状态时返回 null?

public static void InsertTracking(string OrderID)

    if(! IsOrderProcessedOrInProgress(OrderID))
    
        var trackingID = CreateTracking(OrderID);
        NotifyNewTracking(trackingID);
    

【问题讨论】:

简短的回答是肯定的;刚刚阅读了 Cosmos 存储过程。您的要求听起来很简单,您可以用它们做什么。 我应该补充一点,您需要在每次执行 SP 时保持在相同的分区键中;是否可以在您的场景中执行此操作取决于您的容器的配置方式。 感谢@sellotape 的建议。我会理解 Cosmos DB 中的存储过程概念并实现它。 请参考stored procedures and triggers in Azure Cosmos和Transactions within stored procedures 【参考方案1】:

是的,这是可能的。您可以在 CosmosDB 中创建一个存储过程,并通过使用条件语句应用检查来返回跟踪 ID 或 NULL。

在涉及 Cosmos DB 上下文时,存储过程是用 JavaScript 编写的。它们是在集合级别编写和存储的,它们提供了一个安全的事务环境来执行复杂的操作序列。

您可以编写存储过程,如下面的示例 sn-p 所示。

function checkIfNotExists(orderID) 
    var collection = getContext().getCollection();
    var response = getcontext().getResponse();
    
    // Query documents
    var query = 'SELECT * FROM o WHERE o.orderID="' + orderID + '"';
    var isStatus = collection.queryDocuments(...) 
            ...
            //run you condition to check and
            // update the response respectively.
    

之后,您必须通过在 中添加对 Microsoft.Azure.Documents.ClientMicrosoft.Azure.Documents 的引用来初始化文档客户端实例程序.cs。然后就可以按照下图的方法执行存储过程了。

//Read Stored Procedure
var sprocBody = File.ReadAllText(@"..\..\StoredProcedures\checkIfNotExists.js");
//Create SP definition
var spDefinition = new StoredProcedure

    Id = "checkIfNotExists",
    Body = sprocBody
;

//Create a Store Procedure
StoredProcedure sproc = await client.CreateStoredProcedureAsync(UriFactory.CreateDocumenCollectionUri("dbFamily", "Families"), spDefinition);
Console.WriteLine($"\r\nCreated Store procedure Id:sproc.Id ");

//Execute Store Procedure
 var result = await client.ExecuteStoredProcedureAsync<string>  (UriFactory.CreateStoredProcedureUri("dbFamily", "Families", "spHelloWorld"));
 Console.WriteLine($"Executed Store Procedure: response:result.Response");

另请注意,正如@sellotape 所说,您需要在每次执行 SP 时保持在相同的分区键中。在完成上述所有步骤之后,您应该能够达到您想要的结果。我建议阅读Stored Procedures In Azure Cosmos DB 和Stored Procedures 了解更多信息。

【讨论】:

以上是关于检查文档是不是存在并根据 CosmosDB 中的结果插入的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据 ComosDb 中的聚合函数结果对查询结果进行排序?

Azure CosmosDB。存储过程中的继续令牌长度

CosmosDB Mongo 数据库请求保存问题

.htaccess - 根据 URL slug 检查是不是存在多个文件并相应地重写?

Flutter & Firebase:如何检查某个项目是不是存在于 Firebase 文档中的数组中

检查elasticsearch中是不是存在文档