【问题标题】:How to for loop all documents in a collection - Azure CosmosDB - Nodejs如何循环集合中的所有文档-Azure CosmosDB-Nodejs
【发布时间】:2019-02-10 22:01:36
【问题描述】:

我已经查看了有关此问题的一些答案/问题,但尚未找到解决方案。

我有一个包含文档(简化)的集合:

{
    "id": 123
    "stuff": "abc"
    "array":[
        {
        "id2":456
        "properties": [
                {
                    "id3": 789
                    "important": true
                }
            ]
        }
    ]
} 

我想检查 for 我集合中的每个文档,for array 中的每个 array 对象,for 每个 properties,例如,如果它有 important: true。然后返回:

"id": 123
"id2": 456
"id3": 789

我尝试过使用:

client.queryDocuments(self.collection._self, querySpec).toArray(function(err, results) {
    if (err) {
        callback(err);
    } else {
        callback(null, results[0]);
    }
    });

但问题是数组有最大字符限制。如果我的收藏有数百万份文档,这可能会被超过。 (Javascript Increase max array size)

或者,我是否误解了上述问题?是指数组中对象的数量吗(其中,每个对象的字符长度都可以无限?)

因此,我正在寻找一个for loop-esque 解决方案,其中返回每个文档,我进行分析,然后转到下一个/并行执行。

任何见解将不胜感激。

【问题讨论】:

    标签: arrays node.js azure for-loop azure-cosmosdb


    【解决方案1】:

    但问题是数组有最大字符限制。如果我的 集合有数百万个文档,这大概是 超过。 (Javascript 增加最大数组大小)

    基于我的research,js 中最长的数组可能有 232-1 = 4,294,967,295 = 4.29 十亿个元素。但是,它足以满足您数百万数据量的需求。另外,这么大的数据量你肯定不能直接查询,那是不可能的。

    无论是吞吐量限制(RU 设置)还是查询效率因素,您都应该考虑批量处理大量数据。

    因此,我正在寻找一个 for 循环式的解决方案,其中每个文档都在 返回,我做我的分析,然后移动到下一个/做他们 并行。

    也许您可以将v2 js sdk 用于cosmos db sql api。请参考示例代码:

    const cosmos = require('@azure/cosmos');
    const CosmosClient = cosmos.CosmosClient;
    
    const endpoint = "https://***.documents.azure.com:443/";                 // Add your endpoint
    const masterKey = "***";  // Add the masterkey of the endpoint
    const client = new CosmosClient({ endpoint, auth: { masterKey } });
    const databaseId = "db";
    const containerId = "coll";
    
    async function run() {
        const { container, database } = await init();
        const querySpec = {
            query: "SELECT r.id,r._ts FROM root r"
        };
        const queryOptions  = {
            maxItemCount : -1
        }
       const queryIterator = await container.items.query(querySpec,queryOptions);
        while (queryIterator.hasMoreResults()) {
            const { result: results, headers } = await queryIterator.executeNext();
            console.log(results)
            console.log(headers)
            //do what you want to do
    
            if (results === undefined) {
                // no more results
                break;
            }   
        }
    }
    
    async function init() {
        const { database } = await client.databases.createIfNotExists({ id: databaseId });
        const { container } = await database.containers.createIfNotExists({ id: containerId });
        return { database, container };
    }
    
    run().catch(err => {
        console.error(err);
    });
    

    更多关于延续令牌的细节,请参考我的previous case。有任何问题,请告诉我。

    【讨论】:

    • 很快就会试试这个。问题是我的功能应用程序肯定仍然是 v1。有 v1 解决方案吗?还有40亿的长度,是字符还是对象?
    • @JDT 40 亿长度是对象。你的意思是你使用 v1 azure 函数?
    • 是的 v1 Azure。如果是 40 亿个对象,那么这可能不是问题,至少暂时不会
    【解决方案2】:

    我正在使用 Cosmos DB SQL API Node.js 库。我无法从此库中找到继续令牌,以便将其返回给客户。这个想法是从客户端取回它以用于下一个分页请求。

    我有一个工作代码,它会迭代多次以获取所有文档。此处需要进行哪些更改才能获得延续令牌?

    function queryCollectionPaging() {  
    return new Promise((resolve, reject) => {
        function executeNextWithRetry(iterator, callback) {         
            iterator.executeNext(function (err, results, responseHeaders) {
                if (err) {
                    return callback(err, null);
                }
                else {
                    documents = documents.concat(results);
                    if (iterator.hasMoreResults()) {
                        executeNextWithRetry(iterator, callback);
                    }
                    else {
                        callback();
                    }
                }
            });
        }
    
        let options = {
            maxItemCount: 1,
            enableCrossPartitionQuery: true
        };
    
        let documents = []
        let iterator = client.queryDocuments( collectionUrl, 'SELECT r.partitionkey, r.documentid, r._ts FROM root r WHERE r.partitionkey in ("user1", "user2") ORDER BY r._ts', options);
    
        executeNextWithRetry(iterator, function (err, result) {
            if (err) {
                reject(err)
            }
            else {
                console.log(documents);
                resolve(documents)
            }
        });
    });
    

    };

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-30
      • 2021-03-30
      • 1970-01-01
      • 2019-08-05
      • 1970-01-01
      • 2020-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多