Вставить в JSON, используя JSONiq

Мы пишем запрос JSONiq, чтобы вставить новые свойства в JSON и вернуть обновленный JSON из запроса.

Запрос:

jsoniq version "1.0";
let $users := {
  "name" : "Deadbeat Jim",
  "address" : "1 E 161st St, Bronx, NY 10451",
  "risk tolerance" : "high"
} 
insert json {"status" : "credit card declined"} into $users
return $users

users содержит ввод json, мы пытаемся добавить еще одно свойство с помощью команды вставки JSONiq, как указано в документации по JSONiq здесь

Мы получаем ниже исключения:

java.lang.RuntimeException: (no URI):13,1: static error [err:XPST0003]: invalid expression: syntax error, unexpected expression (missing comma "," between expressions?)

Вопросы:

  1. Является ли запрос правильным? если нет, то как сделать так, чтобы это было синтаксически / логически правильно?
  2. Есть ли хорошие онлайн-ресурсы для JSONiq с примерами?

2 ответа

Решение

Вот еще несколько объяснений:

Работа обновлений JSONiq идентична работе обновлений XQuery. Обновления JSONiq являются декларативными: программа обновлений JSONiq в дополнение к пустой последовательности в модели данных возвращает то, что называется списком ожидающих обновлений (PUL), который представляет собой список обновлений (удаления, замены, переименования, вставки и т. Д.) применяться к некоторым документам.

Обновление JSONiq имеет семантику моментальных снимков, что означает, что при оценке основного выражения побочные эффекты не возникают. Вместо этого, после того, как PUL был вычислен, механизм может распространить изменения, указанные PUL, в основное хранилище (такое как файл на диске или хранилище документов).

Синтаксически правильная версия примера вопроса будет выглядеть так:

jsoniq version "1.0";
let $users := {
  "name" : "Deadbeat Jim",
  "address" : "1 E 161st St, Bronx, NY 10451",
  "risk tolerance" : "high"
} 
return insert json {"status" : "credit card declined"} into $users

Однако в этом случае возвращаемый PUL содержит изменения в отношении объекта JSON, созданного на лету в памяти. Время жизни этого объекта - только время оценки запроса, так что эта программа просто не имеет видимого эффекта.

Если collection Функция каким-то образом сопоставлена ​​с базой данных в хранилище документов, таком как Couchbase или MongoDB (то есть, если механизм задокументирован и настроен для этого), следующий запрос семантически применяет обновление к этому хранилищу документов.

jsoniq version "1.0";
let $users := collection("users")[$$.name eq "Jim"]
return insert json {"status" : "credit card declined"} into $users

Выражение copy-modify-return (также называемое выражением transform, как в XQuery, см. Другой ответ на этой странице) обеспечивает способ применения изменений в памяти без их потери и без постоянного хранения. Это:

  • создает объект JSON (как копию другого) или узел XML и т. д.
  • модифицирует этот объект, применяя PUL, полученный из выражения модификации (важно: это не имеет видимых побочных эффектов, так как изменяется только копия)
  • вернуть s измененную копию.

Для опытных пользователей: в этом случае предложение copy содержит конструктор, который создает свежий объект, поэтому оптимизатор может фактически пропустить копирование.

Это способ заставить его работать с помощью JSONiq. Нам нужно использовать предложения copy-modify-return:

jsoniq version "1.0";
copy $users := {
      "name" : "Deadbeat Jim",
      "address" : "1 E 161st St, Bronx, NY 10451",
      "risk tolerance" : "high"
} 
modify insert json {"status" : "credit card declined"} into $users
return $users

Надеюсь, что это может быть полезным для кого-то

Другие вопросы по тегам