Открыть сервис

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 к текущему документу (если ключ существует) и заменяет соответствующую часть документа новым значением. Если путь указывает на несуществующий элемент, он может быть создан (за исключением случаев, когда путь ведёт к несуществующему родительскому объекту — в таких случаях команда вернёт ошибку).

Примеры использования

  1. Создание нового документа:

`` JSON.SET user:1 $ '{"name": "Иван", "age": 30}' ` Результат: OK. По ключу user:1` сохранён JSON-объект.

  1. Обновление существующего поля:

`` JSON.SET user:1 $.age 31 ` Результат: OK. Поле age` изменено с 30 на 31.

  1. Добавление нового поля:

`` JSON.SET user:1 $.city '"Москва"' ` Результат: OK. В объект добавлено поле city со значением "Москва"`.

  1. Использование модификатора NX:

`` JSON.SET user:2 $ '{"name": "Петр"}' NX ` Если ключ user:2 не существует — создаётся документ. Если существует — возвращается nil`.

  1. Использование модификатора 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 →