如何循环集合中的所有文档 - Azure CosmosDB - Nodejs

问题描述 投票:1回答:2

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

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

{
    "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
2个回答
0
投票

但问题是数组具有最大字符限制。如果我的收藏有数百万份文件,那么可能会超出这个数量。 (Javascript增加最大数组大小)

基于我的research,js中最长的数组可能有232-1 = 4,294,967,295 = 4.29十亿元素。但是,它足以满足您数百万的数据量要求。此外,您无法直接查询如此庞大的数据量,这是不可能的。

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

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

也许你可以使用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.Any关注,请告诉我。


0
投票

我正在使用Cosmos DB SQL API Node.js库。我无法从此库中找到Continuation Token,因此我可以将其返回给客户端。我们的想法是从客户端获取下一个分页请求。

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

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)
        }
    });
});

};

© www.soinside.com 2019 - 2024. All rights reserved.