Как зациклить все документы в коллекции - Azure CosmosDB - Nodejs - PullRequest
0 голосов
/ 05 сентября 2018

Я просмотрел несколько ответов / вопросов по этой проблеме, но пока не нашел решения.

У меня есть коллекция с документами (в упрощенном виде):

{
    "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 Увеличить максимальный размер массива )

Или я не правильно понял вышеупомянутый вопрос? Речь идет о количестве объектов в массиве (из которых каждый может иметь неограниченную длину символа объекта?)

Таким образом, я ищу for loop -экологичное решение, где каждый документ возвращается, я делаю анализ, затем перехожу к следующему / затем выполняю их параллельно.

Любое понимание будет с благодарностью.

Ответы [ 2 ]

0 голосов
/ 15 сентября 2018

Я использую библиотеку 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)
        }
    });
});

};

0 голосов
/ 07 сентября 2018

Но проблема в том, что массив имеет максимальный лимит символов. Если мой коллекция имеет миллионы документов, это, вероятно, будет превышены. (Javascript Увеличить максимальный размер массива)

Согласно моим исследованиям , самый длинный из возможных массивов в js может иметь 232-1 = 4,294,967,295 = 4.29 миллиардов элементов. Однако этого вполне достаточно для удовлетворения ваших требований к объему данных в миллионах. Кроме того, вы не можете напрямую запрашивать такие огромные объемные данные, это невозможно.

Независимо от ограничений пропускной способности (настроек RU) или коэффициентов эффективности запросов, вам все равно следует подумать о пакетировании больших объемов данных.

Таким образом, я ищу решение для петли esque, где каждый документ вернулся, я делаю анализ, а затем перейти к следующему / сделать их в параллельны друг другу.

Возможно, вы могли бы использовать 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);
});

Подробнее о токене продолжения см. В моем предыдущем случае . Любая проблема, пожалуйста, дайте мне знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...