2017-01-20 1 views
0

У меня есть база данных DocumentDb, где один из документов-типов имеет следующую структуру:Pure функции Javascript (es2015), чтобы извлечь ребенка из структуры дерева JSon

{ 
 
    "structure": { 
 
     "id": "7d2d5d3f-0c82-4910-aa0b-54d8067588a3", 
 
     "unittype": 1, 
 
     "name": "MyCompany", 
 
     "language": "nb-NO", 
 
     "managers": [], 
 
     "logoURL": null, 
 
     "orginfo": { 
 
      "Orgnumber": null, 
 
      "Country": null, 
 
      "Sector": null, 
 
      "Code": null 
 
     }, 
 
     "tags": [], 
 
     "respondents": [], 
 
     "childUnits": [ 
 
      { 
 
       "id": "3fb44416-8fa8-4b60-8c0c-03b333d176f7", 
 
       "unittype": 3, 
 
       "name": "Marketing", 
 
       "language": "nb-NO", 
 
       "managers": [], 
 
       "logoURL": null, 
 
       "orginfo": { 
 
        "Orgnumber": null, 
 
        "Country": null, 
 
        "Sector": null, 
 
        "Code": null 
 
       }, 
 
       "tags": [], 
 
       "respondents": [], 
 
       "childUnits": [ 
 
        { 
 
         "id": "49932d6f-518e-4511-9bc9-f6f747a81968", 
 
         "unittype": 3, 
 
         "name": "Internet", 
 
         "language": "nb-NO", 
 
         "managers": [], 
 
         "logoURL": null, 
 
         "orginfo": { 
 
          "Orgnumber": null, 
 
          "Country": null, 
 
          "Sector": null, 
 
          "Code": null 
 
         }, 
 
         "tags": [], 
 
         "respondents": [], 
 
         "childUnits": [], 
 
         "Parent": "3fb44416-8fa8-4b60-8c0c-03b333d176f7" 
 
        }, 
 
        { 
 
         "id": "aa76010d-ae59-49b1-b929-9572eb536cc6", 
 
         "unittype": 3, 
 
         "name": "DM", 
 
         "language": "nb-NO", 
 
         "managers": [], 
 
         "logoURL": null, 
 
         "orginfo": { 
 
          "Orgnumber": null, 
 
          "Country": null, 
 
          "Sector": null, 
 
          "Code": null 
 
         }, 
 
         "tags": [], 
 
         "respondents": [], 
 
         "childUnits": [], 
 
         "Parent": "3fb44416-8fa8-4b60-8c0c-03b333d176f7" 
 
        } 
 
       ], 
 
       "Parent": "7d2d5d3f-0c82-4910-aa0b-54d8067588a3" 
 
      }, 
 
      { 
 
       "id": "be1d142a-e09d-4828-aceb-07d65321da5d", 
 
       "unittype": 3, 
 
       "name": "Support", 
 
       "language": "nb-NO", 
 
       "managers": [], 
 
       "logoURL": null, 
 
       "orginfo": { 
 
        "Orgnumber": null, 
 
        "Country": null, 
 
        "Sector": null, 
 
        "Code": null 
 
       }, 
 
       "tags": [], 
 
       "respondents": [], 
 
       "childUnits": [], 
 
       "Parent": "7d2d5d3f-0c82-4910-aa0b-54d8067588a3" 
 
      } 
 
     ], 
 
     "Parent": null 
 
    }, 
 
    "id": "07b4c7c5-7324-4eef-9e4e-9deb70615ec4", 
 
    "type": "organization", 
 
    "owner": "auth0|571f2eb34247998a66726b02", 
 
    "public": false, 
 
    "_rid": "GPFbALqREAMNAAAAAAAAAA==", 
 
    "_self": "dbs/GPFbAA==/colls/GPFbALqREAM=/docs/GPFbALqREAMNAAAAAAAAAA==/", 
 
    "_etag": "\"00004707-0000-0000-0000-5881cef40000\"", 
 
    "_attachments": "attachments/", 
 
    "_ts": 1484902132 
 
}

Это является восстановление старой системы, где все хранилось в реляционной базе данных, и каждый Unit (объекты в свойстве childUnits) первоначально был линией в таблице. Тестирование с одним из наших крупнейших клиентов мы получим структуру с более чем 500 единицами. И более 3000 респондентов. (Я еще не добавил ни одного из этих демо, но объект Respondent содержит адрес электронной почты (обязательно) и, возможно, номер ячейки.)

Результат был не очень хороший. Запуск локально на моем (довольно мускулистом) devpc извлечении структуры занимает около 2-3 секунд. И DocumentDb не поддерживает извлечение деталей документа. Таким образом, каждый раз, когда пользователь нажимает на единицу в древовидной структуре, вся структура возмущается по проводу (эта часть, которую я, вероятно, мог бы кэшировать, но если пользователь что-то изменит, мне нужно будет хранить всю вещь, а затем читать ее) ,

Что такое DocumentDb , однако, это хранимые процедуры Javascript, в которых используется Chakra, что соответствует ES2015, насколько я могу судить.

Итак, я думал о создании хранимой процедуры, в которой я даю id документу (органам) и id для извлечения Единицы. И он ищет через json-документ и извлекает только тот блок, который я хочу, и отправляет его обратно.

Возможно ли это, если нет внешних библиотек, только функции ES2015?

ответ

0

Array.prototype.find решает большинство из этих проблем.

Если необходимо, вы можете заполнить эту функцию: MDN official polyfill.

var db = { 
 
    "structure": { 
 
     "id": "7d2d5d3f-0c82-4910-aa0b-54d8067588a3", 
 
     "unittype": 1, 
 
     "name": "MyCompany", 
 
     "language": "nb-NO", 
 
     "managers": [], 
 
     "logoURL": null, 
 
     "orginfo": { 
 
      "Orgnumber": null, 
 
      "Country": null, 
 
      "Sector": null, 
 
      "Code": null 
 
     }, 
 
     "tags": [], 
 
     "respondents": [], 
 
     "childUnits": [ 
 
      { 
 
       "id": "3fb44416-8fa8-4b60-8c0c-03b333d176f7", 
 
       "unittype": 3, 
 
       "name": "Marketing", 
 
       "language": "nb-NO", 
 
       "managers": [], 
 
       "logoURL": null, 
 
       "orginfo": { 
 
        "Orgnumber": null, 
 
        "Country": null, 
 
        "Sector": null, 
 
        "Code": null 
 
       }, 
 
       "tags": [], 
 
       "respondents": [], 
 
       "childUnits": [ 
 
        { 
 
         "id": "49932d6f-518e-4511-9bc9-f6f747a81968", 
 
         "unittype": 3, 
 
         "name": "Internet", 
 
         "language": "nb-NO", 
 
         "managers": [], 
 
         "logoURL": null, 
 
         "orginfo": { 
 
          "Orgnumber": null, 
 
          "Country": null, 
 
          "Sector": null, 
 
          "Code": null 
 
         }, 
 
         "tags": [], 
 
         "respondents": [], 
 
         "childUnits": [], 
 
         "Parent": "3fb44416-8fa8-4b60-8c0c-03b333d176f7" 
 
        }, 
 
        { 
 
         "id": "aa76010d-ae59-49b1-b929-9572eb536cc6", 
 
         "unittype": 3, 
 
         "name": "DM", 
 
         "language": "nb-NO", 
 
         "managers": [], 
 
         "logoURL": null, 
 
         "orginfo": { 
 
          "Orgnumber": null, 
 
          "Country": null, 
 
          "Sector": null, 
 
          "Code": null 
 
         }, 
 
         "tags": [], 
 
         "respondents": [], 
 
         "childUnits": [], 
 
         "Parent": "3fb44416-8fa8-4b60-8c0c-03b333d176f7" 
 
        } 
 
       ], 
 
       "Parent": "7d2d5d3f-0c82-4910-aa0b-54d8067588a3" 
 
      }, 
 
      { 
 
       "id": "be1d142a-e09d-4828-aceb-07d65321da5d", 
 
       "unittype": 3, 
 
       "name": "Support", 
 
       "language": "nb-NO", 
 
       "managers": [], 
 
       "logoURL": null, 
 
       "orginfo": { 
 
        "Orgnumber": null, 
 
        "Country": null, 
 
        "Sector": null, 
 
        "Code": null 
 
       }, 
 
       "tags": [], 
 
       "respondents": [], 
 
       "childUnits": [], 
 
       "Parent": "7d2d5d3f-0c82-4910-aa0b-54d8067588a3" 
 
      } 
 
     ], 
 
     "Parent": null 
 
    }, 
 
    "id": "07b4c7c5-7324-4eef-9e4e-9deb70615ec4", 
 
    "type": "organization", 
 
    "owner": "auth0|571f2eb34247998a66726b02", 
 
    "public": false, 
 
    "_rid": "GPFbALqREAMNAAAAAAAAAA==", 
 
    "_self": "dbs/GPFbAA==/colls/GPFbALqREAM=/docs/GPFbALqREAMNAAAAAAAAAA==/", 
 
    "_etag": "\"00004707-0000-0000-0000-5881cef40000\"", 
 
    "_attachments": "attachments/", 
 
    "_ts": 1484902132 
 
}; 
 
function getDocument(orgID, docID) { 
 
    //Variable to hold traversal progress 
 
    var extract = db 
 
     .structure 
 
     .childUnits 
 
     .find(function findFunc(organization) { 
 
     return organization.id == orgID; 
 
    }); 
 
    //Return false if we found no organization 
 
    if (typeof extract == "undefined") { 
 
     return false; 
 
    } 
 
    //Traverse organization children 
 
    extract = extract 
 
     .childUnits 
 
     .find(function findFunc(document) { 
 
     return document.id == docID; 
 
    }); 
 
    //Return false if we found no organization 
 
    if (typeof extract == "undefined") { 
 
     return false; 
 
    } 
 
    //if we reach this point we found a result, which we can then return 
 
    return extract; 
 
} 
 
//Running test 
 
console.log(getDocument("3fb44416-8fa8-4b60-8c0c-03b333d176f7", "aa76010d-ae59-49b1-b929-9572eb536cc6")); 
 
console.log(getDocument("3fb44416-8fa8-4b60-8c0c-03b333d176f7", "ERR")); 
 
console.log(getDocument("ERR", "aa76010d-ae59-49b1-b929-9572eb536cc6")); 
 
console.log(getDocument("ERR", "ERR"));

+0

Кто-нибудь подтвердил? Это работает в хранимой процедуре в DocumentDB? –

0

Вы можете использовать Array#some с итеративной и рекурсивной стиле.

function getObject(object, id) { 
 
    var r; 
 
    return function iter(o) { 
 
     if (o.id === id) { 
 
      r = o; 
 
      return true; 
 
     } 
 
     if (Array.isArray(o.childUnits)) { 
 
      return o.childUnits.some(iter); 
 
     } 
 
    }(object) && r || undefined; 
 
} 
 

 
var data = { structure: { id: "7d2d5d3f-0c82-4910-aa0b-54d8067588a3", unittype: 1, name: "MyCompany", language: "nb-NO", managers: [], logoURL: null, orginfo: { Orgnumber: null, Country: null, Sector: null, Code: null }, tags: [], respondents: [], childUnits: [{ id: "3fb44416-8fa8-4b60-8c0c-03b333d176f7", unittype: 3, name: "Marketing", language: "nb-NO", managers: [], logoURL: null, orginfo: { Orgnumber: null, Country: null, Sector: null, Code: null }, tags: [], respondents: [], childUnits: [{ id: "49932d6f-518e-4511-9bc9-f6f747a81968", unittype: 3, name: "Internet", language: "nb-NO", managers: [], logoURL: null, orginfo: { Orgnumber: null, Country: null, Sector: null, Code: null }, tags: [], respondents: [], childUnits: [], Parent: "3fb44416-8fa8-4b60-8c0c-03b333d176f7" }, { id: "aa76010d-ae59-49b1-b929-9572eb536cc6", unittype: 3, name: "DM", language: "nb-NO", managers: [], logoURL: null, orginfo: { Orgnumber: null, Country: null, Sector: null, Code: null }, tags: [], respondents: [], childUnits: [], Parent: "3fb44416-8fa8-4b60-8c0c-03b333d176f7" }], Parent: "7d2d5d3f-0c82-4910-aa0b-54d8067588a3" }, { id: "be1d142a-e09d-4828-aceb-07d65321da5d", unittype: 3, name: "Support", language: "nb-NO", managers: [], logoURL: null, orginfo: { Orgnumber: null, Country: null, Sector: null, Code: null }, tags: [], respondents: [], childUnits: [], Parent: "7d2d5d3f-0c82-4910-aa0b-54d8067588a3" }], Parent: null }, id: "07b4c7c5-7324-4eef-9e4e-9deb70615ec4", type: "organization", owner: "auth0|571f2eb34247998a66726b02", public: false, _rid: "GPFbALqREAMNAAAAAAAAAA==", _self: "dbs/GPFbAA==/colls/GPFbALqREAM=/docs/GPFbALqREAMNAAAAAAAAAA==/", _etag: "\"00004707-0000-0000-0000-5881cef40000\"", _attachments: "attachments/", _ts: 1484902132 }; 
 

 
console.log(getObject(data.structure, 'foo')); 
 
console.log(getObject(data.structure, 'aa76010d-ae59-49b1-b929-9572eb536cc6'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

1

Лучший подход к производительности было бы эффективно использовать внутри документа JOIN - https://www.documentdb.com/sql/demo#JOIN.

Предполагая, что структура собственности фактически является частью документа, то РЕГИСТРИРУЙТЕСЬ запрос будет выглядеть следующим образом:

SELECT c.id, childUnit 
FROM c JOIN childUnit IN c.structure.childUnits 
WHERE c.structure.id = "7d2d5d3f-0c82-4910-aa0b-54d8067588a3" 
    AND childUnit.id = "3fb44416-8fa8-4b60-8c0c-03b333d176f7"* 

Если структура свойство не является частью исходного документа, то РЕГИСТРИРУЙТЕСЬ запрос будет выглядеть так:

SELECT c.id, childUnit 
FROM c JOIN childUnit IN c.childUnits 
WHERE c.id = "7d2d5d3f-0c82-4910-aa0b-54d8067588a3" 
    AND childUnit.id = "3fb44416-8fa8-4b60-8c0c-03b333d176f7"* 

Этот тип запроса возвращает только указанный дочерний блок из вашего документа.Код id и childUnit id в блоке WHERE увеличивает производительность запроса.

+0

Свойство '' structure'' является частью документа и имеет ту же структуру, что и childUnits. Что может быть не так ясно из свойства кода, так это то, что единицы вложены в древовидную структуру. Каждый блок имеет собственный массив childUnits, содержащий больше единиц и так далее. Я думаю, что для вашего примера для работы вам нужно сначала сгладить структуру. Чтобы попытаться быть более ясным: свойство '' structure'' могло бы быть массивом '' childUnits'' с одним модулем. –

+0

Рекурсивные структуры данных сложны, чтобы запросить по-своему. Я обнаружил, что использование полностью материализованного подхода к пути работает лучше всего. Вы можете прочитать об этом подходе [здесь] (http://probablyprogramming.com/2008/07/04/storing-hierarchical-data-in-couchdb) и [здесь] (https://docs.mongodb.com/ ручная/учебник/модель-дерево-структура /). –