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

Posted

技术标签:

【中文标题】如何循环集合中的所有文档-Azure CosmosDB-Nodejs【英文标题】:How to for loop all documents in a collection - 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 解决方案,其中返回每个文档,我进行分析,然后转到下一个/并行执行。

任何见解将不胜感激。

【问题讨论】:

【参考方案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)
        
    );
);

;

【讨论】:

以上是关于如何循环集合中的所有文档-Azure CosmosDB-Nodejs的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Databrick/PySpark 覆盖/更新 Azure Cosmos DB 中的集合

如何在 Azure Cosmos DB 的一个查询中选择多个聚合值

Azure Cosmos DB:将集合克隆到另一个数据库

如何获取 cosmos db 容器中所有文档的所有字段名称 [关闭]

使用Cosmos Client返回Azure Cosmos项目的平面层次结构

Azure Cosmos DB 如何按一系列值进行分组