gpt4 book ai didi

c# - 调试 DocumentDB 触发器

转载 作者:行者123 更新时间:2023-12-02 06:49:23 25 4
gpt4 key购买 nike

为了测试 DocumentDB 中触发器的使用,我:

  • 已上传示例 metadata后触发
  • 使用属性 "isMetadata": true 创建了元数据文档
  • 使用 C# 执行了一些文档写入,包括带有 PostTriggerInclude = new List<string> { "updateMetadata" } 的 RequestOption

不幸的是,当我的代码插入文档时,元数据文件以 0 的形式存放在那里,完全没有受到触发器的影响。我验证了触发器中的选择 SQL,以确保它应该能够找到元数据文档来编辑它。似乎没有可以用来进一步调查的日志。

如何调试 DocumentDB 触发器?

(由于问题可能是 PICNIC,我的设置是否有明显问题?)

updateMetaData script

元数据文档:

  {
"id": "metadata",
"isMetadata": true,
"minSize": 0,
"maxSize": 0,
"totalSize": 0,
}

代码片段:

var docResp =   await client.CreateDocumentAsync(collectionUri, webhit,
new RequestOptions
{
  PostTriggerInclude = new List<string> { "updateMetadata" }
}
);

最佳答案

在存储过程或触发器中,脚本抛出的所有错误都将被传回并转换为客户端异常,并带有堆栈跟踪。因此,调试脚本的一种方法是使用 throw new Error(...) 作为脚本中的断点,单步执行脚本并在不同点抛出以验证代码的行为是否符合预期。

假设您正在使用分区集合。触发器与存储过程一样,作用域位于单个分区 ( https://azure.microsoft.com/en-us/documentation/articles/documentdb-programming/#database-program-transactions ) 中。因此,触发器可以访问和更新的内容必须位于触发器运行的分区内。

在您的示例中,如果不更改触发脚本,您将需要为每个分区键值预先创建一个元数据文档。然后,为了获得集合的最终统计信息,您需要查询所有元数据文档(将有多个)并在客户端对这些元数据文档进行最终聚合。

另一个选项是在触发器内自动创建元数据文档。这将避免创建超过必要的元数据文档,因为每个分区只需要一个元数据文档。这是我对您进行创建的原始脚本的修改:

   /**

* This script runs as a trigger:

* for each inserted document, look at document.size and update aggregate properties of metadata document: minSize, maxSize, totalSize.

*/

function updateMetadata() {

// HTTP error codes sent to our callback funciton by DocDB server.

var ErrorCode = {

RETRY_WITH: 449,

}



var collection = getContext().getCollection();

var collectionLink = collection.getSelfLink();



// Get the document from request (the script runs as trigger, thus the input comes in request).

var doc = getContext().getRequest().getBody();



// Check the doc (ignore docs with invalid/zero size and metaDoc itself) and call updateMetadata.

if (!doc.isMetadata && doc.size != undefined && doc.size > 0) {

getAndUpdateMetadata();

}



function getAndUpdateMetadata() {

// Get the meta document. We keep it in the same collection. it's the only doc that has .isMetadata = true.

var isAccepted = collection.queryDocuments(collectionLink, 'SELECT * FROM TestColl r WHERE r.isMetadata = true', function (err, feed, options) {

if (err) throw err;

var metaDoc;
if (!feed || !feed.length) {
// Create the meta doc for this partition, using the partition key value from the request document
metaDoc = {
"id": "metadata",
"isMetadata": true,
"minSize": 0,
"maxSize": 0,
"totalSize": 0,
}
metaDoc.partitionKey = doc.partitionKey;
}
else {
// Found the metadata document for this partition. So just use it
metaDoc = feed[0];
}


// Update metaDoc.minSize:

// for 1st document use doc.Size, for all the rest see if it's less than last min.

if (metaDoc.minSize == 0) metaDoc.minSize = doc.size;

else metaDoc.minSize = Math.min(metaDoc.minSize, doc.size);



// Update metaDoc.maxSize.

metaDoc.maxSize = Math.max(metaDoc.maxSize, doc.size);



// Update metaDoc.totalSize.

metaDoc.totalSize += doc.size;



// Update/replace the metadata document in the store.
var isAccepted;
if (!feed || !feed.length) {
// Create the metadata document if it doesn't exist
isAccepted = collection.createDocument(collectionLink, metaDoc, function (err) {

if (err) throw err;

// Note: in case concurrent updates causes conflict with ErrorCode.RETRY_WITH, we can't read the meta again

// and update again because due to Snapshot isolation we will read same exact version (we are in same transaction).

// We have to take care of that on the client side.

});
}
else {
// Replace the metadata document
isAccepted = collection.replaceDocument(metaDoc._self, metaDoc, function (err) {

if (err) throw err;

// Note: in case concurrent updates causes conflict with ErrorCode.RETRY_WITH, we can't read the meta again

// and update again because due to Snapshot isolation we will read same exact version (we are in same transaction).

// We have to take care of that on the client side.

});
}

if (!isAccepted) throw new Error("The call replaceDocument(metaDoc) returned false.");
});

if (!isAccepted) throw new Error("The call queryDocuments for metaDoc returned false.");

}

}

希望这有帮助。如果您还有其他问题,请随时回复。

谢谢。

冷宁

关于c# - 调试 DocumentDB 触发器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38996473/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com