JSON-индекс — быстрый старт

В этом руководстве показано, как создать JSON-индекс и выполнять запросы с использованием функций JSON_EXISTS и JSON_VALUE в YDB.

Создайте таблицу и JSON-индекс

CREATE TABLE documents (
    id Uint64,
    payload JsonDocument,
    PRIMARY KEY (id),
    INDEX json_idx GLOBAL USING json ON (payload)
);

Тип колонки JsonDocument хранит JSON в компактном бинарном формате и предпочтителен для индексируемой колонки. Альтернативно может использоваться тип Json (текстовое представление).

Первичный ключ таблицы должен состоять из единственной колонки целочисленного типа (Uint64, Uint32, Int64 или Int32) — это текущее ограничение реализации JSON-индексов.

Добавьте тестовые данные

UPSERT INTO documents (id, payload) VALUES
    (1, JsonDocument(@@{"user": {"id": 100, "name": "Alice"}, "active": true}@@)),
    (2, JsonDocument(@@{"user": {"id": 101, "name": "Bob"}, "active": false}@@)),
    (3, JsonDocument(@@{"user": {"id": 102, "name": "Charlie"}, "archived": true}@@));

Здесь конструкция @@...@@ — это многострочный строковый литерал, удобный для записи JSON без экранирования кавычек. Функция JsonDocument(...) преобразует текст в значение типа JsonDocument.

Фильтр по наличию пути в документе

Функция JSON_EXISTS проверяет, существует ли в документе путь, заданный выражением JsonPath.

SELECT id
FROM documents VIEW json_idx
WHERE JSON_EXISTS(payload, '$.user.id');

Результат:

id
1
2
3

Для поиска по индексу используется токен пути $.user.id. Индекс возвращает результат без сканирования основной таблицы.

Отбор строк с конкретным значением поля документа

Функция JSON_VALUE извлекает скалярное значение по JsonPath; для использования индекса обязательно нужно указать тип возвращаемого значения в секции RETURNING:

SELECT id
FROM documents VIEW json_idx
WHERE JSON_VALUE(payload, '$.user.name' RETURNING Utf8) = "Alice"u;

Результат:

id
1

При проверке равенства в индекс попадает токен «путь + значение» ($.user.name = "Alice"), что обеспечивает наивысшую селективность.

Комбинация условий

Несколько вызовов JSON_EXISTS / JSON_VALUE на одной индексированной JSON-колонке можно объединять операторами AND и OR:

SELECT id
FROM documents VIEW json_idx
WHERE JSON_EXISTS(payload, '$.user.id')
  AND JSON_VALUE(payload, '$.active' RETURNING Bool);

Результат:

id
1

Подробнее