Javascript 如何在服务器端触发器内同步读取Azure DocumentDb集合中的数据?

Javascript 如何在服务器端触发器内同步读取Azure DocumentDb集合中的数据?,javascript,azure,azure-cosmosdb,Javascript,Azure,Azure Cosmosdb,我试图在Azure DocumentDb集合上实现一个触发器,它应该自动增加正在插入的文档的版本。触发器被创建为预触发器。 我面临的挑战是,collection类似乎没有提供用于查询数据的同步API。我的触发器计划是查询现有文档,获取顶级版本、增量,并将+1值分配给要插入到集合中的文档。但是,由于查询结果只能异步使用,因此到那时,我的触发器已完成,并且文档未经修改就插入了。 我如何等待查询结果? 以下是当前触发器的外观: // TRIGGER Auto increment version

我试图在Azure DocumentDb集合上实现一个触发器,它应该自动增加正在插入的文档的版本。触发器被创建为预触发器。 我面临的挑战是,collection类似乎没有提供用于查询数据的同步API。我的触发器计划是查询现有文档,获取顶级版本、增量,并将+1值分配给要插入到集合中的文档。但是,由于查询结果只能异步使用,因此到那时,我的触发器已完成,并且文档未经修改就插入了。
我如何等待查询结果? 以下是当前触发器的外观:

// TRIGGER Auto increment version
    function autoIncrementVersion() {
      var collection = getContext().getCollection();
      var request = getContext().getRequest();
      var docToCreate = request.getBody();

      // Reject documents that do not have a name property by throwing an exception.
      if (!docToCreate.Version) {
        throw new Error('Document must include a "Version" property.');
      }

      var lastVersion;

      var filter = "SELECT TOP 1 d.Version FROM CovenantsDocuments d ORDER BY d.Version DESC";

      var result = collection.queryDocuments(collection.getSelfLink(), filter, {},
                function (err, documents, responseOptions) {
                    if (err) throw new Error("Error: " + err.message);
                    if (documents.length != 1 || !documents[0]) {
                      lastVersion = 0;
                    } else {
lastVersion  = documents[0];
}
                   //By the time we reach this line, our trigger has already completed?
                    docToCreate.Version = lastVersion + 1;
                });
      if (!result) throw "Unable to read last version of the document";

    }
更新:问题在于我提交请求的方式。看起来默认情况下不会触发触发器,它们的名称需要显式地作为请求的参数提供。 在我的例子中,直到我将客户端代码更改为以下代码时,触发器才触发:

RequestOptions options = new RequestOptions
{
    PreTriggerInclude = new[] { "autoIncrementVersion"}
};
client.CreateDocumentAsync(url, document, options);

它将自动等待,直到所有挂起的异步操作完成、失败或超时后再返回。你所拥有的很接近。我唯一能看到的是,在更改
docToCreate
之后,您从未调用
request.setBody(docToCreate)

也就是说,我不能100%肯定这种方法是安全的。触发器、存储过程或UDF中的所有操作都是原子操作,但我不确定预触发器和写入操作的组合是否是原子操作。风险在于两次同时写入都将运行并完成触发器部分,这将为它们提供相同的.Version。您可能需要让DocumentDB产品经理确认这一点。他们在这里逗留,以便在这里作出反应

如果您发现它不是原子的,那么您可以将所有内容(读取以查找最新版本和写入)移动到存储过程(存储过程)中

你也可以考虑创建一个文件,它的代码> ID >你硬编码到像“LaStIdVoice”这样的东西来保存最后一个使用的版本。这意味着每次写入都会导致读+写两次(一次用于文档,另一次用于更新此文档),但这可能比查询+写一次的方法更有效。您可以在一个存储过程中完成所有这一切,也可以使用预触发器(获取“最后一个版本”+写入操作+后触发器(更新“最后一个版本”文档),具体取决于产品经理对原子性的看法


关于您当前的方法还有一点需要注意……请确保版本字段上索引的精度设置为-1(最大精度)。

Larry,非常感谢,您的回答听起来像是一个解决方案,我将尝试request.setBody()明天,这一定是我的触发器没有更新版本的原因。此外,我将研究原子性方面。并将确保版本字段的精度正确。不过,您的回答中的一个细节我并不清楚-关于抛出if documents.length>1的部分。这是我第一次尝试DocumentDb查询语法,所以我是curios,TOP 1关键字不能保证我不能取回超过1条记录吗?再次感谢!你说得对,不需要使用TOP。我想它会确认没有两个文档具有相同的版本,但它不会这样做。我编辑了它。结果,setBody()打电话对我来说没什么区别。真正的问题是我提交请求的方式。