创建触发器和用户定义的函数
Azure Cosmos DB 支持前触发器和后触发器。 前触发器是在修改数据库项之前执行的,后触发器是在修改数据库项之后执行的。 触发器不会自动执行。 必须为要执行触发器的每个数据库操作指定它们。 定义触发器后,应使用 Azure Cosmos DB SDK 来注册它。
前触发器
以下示例演示如何使用前触发器来验证正在创建的 Azure Cosmos 项的属性。 如果新添加的项未包含时间戳属性,则会向其中添加该属性。
function validateToDoItemTimestamp() {
var context = getContext();
var request = context.getRequest();
// item to be created in the current operation
var itemToCreate = request.getBody();
// validate properties
if (!("timestamp" in itemToCreate)) {
var ts = new Date();
itemToCreate["timestamp"] = ts.getTime();
}
// update the item that will be created
request.setBody(itemToCreate);
}
前触发器不能有任何输入参数。 使用触发器中的请求对象来处理与操作关联的请求消息。 在前面的示例中,创建 Azure Cosmos 项时将运行前触发器,请求消息正文包含要以 JSON 格式创建的项。
注册触发器后,可以指定可对哪些操作运行该触发器。 应使用 TriggerOperation
的 TriggerOperation.Create
值创建此触发器,不允许在 replace 操作中使用此触发器。
有关如何注册和调用前触发器的示例,请访问前触发器文章。
后触发器
以下示例演示了一个后触发器。 此触发器查询元数据项,并在其中更新有关新建项的详细信息。
function updateMetadata() {
var context = getContext();
var container = context.getCollection();
var response = context.getResponse();
// item that was created
var createdItem = response.getBody();
// query for metadata document
var filterQuery = 'SELECT * FROM root r WHERE r.id = "_metadata"';
var accept = container.queryDocuments(container.getSelfLink(), filterQuery,
updateMetadataCallback);
if(!accept) throw "Unable to update metadata, abort";
function updateMetadataCallback(err, items, responseOptions) {
if(err) throw new Error("Error" + err.message);
if(items.length != 1) throw 'Unable to find metadata document';
var metadataItem = items[0];
// update metadata
metadataItem.createdItems += 1;
metadataItem.createdNames += " " + createdItem.id;
var accept = container.replaceDocument(metadataItem._self,
metadataItem, function(err, itemReplaced) {
if(err) throw "Unable to update metadata, abort";
});
if(!accept) throw "Unable to update metadata, abort";
return;
}
}
必须注意的一个要点是 Azure Cosmos DB 中触发器的事务执行。 后触发器作为基础项本身的同一事务的一部分运行。 后触发器执行期间的异常会导致整个事务失败。 提交的任何内容都会回退并返回异常。
用户定义的函数
以下示例创建一个 UDF 用于计算各个收入阶层的所得税。 然后,在查询中使用此用户定义的函数。 此示例假设有一个名为“Incomes”的容器,其中包含以下属性:
{
"name": "User One",
"country": "USA",
"income": 70000
}
以下示例代码是用于计算各个收入阶层的所得税的函数定义:
function tax(income) {
if(income == undefined)
throw 'no input';
if (income < 1000)
return income * 0.1;
else if (income < 10000)
return income * 0.2;
else
return income * 0.4;
}