C# 调试DocumentDB触发器
要测试DocumentDB中触发器的使用,请执行以下操作:C# 调试DocumentDB触发器,c#,azure,azure-cosmosdb,C#,Azure,Azure Cosmosdb,要测试DocumentDB中触发器的使用,请执行以下操作: 上传了示例post触发器 创建了一个元数据文档,其属性为“isMetadata”:true 使用C#执行一些文档写入,包括带有PostTriggerInclude=new List{“updateMetadata”} 不幸的是,当我的代码插入文档时,元数据文件就放在那里,0完全不受触发器的影响。我验证了触发器中的选择SQL,以确保它能够找到元数据文档来编辑它。似乎没有日志可供我进一步调查 如何调试DocumentDB触发器? (由于
- 上传了示例post触发器
- 创建了一个元数据文档,其属性为
“isMetadata”:true
- 使用C#执行一些文档写入,包括带有
PostTriggerInclude=new List{“updateMetadata”}
{
"id": "metadata",
"isMetadata": true,
"minSize": 0,
"maxSize": 0,
"totalSize": 0,
}
代码段:
var docResp = await client.CreateDocumentAsync(collectionUri, webhit,
new RequestOptions
{
PostTriggerInclude = new List<string> { "updateMetadata" }
}
);
var docResp=await client.createDocumentSync(collectionUri、webhit、,
新的请求选项
{
PostTriggerInclude=新列表{“updateMetadata”}
}
);
在存储过程或触发器中,脚本抛出的所有错误都将被传输回客户端异常,并带有堆栈跟踪。因此,调试脚本的一种方法是使用throw new Error(…)作为脚本中的断点,单步执行脚本并在不同点进行抛出,以验证代码是否按预期运行
假设您使用的是分区集合。与存储过程一样,触发器的作用域是单个分区()。因此,触发器可以访问和更新的内容必须在运行触发器的分区内
在您的示例中,在不更改触发器脚本的情况下,您需要为每个分区键值预先创建一个元数据文档。然后,要获得集合的最终统计信息,您需要查询所有元数据文档(将有多个),并在客户端对这些元数据文档进行最终聚合
另一个选项是在触发器内自动创建元数据文档。这将避免创建多于必要的元数据文档,因为每个分区只需要一个元数据文档。以下是我对您的原始脚本的修改,用于创建:
/**
* 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.");
}
}
希望这有帮助。如果您还有其他问题,请随时发回
谢谢
Lenning我使用了这个修订版,使用Azure DocumentDB Studio我可以添加一个文档,并将UpdateMatadata作为PostTrigger。它添加文档并返回罚款,但有趣的是,如果我尝试“读取”任何内容,我会得到
Microsoft.Azure.Documents.DocumentClientException:Message:{“Errors”:[“指定的输入之一无效”]}ActivityId:706529a1-82b9-4ed1-a395-6090ddf91b50,请求URI:/apps/36834417-c2b8-4524-871e-e3247817af32/services/78da0810-31a5-45d3-bb94-8ef7a68e12cd/partitions/91e5e314-dc36-419e-84d8-fba2825499c9/replications/131157324155592025s
你好,斯蒂芬,你是如何“阅读”这个收藏的?从门户或我的C#代码中读取数据和元数据文档都没有问题。您执行的特定操作产生了一个错误,我们说触发器的操作类型无效。似乎您在尝试调用触发器时,您的操作不是创建、删除或替换。你能让我知道更多关于“读取”操作的信息吗?谢谢