diff options
author | iliashev <iliashev@yandex-team.com> | 2023-03-17 17:16:57 +0300 |
---|---|---|
committer | iliashev <iliashev@yandex-team.com> | 2023-03-17 17:16:57 +0300 |
commit | 13698560d299d3c1007cf0125f43008b63e6df7f (patch) | |
tree | e7376d1e658e047f7564873b40d159723060624e | |
parent | 9959a42781bf641f75ef94972faa4d29126ff14c (diff) | |
download | ydb-13698560d299d3c1007cf0125f43008b63e6df7f.tar.gz |
Add YSON and YPath docs
5 files changed, 450 insertions, 3 deletions
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_string.md b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_string.md index 74c985cb1e0..cc397b944db 100644 --- a/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_string.md +++ b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_string.md @@ -4,7 +4,7 @@ `Utf8` | Текст в кодировке [UTF-8](https://en.wikipedia.org/wiki/UTF-8) | `Json` | [JSON](https://en.wikipedia.org/wiki/JSON) в текстовом представлении|Не поддерживает возможность сравнения{% if feature_map_tables %}, не может быть использован в первичном ключе{% endif %} `JsonDocument` | [JSON](https://en.wikipedia.org/wiki/JSON) в бинарном индексированном представлении | Не поддерживает возможность сравнения{% if feature_map_tables %}, не может быть использован в первичном ключе{% endif %} -`Yson` | [YSON](../../udf/list/yson.md) в текстовом или бинарном представлении | Не поддерживает возможность сравнения{% if feature_map_tables %}, не может быть использован в первичном ключе{% endif %} +`Yson` | [YSON](../yson.md) в текстовом или бинарном представлении | Не поддерживает возможность сравнения{% if feature_map_tables %}, не может быть использован в первичном ключе{% endif %} `Uuid` | Универсальный идентификатор [UUID](https://tools.ietf.org/html/rfc4122) | Не поддержан для столбцов таблиц {% note info "Ограничения на размер" %} diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/index.md b/ydb/docs/ru/core/yql/reference/yql-core/types/index.md index 08821222c36..3c45e83bfe0 100644 --- a/ydb/docs/ru/core/yql/reference/yql-core/types/index.md +++ b/ydb/docs/ru/core/yql/reference/yql-core/types/index.md @@ -8,4 +8,5 @@ - [Специальные типы](special.md) - [Преобразования типов](cast.md) - [Текстовое представление типов данных](type_string.md) -- [Представление данных в формате JSON](json.md)
\ No newline at end of file +- [Представление данных в формате JSON](json.md) +- [Представление данных в формате YSON](yson.md)
\ No newline at end of file diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/toc_i.yaml b/ydb/docs/ru/core/yql/reference/yql-core/types/toc_i.yaml index e5b55f2535c..8b15ff4025f 100644 --- a/ydb/docs/ru/core/yql/reference/yql-core/types/toc_i.yaml +++ b/ydb/docs/ru/core/yql/reference/yql-core/types/toc_i.yaml @@ -14,4 +14,6 @@ items: - name: Текстовое представление типов данных href: type_string.md - name: JSON - href: json.md
\ No newline at end of file + href: json.md +- name: YSON + href: yson.md
\ No newline at end of file diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/yson.md b/ydb/docs/ru/core/yql/reference/yql-core/types/yson.md new file mode 100644 index 00000000000..ea7da2cf913 --- /dev/null +++ b/ydb/docs/ru/core/yql/reference/yql-core/types/yson.md @@ -0,0 +1,438 @@ +# Yson + +В данном разделе собрана информация про YSON — JSON-подобный формат данных, разработанный в Яндексе. + +{% note info %} + +SQL-функции для работы с YSON описаны [здесь](../udf/list/yson.md) + +{% endnote %} + +## Введение {#intro} + +К основным **отличиям YSON от JSON** относится: + +1. Поддержка бинарного представления скалярных типов (чисел, строк и булевого типа); +2. [Атрибуты](#attributes): произвольный словарь, который можно установить дополнительно на литерал любого (даже скалярного) типа. + +Кроме того существуют **синтаксические отличия**: + +1. Вместо запятой в качестве разделителя используется точка с запятой; +2. В словарях ключ от значения отделяется не двоеточием, а знаком равенства: `=`; +3. Строковые литералы не обязательно всегда заключать в кавычки (только если иначе возникает неоднозначность при парсинге). + +Имеется следующий набор **скалярных** типов: + +1. [Строки](#string) (`string`); +2. [Знаковые](#int) и [беззнаковые](#uint) 64-битные целые числа (`int64` и `uint64` ); +3. [Числа с плавающей точкой](#double) двойной точности (`double`); +4. [Булев](#boolean) (логический) тип (`boolean`); +5. [Специальный тип entity](#entity), имеющий всего один литерал (`#`). + +Скалярные типы обычно имеют как текстовое, так и бинарное представление. + +Есть два **композитных** типа: + +1. [Список](#list) (`list`); +2. [Словарь](#map) (`map`). + +## Скалярные типы {#scalar_types} + +### Строки {#string} + +Токены строк бывают трех видов: + +1. **Идентификаторы** задаются регулярным выражением ` [A-Za-z_][A-Za-z0-9_.\-]*` (Первый символ - буква или нижнее подчеркивание, со второго символа могут быть дополнительно использованы цифры и символы `-`,`.`). Идентификатор задает строку с идентичным ему содержимым и используется в первую очередь для краткости (не нужно ставить кавычки). + + Примеры: + + - `abc123`; + - `_`; + - `a-b`. + +2. **Текстовые строки** — [C-escaped](https://en.wikipedia.org/wiki/Escape_sequences_in_C) строки в двойных кавычках. + + Примеры + + - `"abc123"`; + - `""`; + - `"quotation-mark: \", backslash: \\, tab: \t, unicode: \xEA"`. + +3. **Бинарные строки**: `\x01 + length (protobuf sint32 wire format) + data (<length> bytes)`. + +### Знаковые 64-битные целые числа (`int64`) {#int} + +Два способа записи: + +1. **Текстовый** (`0`, `123`, `-123`, `+123`); +2. **Бинарный**: `\x02 + value (protobuf sint64 wire format)`. + +### Беззнаковые 64-битные целые числа (`uint64`) {#uint} +Два способа записи: + +1. **Текстовый** (`10000000000000`, `123u`); +2. **Бинарный**: `\x06 + value (protobuf uint64 wire format)`. + +### Числа с плавающей точкой (`double`) {#double} + +Два способа записи: + +1. **Текстовый** (`0.0`, `-1.0`, `1e-9`, `1.5E+9`, `32E1`, `%inf`, `%-inf`, `%nan`); +2. **Бинарный**: `\x03 + protobuf double wire format`. + +{% note warning %} + +Текстовое представление чисел с плавающей точкой включает в себя округление, которое может привести к тому, что при обратном парсинге значение окажется иным. В случае, если вам важна точность, следует использовать бинарное представление. + +{% endnote %} + +{% note warning %} + +Значения `%inf`, `%-inf`, `%nan` не существуют в JSON, поэтому вызов `Yson::SerializeJson` с содержащим эти значения YSON приведет к ошибке + +{% endnote %} + +### Булевы литералы (`boolean`) {#boolean} + +Два способа записи: + +1. **Текстовый** (`%false`, `%true`); +2. **Бинарный** (`\x04`, `\x05`). + +### Entity (`entity`) {#entity} + +Entity представляет собой атомарное скалярное значение, не имеющее никакого собственного содержимого. Сценарии, в которых данный тип может быть полезен, разнообразны. Например, часто `entity` обозначает `null`. При этом `entity` может иметь аттрибуты + +Лексически entity кодируется символом решетки: `#`. + +### Выделенные литералы {#special_literals} + +Специальные токены: +`;`, `=`, `#`, `[`, `]`, `{`, `}`, `<`, `>`, `)`, `/`, `@`, `!`, `+`, `^`, `:`, `,`, `~`. +Не все эти символы используются в YSON, некоторые используются в [YPath](#ypath). + +## Композитные типы {#composite_types} + +### Список (`list`) {#list} + +Задается следующим образом: `[value; ...; value]`, где `value` — литералы произвольных скалярных или композитных типов. + +Пример: `[1; "hello"; {a=1; b=2}]`. + +### Словарь (`map`) {#map} + +Задается следующим образом: `{key = value; ...; key = value}`. Здесь `*key*` — литералы строкового типа, а `value` — литералы произвольных скалярных или композитных типов. + +Пример: `{a = "hello"; "38 parrots" = [38]}`. + +### Атрибуты {#attributes} + +На любой литерал в YSON можно установить **атрибуты**. Записывается это так: `<key = value; ...; key = value> value`. Внутри угловых скобок синтаксис аналогичен словарю. Например, `<a = 10; b = [7,7,8]>"some-string"` или `<"44" = 44>44`. Но чаще всего атрибуты можно встретить на литералах типа `entity`, например, `<id="aaad6921-b5704588-17990259-7b88bad3">#`. + +## Грамматика {#grammar} +YSON-данные бывают трех типов: + 1. **Node** (одно дерево, в примере — `<tree>`) + 2. **ListFragment** (значения, разделенные `;`, в примере — `<list-fragment>`) + 3. **MapFragment** (пары ключ-значение, разделенные `;`, в примере — `<map-fragment>`) + + +Грамматика (определяется с точностью до пробельных символов, которые могут быть в произвольном количестве добавлены и удалены между токенами): +``` + <tree> = [ <attributes> ], <object>; + <object> = <scalar> | <map> | <list> | <entity>; + + <scalar> = <string> | <int64> | <uint64> | <double> | <boolean>; + <list> = "[", <list-fragment>, "]"; + <map> = "{", <map-fragment>, "}"; + <entity> = "#"; + <attributes> = "<", <map-fragment>, ">"; + + <list-fragment> = { <list-item>, ";" }, [ <list-item> ]; + <list-item> = <tree>; + + <map-fragment> = { <key-value-pair>, ";" }, [ <key-value-pair> ]; +<key-value-pair> = <string>, "=", <tree>; % Key cannot be empty +``` + +Символ `;` после последнего элемента внутри `<list-fragment>` и `<map-fragment>` может быть опущен. Следующие конструкции следует считать валидными при чтении: + +#| +|| **C `;` на конце** | **Сокращенная запись** || +|| +``` +<a=b;>c +{a=b;} +1;2;3; +``` +| +``` +<a=b>c +{a=b} +1;2;3 +``` + || +|# + + +## Примеры {#examples} + +- Map (Node) +``` +{ performance = 1 ; precision = 0.78 ; recall = 0.21 } +``` + +- Map (Node) +``` +{ cv-precision = [ 0.85 ; 0.24 ; 0.71 ; 0.70 ] } +``` + + +- List (Node) +``` +[ 1; 2; 3; 4; 5 ] +``` + + +- String (Node) +``` +foobar +``` +``` +"hello world" +``` + +- Int64 (Node) `42` + +- Double (Node) `3.1415926` + +- ListFragment +``` +{ key = a; value = 0 }; +{ key = b; value = 1 }; +{ key = c; value = 2; unknown_value = [] } +``` + +- MapFragment +``` +do = create; type = table; scheme = {} +``` + +- HomeDirectory (Node) +``` +{ home = { sandello = { mytable = <type = table> # ; anothertable = <type = table> # } ; monster = { } } } +``` + +# YPATH {#ypath} + +В данном разделе собрана информация про YPath — язык, описывающий пути к объектам в YSON. + +YPath представляет собой язык описания путей, которые идентифицирует объекты в YSON. Язык позволяет обращаться к узлам и указывать аннотации, которые могут быть полезны при совершении операций над узлами, такими как запись и чтение свойств. + +Например: + +- `/0-25-3ec012f-406daf5c/@type` — путь к атрибуту `type` объекта с идентификатором `0-25-3ec012f-406daf5c`; + +Существует несколько разновидностей YPath. В самом простом случае YPath представляет собой строку, кодирующую путь. + +### Лексика {#simple_ypath_lexis} + +Строка, кодирующая простой YPath, разбивается на следующие **токены**: + +1. **Специальные символы**: прямой слеш (`/`), "собака" (`@`), амперсанд (`&`), звездочка (`*`); +2. **Литералы**: максимальная непустая последовательность неспециальных символов. В литералах разрешен escaping вида `\<escape-sequence>`, где в качестве `<escape-sequence>` может выступать один из символов `\`, `/`, `@`, `&`, `*`, `[`, `{`, а также выражение вида `x<hex1><hex2>`, где `<hex1>` и `<hex2>` — шестнадцатеричные цифры. + +### Синтаксис и семантика {#simple_ypath_syntax} + +Структурно YPath имеет вид `/<relative-path>`. `<relative-path>` разбирается последовательно слева направо, в результате чего возникают шаги перемещения по дереву следующих видов: + +- **Переход к потомку**: последовательность из токена `/` и литерала. + Данный тип шагов применим к словарям и спискам. В случае словаря литерал должен содержать имя потомка. Пример: `/child` — переход к потомку с именем `child`. + В случае списка литерал должен содержать целое число в десятичной системе счисления — номер потомка. Потомки в списке нумеруются с нуля. Разрешены также отрицательные номера, которые нумеруют потомков с конца списка. Примеры: `/1` — переход ко второму потомку в списке, `/-1` — переход к последнему потомку в списке; +- **Переход к атрибуту**: последовательность из токенов `/@` и литерала. + Данный тип шагов применим в любой точке пути и означает переход к атрибуту с данными именем. Пример: `/@attr` — переход к атрибуту с именем `attr`. + +{% note info "Примечание" %} + +В YPath относительные пути начинаются со слешей. Тем самым, слеш служит не разделителем (как в случае файловых систем), а полноправным членом команды перемещения по дереву. В частности, для склейки двух YPath достаточно обычной конкатенации строк. Это свойство может показаться необычным, но во многих местах оно удобно, и к нему достаточно легко привыкнуть. + +{% endnote %} + +### Примеры {#simple_ypath_examples} + +```json +$data = Yson(@@{"0-25-3ec012f-406daf5c" = {a=<why="I can just do it">1;b=2}}@@); +SELECT Yson::SerializeJson($data), Yson::SerializeJson(Yson::YPath($data, "/0-25-3ec012f-406daf5c/a/@/why")); +``` + +**Результат:** + +#| +|| **column0** | **column1** || +|| + +```json +{ + "0-25-3ec012f-406daf5c": { + "a": { + "$attributes": { + "why": "I can just do it" + }, + "$value": 1 + }, + "b": 2 + } +} +``` + +| `"I can just do it"` || +|# + + +```json +$data = Yson(@@{ + a = <a=z;x=y>[ + {abc=123; def=456}; + {abc=234; xyz=789; entity0123 = #}; + ]; + b = {str = <it_is_string=%true>"hello"; "38 parrots" = [38]}; + entity0 = <here_you_can_store=something>#; + } +@@); + +SELECT Yson::ConvertToStringDict(Yson::YPath($data, "/a/@")) AS attrs_root, +Yson::SerializeJson(Yson::YPath($data, "/b/str/@")) AS attrs_b_str, +Yson::SerializeJson(Yson::YPath($data, "/b/str/@/it_is_string")) AS attr_exact, +Yson::SerializeJson(Yson::YPath($data, "/a/0")) as array_index0, +Yson::SerializeJson(Yson::YPath($data, "/a/-1")) as array_last, +Yson::SerializeJson(Yson::YPath($data, "/entity0")) as entity, +Yson::SerializeJson(Yson::YPath($data, "/a/#entity0123/abc")) as entity1, +Yson::SerializeJson(Yson::YPath($data, "/a")) AS whole_a, +Yson::SerializeJson($data) AS whole_data; +``` + +**Результат:** + +#| +|| **attrs_root** | **attrs_b_str** | **attr_exact** | **array_index0** | **array_last** | **entity** | **entity1** | **whole_a** | **whole_data** || +|| + +```json +{ + "a": "z", + "x": "y" +} +``` + +| + +```json +{ + "it_is_string": true +} +``` + +| + +```json +true +``` + +| + +```json +{ + "abc": 123, + "def": 456 +} +``` + +| + +```json +{ + "abc": 234, + "entity0123": null, + "xyz": 789 +} +``` + +| + +```json +{ + "$attributes": { + "here_you_can_store": "something" + }, + "$value": null +} +``` + +| + +```json +null +``` + +| + +```json +{ + "$attributes": { + "a": "z", + "x": "y" + }, + "$value": [ + { + "abc": 123, + "def": 456 + }, + { + "abc": 234, + "entity0123": null, + "xyz": 789 + } + ] +} +``` + +| + +```json +{ + "a": { + "$attributes": { + "a": "z", + "x": "y" + }, + "$value": [ + { + "abc": 123, + "def": 456 + }, + { + "abc": 234, + "xyz": 789 + } + ] + }, + "b": { + "38 parrots": [ + 38 + ], + "str": { + "$attributes": { + "it_is_string": true + }, + "$value": "hello" + } + } +} +``` +|| +|# + + + + + + diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/yson.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/yson.md index 568aa59fa6b..5fd6331e78e 100644 --- a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/yson.md +++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/yson.md @@ -10,6 +10,12 @@ * В текстовом представлении вместо запятых — точки с запятой, а вместо двоеточий — равно; * Поддерживается концепция «атрибутов», то есть именованных свойств, которые могут быть присвоены узлу в дереве. +{% note tip %} + +Подробнее формат YSON описан [здесь](../../types/yson.md) + +{% endnote %} + Особенности реализации и функциональность модуля: * Наравне с YSON данный модуль поддерживает и стандартный JSON, что несколько расширяет область его применения. |