JSON.SET
JSON.SET — это команда (функция) языка запросов Redis, предназначенная для установки или обновления значения JSON-документа, хранящегося по указанному ключу в модуле RedisJSON. Команда относится к классу операций записи (write) и позволяет модифицировать как весь документ, так и его отдельные части, используя JSONPath-выражения.
История
Команда JSON.SET была введена в составе модуля RedisJSON, который впервые появился в Redis версии 4.0 (выпущен в 2018 году) как экспериментальный модуль. Разработка модуля велась компанией Redis Labs (ныне Redis Ltd.) с целью расширения функциональности Redis для работы с документами в формате JSON. Официальная стабильная версия RedisJSON 1.0 была выпущена в 2019 году. В Redis Stack (начиная с версии 6.2, 2021 год) модуль RedisJSON стал частью стандартной поставки, что сделало JSON.SET доступной без дополнительной установки.
Синтаксис
Команда имеет следующий синтаксис:
`` JSON.SET key path value [NX | XX] ``
Параметры
- key — ключ, под которым хранится JSON-документ (строка). Если ключ не существует, будет создан новый.
- path — JSONPath-выражение, указывающее на часть документа, которую требуется установить. По умолчанию используется корневой путь
$. - value — значение, которое будет записано. Должно быть корректным JSON-значением (строка, число, объект, массив,
true,false,null). В команде передаётся как строка в формате JSON. - NX — необязательный модификатор. Если указан, операция выполняется только при условии, что ключ не существует (создание нового документа). Если ключ уже существует, команда возвращает
nil. - XX — необязательный модификатор. Если указан, операция выполняется только при условии, что ключ уже существует (обновление существующего документа). Если ключ не существует, команда возвращает
nil.
Возвращаемое значение
- При успешном выполнении — строка
OK. - Если условие
NXилиXXне выполнено —nil.
Принцип работы
Команда JSON.SET оперирует в рамках модуля RedisJSON, который хранит JSON-документы в бинарном формате, оптимизированном для быстрого доступа и модификации. При вызове команды Redis парсит переданное значение как JSON, проверяет его корректность, затем применяет заданный JSONPath к текущему документу (если ключ существует) и заменяет соответствующую часть документа новым значением. Если путь указывает на несуществующий элемент, он может быть создан (за исключением случаев, когда путь ведёт к несуществующему родительскому объекту — в таких случаях команда вернёт ошибку).
Примеры использования
- Создание нового документа:
`` JSON.SET user:1 $ '{"name": "Иван", "age": 30}' ` Результат: OK. По ключу user:1` сохранён JSON-объект.
- Обновление существующего поля:
`` JSON.SET user:1 $.age 31 ` Результат: OK. Поле age` изменено с 30 на 31.
- Добавление нового поля:
`` JSON.SET user:1 $.city '"Москва"' ` Результат: OK. В объект добавлено поле city со значением "Москва"`.
- Использование модификатора NX:
`` JSON.SET user:2 $ '{"name": "Петр"}' NX ` Если ключ user:2 не существует — создаётся документ. Если существует — возвращается nil`.
- Использование модификатора XX:
`` JSON.SET user:1 $.name '"Анна"' XX ` Если ключ user:1 существует — поле name обновляется. Если нет — возвращается nil`.
Ограничения и особенности
- Размер значения: Максимальный размер JSON-документа, который можно сохранить, ограничен параметром
proto-max-bulk-len(по умолчанию 512 МБ в Redis 7.0+). Однако на практике рекомендуется не превышать несколько мегабайт для оптимальной производительности. - Глубина вложенности: RedisJSON поддерживает документы глубиной до 128 уровней (по умолчанию). Превышение этого лимита приводит к ошибке.
- Типы данных: Поддерживаются все стандартные типы JSON: объекты, массивы, строки, числа, логические значения и
null. Числа могут быть целыми (64-битные) или с плавающей точкой (двойной точности). - JSONPath: RedisJSON использует собственную реализацию JSONPath, которая поддерживает синтаксис, схожий с XPath для XML. Поддерживаются фильтры, подстановки и рекурсивные обходы (например,
$..). Однако полная поддержка стандарта JSONPath (RFC 9535) не гарантируется — некоторые расширенные конструкции могут работать иначе. - Атомарность: Команда
JSON.SETвыполняется атомарно в рамках одной операции Redis. Однако она не является транзакционной в смысле ACID — при сбое сервера между операциями может произойти частичная запись, если используется несколько команд. - Кодировка: Все строки в JSON-документе должны быть в кодировке UTF-8. Redis не выполняет перекодировку.
Применение
Команда JSON.SET широко используется в приложениях, где требуется хранить и модифицировать структурированные данные в Redis, например:
- Кэширование веб-страниц и API-ответов — позволяет сохранять сложные JSON-ответы и обновлять их частично без перезаписи всего документа.
- Управление сессиями пользователей — хранение профилей, настроек и состояния в виде JSON-объектов.
- Обработка событий и логов — запись структурированных данных в реальном времени.
- Конфигурационные системы — хранение иерархических конфигураций с возможностью точечного обновления.
- Игровая индустрия — сохранение состояния игровых объектов, инвентаря, характеристик персонажей.
Сравнение с другими командами
| Команда | Назначение | Отличия |
|---|---|---|
JSON.SET | Установка/обновление значения по пути | Позволяет модифицировать часть документа, поддерживает JSONPath |
JSON.GET | Чтение значения по пути | Только чтение, возвращает JSON-строку |
JSON.DEL | Удаление части документа по пути | Удаляет элемент, а не заменяет его |
SET (стандартная) | Установка строкового значения | Не поддерживает JSON-структуру, работает только с целыми строками |
Критика и ограничения
- Отсутствие схемы: RedisJSON не поддерживает схемы валидации JSON (например, JSON Schema). Любое корректное JSON-значение может быть записано, что может привести к несоответствиям в данных.
- Производительность при больших документах: Частичное обновление глубоко вложенных структур может быть медленнее, чем работа с плоскими ключами, из-за необходимости парсинга JSONPath и модификации бинарного представления.
- Сложность отладки: Ошибки в JSONPath-выражениях (например, неверный синтаксис) могут приводить к неожиданным результатам или ошибкам, которые сложно диагностировать без специальных инструментов.
- Зависимость от модуля: Для использования
JSON.SETтребуется установленный модуль RedisJSON, что не всегда доступно в облачных или управляемых сервисах Redis (хотя большинство крупных провайдеров, таких как AWS ElastiCache и Azure Cache for Redis, поддерживают его).
Альтернативы
В экосистеме Redis существуют и другие способы работы с JSON-данными:
- Хранение в виде строки — использование стандартной команды
SETс сериализованным JSON. Минус: отсутствие частичного обновления. - Модуль RediSearch — позволяет индексировать JSON-документы и выполнять полнотекстовый поиск, но не предоставляет команд для прямого манипулирования структурой.
- Внешние библиотеки — например, использование клиентских библиотек (redis-py, node-redis) для сериализации/десериализации JSON на стороне приложения.
Источники
- Redis Documentation — JSON.SET command (Redis Ltd.)
- RedisJSON Module — Official Repository and README (Redis Ltd.)
- Redis Stack Documentation — Working with JSON (Redis Ltd.)
- Redis in Action by Josiah L. Carlson (Manning Publications, 2013) — общие принципы работы с Redis
- Redis 7.0 Release Notes — изменения в модуле RedisJSON
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →