如何使用 JavaScript 查詢 API 在 Azure Cosmos DB 中撰寫預存程序和觸發程序

適用于: NoSQL

Azure Cosmos DB 可讓您使用流暢的 JavaScript 介面來執行最佳化查詢,而無須具備任何可用來撰寫預存程序或觸發程序的 SQL 語言知識。 若要深入了解 Azure Cosmos DB 中的 JavaScript 查詢 API 支援,請參閱在 Azure Cosmos DB 中使用 JavaScript 語言整合式查詢 API 一文。

使用 JavaScript 查詢 API 撰寫預存程序

下列程式碼範例說明如何在預存程序的內容中使用 JavaScript 查詢 API。 預存程序會插入輸入參數所指定的 Azure Cosmos DB 項目,然後使用 __.filter() 方法,根據輸入項目的大小屬性,以 minSize、maxSize 和 totalSize 來更新中繼資料文件。

注意

使用 JavaScript 查詢 API 時,__ (雙底線) 是 getContext().getCollection() 的別名。

/**
 * 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.");
}

下一步

參閱下列文章以了解 Azure Cosmos DB 中的預存程序、觸發程序和使用者定義函式: