Как считать субдокументы рекурсивно - PullRequest
0 голосов
/ 07 февраля 2020

У меня есть документы в моей БД, которые выглядят так:

{
  "id": "1"
  "entityType": "node"
  "childNodes": [
   {
     "id": "2"
     "entityType": "node"
     "childNodes": [
          ...
     ]
   }
  ]
}

Как большая древовидная структура.

Я хотел бы подсчитать общее количество документов и вложенных документов в моей коллекции, которые имеют entityType = "Node".

Моя попытка - получить данные по одному уровню за раз вручную :

SELECT VALUE COUNT(c.id) FROM c where CONTAINS(c.id, 'a|') and c.entityType = 'node'
SELECT VALUE COUNT(l.id) FROM c JOIN l in c.childNodes where CONTAINS(c.id, 'a|') and c.entityType = 'node'
SELECT VALUE COUNT(l2.id) FROM c JOIN l in c.childNodes JOIN l2 in l.childNodes where CONTAINS(c.id, 'a|') and c.entityType = 'node'

1 Ответ

0 голосов
/ 10 февраля 2020

Прежде всего, трудно найти плавный (прямой) способ реализации ваших потребностей. Конечно, ручной способ, который вы упомянули в своем вопросе, работает. Однако, если у вас слишком много уровней вложенности JSON, или это случайным образом, ваш путь может быть неуместным.

Я бы предложил вам рекурсивно получить l oop результат для подсчета объектов, содержащих "entityType": "node". Например, в хранимой процедуре cosmos db:

function sample(prefix) {
    var collection = getContext().getCollection();

    var isAccepted = collection.queryDocuments(
        collection.getSelfLink(),
        'SELECT c.childNodes FROM c where c.entityType = "node"',
    function (err, feed, options) {
        if (err) throw err;

        if (!feed || !feed.length) {
            var response = getContext().getResponse();
            response.setBody('no docs found');
        }
        else {
            var response = getContext().getResponse();
            var count = {count:1};
            loopChildNodes(feed,count);
            response.setBody(count);
        }
    });

    if (!isAccepted) throw new Error('The query was not accepted by the server.');

    function loopChildNodes(array,count){
        for (var i=0;i<array.length;i++){
            console.log(count)
            if(array[i].entityType == "node"){
                count.count++;
            }
            if(array[i].childNodes!=null)
                loopChildNodes(array[i].childNodes,count)
        }
    }
}

Мои данные испытаний:

enter image description here

Выход:

enter image description here

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