在Azure Cosmos存储过程中递归获取文档

时间:2018-11-27 23:32:22

标签: azure stored-procedures azure-cosmosdb

我正在尝试为简单的Wiki生成内容树。每个页面都有一个Children属性,该属性存储其他Wiki页面的ID。我正在尝试编写获取所有文档的SPROC,然后遍历每个页面的Children属性,并用实际的Wiki页面文档替换每个项目。我可以获取第一套文档,但是WikiChildQuery返回undefined,但我不确定为什么。

我已经能够单独使用查询获取文档,但是由于某种原因,它在SPROC中不起作用。这里有我想念的东西吗?

function GetWikiMetadata(prefix) {
    var context = getContext();
    var collection = context.getCollection();
    var metadataQuery = 'SELECT {\"ExternalId\": p.ExternalId, \"Title\": p.Title, \"Slug\": p.Slug, \"Children\": p.Children} FROM Pages p'

    var metadata = collection.queryDocuments(collection.getSelfLink(), metadataQuery, {}, function (err, documents, options) {
        if (err) throw new Error('Error: ', + err.message);

        if (!documents || !documents.length) {
            throw new Error('Unable to find any documents');
        } else {
            var response = getContext().getResponse();

            for (var i = 0; i < documents.length; i++) {
                var children = documents[i]['$1'].Children;

                if (children.length) {
                    for (var j = 0; j < children.length; j++) {
                        var child = children[j];

                        children[j] = GetWikiChildren(child);
                    }
                }
            }

            response.setBody(documents);
        }
    });

    if (!metadata) throw new Error('Unable to get metadata from the server');

    function GetWikiChildren(child) {
        var wikiChildQuery = metadataQuery + ' WHERE p.ExternalId = \"' + child + '\"';

        var wikiChild = collection.queryDocuments(collection.getSelfLink(), wikiChildQuery, {}, function(err, document, options) {
            if (err) throw new Error('Error: ', + err.message);

            if (!document) {
                throw new Error('Unable to find child Wiki');
            } else {
                var children = document.Children;

                if (children) {
                    for (var k = 0; k < children.length; k++) {
                        var child = children[k];

                        children[k] = GetWikiChildren(child);
                    }
                } else {
                    return document;
                }
            }

            if (!wikChild) throw new Error('Unable to get child Wiki details');
        });
    }
}

1 个答案:

答案 0 :(得分:0)

  

1。我可以获取第一套文档,但是WikiChildQuery   返回undefined,我不太确定为什么。

首先,应在此处更正。在第一个循环中,您获得带有documents[i]['$1'].Children的孩子数组,但是,在GetWikiChildren函数中,您想要获得带有document.Children的孩子数组吗?当然是undefined。您需要使用var children = document[0]['$1'].Children;

  

2。似乎您错过了replaceDocument方法。

您可以参考metaDataQuery函数的代码段:

for (var i = 0; i < documents.length; i++) {
            var children = documents[i]['$1'].Children;

            if (children.length) {
                for (var j = 0; j < children.length; j++) {
                    var child = children[j];

                    children[j] = GetWikiChildren(child);
                }
            }
            documents[i]['$1'].Children = children;
            collection.replaceDocument(doc._self,doc,function(err) {
                             if (err) throw err;
                 });
        }
  

3。到目前为止,Cosmos db SQL Api不支持部分更新,但仍在进行中。

因此,如果您的sql不能覆盖您的整个列,则不能出于替换目的而使用它。(feedback)请务必注意,替换对象中未提及的列使用replaceDocument方法时会被吞噬。