首页 文章

在存储过程中获取多个文档(Azure DocumentDB)

提问于
浏览
0

我有两种文档类型,列表和产品 . 清单对象包含某些国家/地区的产品列表,如下所示:

Listing

{
  "Name": "Default",
  "Countries": {
    "_default": [
      "4QlxAPFcCAAPAAAAAAAAAA==",
      "4QlxAPFcCAAHAAAAAAAAAA=="
    ],
    "US": [
      "4QlxAPFcCAAIAAAAAAAAAA==",
      "4QlxAPFcCAAHAAAAAAAAAA=="
    ]
  },
  "Type": "Listing",
  "id": "dfed1839-07c5-482b-81c5-669b1dbcd0b6",
  "_rid": "4QlxAPFcCAAEAAAAAAAAAA=="
}

Product:

{
    "Name": "Widget",
    "Price": 3.45,
    "Type": "Product",
    "_rid": "4QlxAPFcCAAHAAAAAAAAAA=="
}

我的目标是在Azure DocumentDB集合中创建一个存储过程,它采用两个参数 ridcountry ,它们本质上可以以最有效的方式获取列表文档和该国家/地区的文档 . 我的假设是使用 getContext().getCollection().readDocument(...) 按其资源ID加载文档将是最快的方法,因此尝试为此创建存储过程 .

我的尝试是嵌套连续调用(回调地狱?),使用带有yield的生成器/迭代器,然后使用纯 Promise 方法 . 所有尝试都给出了相同的结果:

它将获取第一个文档,但在收到文档后会突然结束 .

作为参考,这是我的最新尝试:

function test(rid, country) {
    var collection = getContext().getCollection();
    var collectionSelfLink = collection.getSelfLink();
    var docsLink = collectionSelfLink + "docs/";
    var body = getContext().getResponse().setBody;  

    function getDocument(rid) {
        return new Promise(function(resolve, reject) {
            var accepted = collection.readDocument(docsLink + rid, (err, doc, opts) => {
                resolve(doc);
            });

            if (!accepted)
                reject("Not accepted");            
        });
    }

    getDocument(rid)
        .then(doc => { 
            body("0. First step"); // set test body 

            // Countries is a Dictionary<string, string[]> with resource ids
            return doc.Countries[country] || doc.Countries["_default"];
        })
        // This is how far it gets, resulting in response "1. Documents to fetch: 2"
        .then(a => body("1. Documents to fetch: " + a.length))
        .then(a => a.map(function(productId) { return getDoument(productId); }))
        .then(a => body("2. It should come this far, right?"))
        .then(a => Promise.all(a))
        .then(a => body(a))
        .catch(function(e) { throw new Error(JSON.stringify(e)); });
}

1 回答

  • 0

    事实证明,如果频繁更改响应主体,嵌套调用 do 实际上是有效的(?)

    以下过程按预期工作:

    function test(rid, country) {
        var collection = getContext().getCollection();
        var collectionSelfLink = collection.getSelfLink();
        var docsLink = collectionSelfLink + "docs/";
        var body = getContext().getResponse().setBody;
    
        var accepted = collection.readDocument(docsLink + rid, (err, doc, opts) => {
            if (err) throw new Error(err.message);
    
            // Countries is a Dictionary<string, string[]> with resource ids
            var offerIds = doc.Countries[country] || doc.Countries["_default"];
            var result = [];
    
            for (var docId of offerIds) {
                var subAccepted =
                    collection.readDocument(docsLink + docId, (err, doc, opts) => {
                        if (err) throw new Error(err.message);
    
                        result.push(doc);
                    });
    
                if (!subAccepted)
                    throw new Error("A subsequent request was not accepted");
    
                body(result); // <-- Note, setting body in each iteration.
            }
        });
    
        if (!accepted)
            throw new Error("The request was not accepted");
    }
    

相关问题