如何使用 JavaScript 查询 API 在 Azure Cosmos DB 中编写存储过程和触发器How to write stored procedures and triggers in Azure Cosmos DB by using the JavaScript query API

Azure Cosmos DB 允许使用流畅的 JavaScript 接口执行优化的查询,不需要了解可以用来编写存储过程或触发器的 SQL 语言。Azure Cosmos DB allows you to perform optimized queries by using a fluent JavaScript interface without any knowledge of SQL language that can be used to write stored procedures or triggers. 若要详细了解 Azure Cosmos DB 对 JavaScript 查询 API 的支持,请参阅在 Azure Cosmos DB 中使用 JavaScript 语言集成的查询 API 一文。To learn more about JavaScript Query API support in Azure Cosmos DB, see Working with JavaScript language integrated query API in Azure Cosmos DB article.

使用 JavaScript 查询 API 的存储过程Stored procedure using the JavaScript query API

下面的代码示例是一个有关在存储过程的上下文中使用 JavaScript 查询 API 的示例。The following code sample is an example of how the JavaScript query API is used in the context of a stored procedure. 此存储过程插入由输入参数指定的 Azure Cosmos 项,并使用 __.filter() 方法更新元数据文档,其中 minSize、maxSize 和 totalSize 基于输入项的 size 属性。The stored procedure inserts an Azure Cosmos item that is specified by an input parameter, and updates a metadata document by using the __.filter() method, with minSize, maxSize, and totalSize based upon the input item's size property.

备注

使用 JavaScript 查询 API 时,__(双下划线)是 getContext().getCollection() 的别名。__ (double-underscore) is an alias to getContext().getCollection() when using the JavaScript query API.

/**
 * Insert an item and update metadata doc: minSize, maxSize, totalSize based on item.size.
 */
function insertDocumentAndUpdateMetadata(item) {
  // HTTP error codes sent to our callback function by CosmosDB server.
  var ErrorCode = {
    RETRY_WITH: 449,
  }

  var isAccepted = __.createDocument(__.getSelfLink(), item, {}, function(err, item, options) {
    if (err) throw err;

    // Check the item (ignore items with invalid/zero size and metadata itself) and call updateMetadata.
    if (!item.isMetadata && item.size > 0) {
      // Get the metadata. We keep it in the same container. it's the only item that has .isMetadata = true.
      var result = __.filter(function(x) {
        return x.isMetadata === true
      }, function(err, feed, options) {
        if (err) throw err;

        // We assume that metadata item was pre-created and must exist when this script is called.
        if (!feed || !feed.length) throw new Error("Failed to find the metadata item.");

        // The metadata item.
        var metaItem = feed[0];

        // Update metaDoc.minSize:
        // for 1st document use doc.Size, for all the rest see if it's less than last min.
        if (metaItem.minSize == 0) metaItem.minSize = item.size;
        else metaItem.minSize = Math.min(metaItem.minSize, item.size);

        // Update metaItem.maxSize.
        metaItem.maxSize = Math.max(metaItem.maxSize, item.size);

        // Update metaItem.totalSize.
        metaItem.totalSize += item.size;

        // Update/replace the metadata item in the store.
        var isAccepted = __.replaceDocument(metaItem._self, metaItem, 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("replaceDocument(metaItem) returned false.");
      });
      if (!result.isAccepted) throw new Error("filter for metaItem returned false.");
    }
  });
  if (!isAccepted) throw new Error("createDocument(actual item) returned false.");
}

后续步骤Next steps

参阅以下文章来了解 Azure Cosmos DB 中的存储过程、触发器和用户定义的函数:See the following articles to learn about stored procedures, triggers, and user-defined functions in Azure Cosmos DB: