---
metadata:
  - name: generator
    content: Diplodoc Platform v5.57.3
alternate:
  - https://ydb-platform--ydb.viewer.diplodoc.com/en/concepts/query_execution/json_search.md
  - https://ydb-platform--ydb.viewer.diplodoc.com/ru/concepts/query_execution/json_search.md
  - href: https://ydb-platform--ydb.viewer.diplodoc.com/ru/concepts/query_execution/json_search.md
    type: text/markdown
    title: Markdown version
  - href: https://ydb-platform--ydb.viewer.diplodoc.com/ru/llms.txt
    type: text/markdown
    title: llms.txt
sourcePath: ru/core/concepts/query_execution/json_search.md
---
> **Documentation Index:** Fetch the complete configuration index at https://ydb-platform--ydb.viewer.diplodoc.com/ru/llms.txt

# Поиск по содержимому JSON-документов

Поиск по JSON — это способ находить строки таблицы по содержимому JSON-документа, хранящегося в колонке типа `Json` или `JsonDocument`: по существованию пути в документе и по значению, расположенному в указанном пути. Путь задаётся выражением [JsonPath](https://ydb-platform--ydb.viewer.diplodoc.com/ru/yql/reference/builtins/json.md#jsonpath), а проверки выполняются уже существующими функциями [JSON_EXISTS](https://ydb-platform--ydb.viewer.diplodoc.com/ru/yql/reference/builtins/json.md#json_exists) и [JSON_VALUE](https://ydb-platform--ydb.viewer.diplodoc.com/ru/yql/reference/builtins/json.md#json_value). Типичные сценарии:

* поиск документов с определённым вложенным полем;
* поиск документов, у которых поле по заданному пути равно нужному значению;
* фильтрация полуструктурированных данных без заранее зафиксированной схемы.

В YDB поиск по JSON можно выполнять двумя основными способами:

* без индекса — сканированием таблицы и применением функций `JSON_EXISTS` / `JSON_VALUE` к каждой строке. Подход прост, но плохо масштабируется: объём работы по сканированию растёт вместе с размером таблицы.
* с JSON-индексом — созданием [JSON-индекса](https://ydb-platform--ydb.viewer.diplodoc.com/ru/dev/json-indexes.md) по JSON-колонке. Этот подход предназначен для масштабируемого поиска.

## Поиск по JSON с JSON-индексом {#json-search-index}

Ключевая идея [JSON-индекса](https://ydb-platform--ydb.viewer.diplodoc.com/ru/dev/json-indexes.md) — построение [инвертированного индекса](https://ru.wikipedia.org/wiki/Инвертированный_индекс) по путям и парам «путь + значение». Каждый путь JSON-документа (а для проверок равенства — и скалярное значение по этому пути) кодируется в токен. Для каждого токена в индексе хранится список значений первичного ключа соответствующих строк таблицы. Запросы к индексу сводятся к инвертированному поиску по этим токенам — по той же схеме, что и у [полнотекстового индекса](https://ydb-platform--ydb.viewer.diplodoc.com/ru/dev/fulltext-indexes.md#basic), но с собственным токенизатором JSON.

JSON-индекс не хранит копию JSON-документа целиком, а раскладывает его на отдельные токены:

* для каждого пути в JSON-дереве создаётся токен «путь существует»;
* если путь ведёт к скалярному значению (строке, числу, логическому значению или `null`), дополнительно создаётся токен «путь + значение».

Массивы при этом прозрачны: элементы массива индексируются под тем же путём, что и сам массив, поэтому индекс одинаково отвечает на запросы к `$.items`, `$.items[0]` и `$.items[*]`.

Например, для документа:

```json
{
    "id": 42042,
    "name": "Michael",
    "email": null,
    "items": [null, "str"],
    "parts": {
        "key": "k1",
        "value": false
    }
}
```

концептуально индексируются следующие токены (без учёта специфики внутреннего представления):

| Токен | Что позволяет найти |
|---|---|
| `$` | документ не равен `NULL` |
| `$.id` / `$.id == 42042` | путь `id` существует / равен `42042` |
| `$.name` / `$.name == "Michael"` | путь `name` существует / равен `"Michael"` |
| `$.email` / `$.email == null` | путь `email` существует / равен `null` |
| `$.items` / `$.items == null` / `$.items == "str"` | путь `items` существует / содержит элемент `null` / содержит элемент `"str"` |
| `$.parts` | путь `parts` существует |
| `$.parts.key` / `$.parts.key == "k1"` | вложенный путь существует / равен `"k1"` |
| `$.parts.value` / `$.parts.value == false` | вложенный путь существует / равен `false` |

JSON-индекс позволяет:

* находить строки по существованию пути через [JSON_EXISTS](https://ydb-platform--ydb.viewer.diplodoc.com/ru/yql/reference/builtins/json.md#json_exists);
* находить строки по значению в пути через [JSON_VALUE](https://ydb-platform--ydb.viewer.diplodoc.com/ru/yql/reference/builtins/json.md#json_value) или фильтр-предикат внутри `JSON_EXISTS`.

При выполнении запроса JSON-индекс может быть автоматически задействован [оптимизатором](https://ydb-platform--ydb.viewer.diplodoc.com/ru/concepts/glossary.md#optimizer). Достаточно написать обычное условие `WHERE` с выражениями `JSON_EXISTS` / `JSON_VALUE` по индексированной JSON-колонке — оптимизатор распознает такой предикат и применит чтение по JSON-индексу вместо перебора записей исходной таблицы. Кроме того, JSON-индекс, как и любой другой [вторичный индекс](https://ydb-platform--ydb.viewer.diplodoc.com/ru/concepts/glossary.md#secondary-index), можно принудительно задействовать, указав его имя в секции `VIEW IndexName`.

Если предикат не удаётся превратить в обращение к индексу, поведение YDB зависит от того, был ли в запросе явно указан требуемый JSON-индекс:

* при автоматическом выборе индекса оптимизатором запрос просто выполняется без ускорения индексом (результат остаётся корректным);
* при явном указании индекса через выражение `VIEW` возвращается ошибка.

Подробнее см. [VIEW (JSON-индекс)](https://ydb-platform--ydb.viewer.diplodoc.com/ru/yql/reference/syntax/select/json_index.md).

Дополнительная информация:

* [JSON-индексы](https://ydb-platform--ydb.viewer.diplodoc.com/ru/dev/json-indexes.md) — обзор возможностей, поддерживаемых предикатов и ограничений.
* [Функции для работы с JSON](https://ydb-platform--ydb.viewer.diplodoc.com/ru/yql/reference/builtins/json.md) — справка по `JSON_EXISTS`, `JSON_VALUE` и языку JsonPath.
* [VIEW (JSON-индекс)](https://ydb-platform--ydb.viewer.diplodoc.com/ru/yql/reference/syntax/select/json_index.md) — синтаксис запросов с JSON-индексом.
