NSNJSON. 道 (Заключительная статья)

    道 — путь. В этой заключительной статье о формате NSNJSON я хочу рассказать о моем пути, который привел меня к изобретению этого формата.

    В комментариях к моим прошлым статьям («Усложнённый упрощённый JSON» и «JSON для любителей скобочек») неоднократно прозвучали вопросы о смысле, сложности, удобности и применимости этого формата. Итак, спешу поздравить всех неравнодушных — Вы дождались!




    Содержание


        Введение
        Задача №1. Представление документов на иерархических структрах данных
        Задача №2. Реализация драйвера
        О формате NSNJSON
        Заключение

    Введение


    Всё началось с моего знакомства с одной интересной NoSQL СУБД, а именно, InterSystems Caché. Компания InterSystems ведет блог на Хабрахабре, в котором можно почитать о внутреннем устройстве этой СУБД. Скажу лишь, что ESA использует InterSystems Caché в проекте GAIA (спасибо за поправку tsafin и morrison).

    Для того, чтобы понять дальнейшую суть необходимо знать, что данные в Caché хранятся в глобалах (можно думать о глобале, как о иерархической структуре данных). Более подробно о глобалах можно почитать в следующих статьях:

    1. GlobalsDB — универсальная NoSQL база данных. Часть 1,
    2. GlobalsDB — универсальная NoSQL база данных. Часть 2.

    В рамках моей магистерской программы, был начат проект по реализации документо-ориентированной NoSQL на основе Caché. Теоретической исследовательской базой этого проекта является концептуальный вопрос о быстродействии, производительности и надежности такой реализации, по сравнению с существующим решением. В качестве опорной документо-ориентированной NoSQL была выбрана моя любимая MongoDB.

    Итак, что же я имел в своем начале пути?

    1. Документо-ориентированную NoSQL MongoDB.
    2. Иерархическую NoSQL Caché.


    Задача №1. Представление документов на иерархических структрах данных


    Казалось бы, JSON документы итак можно назвать иерархическими, и потому никакой сложности в этой задаче нет. Однако, дъявол кроется в деталях, как оказалось, в глобалах может храниться значение или бинарное, или строковое или числовое. Еще поддерживаются списки. Иными словами, лист дерева (значение глобала) может содержать или число или строку или бинарные данные или список. Я был в самом начале своего пути и потому отказался от хранения JSON в бинарном виде, отдав предпочтение строкам и числам. В свою очередь, такое решение потребовало придумать как сохранять JSON данные имея в распоряжении лишь строки и числа.

    Напомню, что JSON формат определяет 6 типов: null, number, string, true, false, array, object. Таким образом, требовалось придумать однозначную схему представления данных для каждого JSON типа, имя в распоряжении лишь возможность строить иерархии и использовать, в качестве значений для листов дерева, строки и числа. Однако, к схеме представления JSON данных выдвигалось еще одно требование — однозначность. Это условие — гарант однозначной восстанавливаемости JSON данных из глобалов.

    Немного поясню этот момент.

    Рассмотрим JSON тип null. Можно было бы предложить для него простую схему. Допустим, если есть значения типа JSON null, то при сохранении этого значения в глобал необходимо создать лист и установить в качестве значения пустую строку "". Однако, первый же контрпример приходит очень быстро, — схема теряет однозначность в тот момент, когда нам потребуется сохранить значение типа JSON string, равное пустой строке. В связи с этим я решил перейти на другую, довольно простую схему.

    описание схемы
    JSON null


    JSON number (значение value)


    Например, для значения value
    2015
    представление было бы следующим:


    JSON string (значение value)


    Например, для значения value
    "R&D"
    представление было бы следующим:


    JSON true


    JSON false


    JSON array


    Например, для массива
    [ 2015, "R&D" ]
    представление было бы следующим:


    JSON object


    Например, для объекта

    { "year": 2015, "section": "R&D" }

    представление было бы следующим:



    Можно считать, что эта схема и стала прародителем формата NSNJSON.

    Теперь, когда схема представления JSON данных готова, меня ждал следующий шаг на моем пути. Мне нужно было разработать драйвер для этой документо-ориентированной NoSQL СУБД.


    Задача №2. Реализация драйвера


    Реализация драйвера состоит из двух этапов:

    1. разработка хранимого кода (в Caché, на языке Caché ObjectScript),
    2. разработка кода, который будет обращаться к драйверу Caché и передавать данные хранимому коду.

    Для передачи данных между моим драйвером и драйвером Caché, я выбрал простой формат, — строковый. Мой драйвер получал JSON, преобразовывал в строку и передавал драйверу Caché, тот в свою очередь передавал эту строку хранимому коду. Хранимый код парсил эту строку, а далее применял правила представления JSON данных на глобалах.

    Однако, меня ждал сюрприз!

    Во время разработки и отладки выяснилось несколько интересных фактов об используемом мной JSON парсере в хранимом коде Caché:

    • JSON тип null транслируется в "",
    • JSON тип true транслируется в 1,
    • JSON тип false транслируется в 0.
    • поля начинающиеся со знака _ игнорируются.

    Таким образом, мне нужно было решить следующие проблемы:

    • сохранение информации о типе,
    • сохранение полей, начинающихся со знака _.

    Решением этих проблем стал разработанный мной формат NSNJSON.

    Так, для значений типа null предлагалось следующее представление:

    
    { "t": "null" }
    

    Для значений типа true предлагалось следующее представление:

    
    { "t": "boolean", "v": 1 }
    

    Для значений типа false предлагалось следующее представление:

    
    { "t": "boolean", "v": 0 }
    

    Проблема с _ решилась с помощью введения поля «n».

    Так, для поля _id со значением 213, представление было бы таким:

    
    { "n": "_id", "t": "number", "v": 213 }
    

    Таким образом, данный формат решил все ранее указанные проблемы.


    О формате NSNJSON


    Я решил выделить формат в отдельный проект и назвать NSNJSON (Not So Normal JSON). А потом я решил поделиться этим фоматом с уважаемым сообществом Хабрахабра в своей статье «Усложнённый упрощённый JSON», а также, об интересной, на мой взгляд, модификации этого формата, в котором JSON данные представляются с помощью чисел, строк и массивов, в статье «JSON для любителей скобочек».

    Проект NSNJSON опубликован на GitHub.

    Для него реализованы два драйвера:

    1. NSNJSON Node.js Driver
    2. NSNJSON Java Driver


    Заключение


    Вот и подошла к концу заключительная статья о NSNJSON. Я рассказал о трудностях с которыми столкнулся, а также о том, как я их преодолел.
    На последок, хочу еще раз отметить, что это был мой 道 (путь), и я его прошёл именно таким образом. На каждом шаге можно было бы пойти по-другому, выбирая другой вариант решения возникавших проблем, но это был бы уже не мой путь…

    Similar posts

    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 15

      0
      Раз уж это магистерская, то имело бы смысл реализовывать не примитивную документоориентированную субд, а хотя бы графовую. Ну и опять же, не понятно зачем ограничиваться именно JSON, если он для этой задачи не слишком подходит.
        0
        В JSON все что не хватает — это комментариев.
        Я бы предложил такое:
        Однострочные //
        Многострочные /* */
        И блочные (для структурного комментирования скобочного блока) #
          0
          В JSON много чего не хватает. Прежде всего не хватает расширяемости.
            0
            О какой расширяемости идет речь? «Расширяемость» — слишком большое понятие.
            А так он свою функцию вполне выполняет.
              +3
              О добавлении своих типов узлов. Приходится писать такие костыли: [ «date», «2015-11-11» ] или { «type»: «date», «value»: «2015-11-11» }
                0
                Добавлю в список костыль от Microsoft: "/Date(1234567)/"
                  0
                  Как хорошо что в JSON нет расширяемости!!!
                    0
                    Ну да, ведь шести типов хватит всем :-)
              +1
              Блочный комментарий сделает JSON несовместимым с JS…
                –1
                Для красоты и удобства могу присоветовать CSON. Coffescript JSON.
                Тот же JSON только в Coffee. Плюс в том что нет запятых и скобочек и все красиво.

                И вместо `require('config.json')` даем `require('config.cson')` и все.
                Очень удобно.
                  0
                  Да-да, очень. Особенно тем, кто никогда не писал require('config.json') :)
                    –1
                    Писать в JS и не писать `require` немного странно )
                      0
                      Я не говорил, что не писал require (хотя в этом тоже нет ничего странного, всего лишь ручная сборка зависимостей). Я сказал, что никогда не загружал конфиг через require…

                      Для справки: js — это не только сервер-сайд в виде node.js, некоторые люди еще и скрипты для браузера пишут :)
              +1
              FWIW. GAIA это не про NASA, а про ESA (European Space Agency).
                0
                Скажу лишь, что NASA использует InterSystems Caché в проекте GAIA.
                Поправочка: не NASA, а ESA.

                Only users with full accounts can post comments. Log in, please.