В MarkLogic Server реализован собственный диалект XQuery, который называется XQuery 1.0-ml. Не трудно догадаться, что это — тот самый XQuery 1.0 с некоторыми дополнениями от MarkLogic, призванными сделать жизнь разработчика лучше. В спецификации говорится, что данные изменения делают XQuery более пригодным для программирования приложения. Посмотрим на дополнения XQuery, описанные в спецификации MarkLogic Server 6.0 (http://docs.marklogic.com/6.0/guide/xquery.pdf)
Объявляется используемый диалект следующей директивой
xquery version "1.0-ml";
По умолчанию используется именно он, но также существует возможность использовать XQuery 1.0, разместив следующую директиву в начале модуля
xquery version "1.0";
Список улучшений XQuery 1.0-ml по мнению MarkLogic
1. Выражения try/catch
2. Отображение функции (Function Mapping)
3. Точка с запятой как разделитель транзакций
4. Приватные функции и переменные
5. Функции с побочным эффектом «Side эффектом»
6. Сокращенный предикат позиционирования
7. Конструктор бинарных объектов
8. Выражение validate as
9. Опции сериализации
10. Импорт XSLT стилей в модели XQuery
11. Семантика определяемая реализацией
Рассмотрим чуть более подробно каждый пункт
1. Выражения try/catch
Данное выражение дает возможность отлавливать исключения во время исполнения XQuery и адекватно на них реагировать
try {
код генерирующий исключение
} catch ($exception) {
реакция на исключение
}
Переменная $exception, как и все в MarkLogic Server — это XML описывающий исключение по которому можно натравить, например XPath, и вытащить интересующие данные, либо же сделать все то, что можно сделать с XML внутри MarkLogic Server.
И только три «особых» исключения нельзя поймать таким способом — XDMP-CANCELED, SVC-CENCELER и XDMP-DISABLED
.
2. Отображение функции (Function Mapping)
" Function Mapping" — это выражение, которое позволяет вам передавать последовательный набор (sequence) элементов, как параметр функции, НО! обработка каждого элемента в последовательности производится отдельно. Это значит, что на каждый элемент последовательности будет вызвана функция обработчик, и ей в виде параметра будет передан один элемент.
«Function Mapping» — это аналог иттерационной обработки массива элементов в цикле for. Естественно с некоторыми исключениями
xquery version "1.0-ml";
declare function local:print-word ($word as xs:string) { $word };
local:print-word( ("hello", "world") )
Данный код распечатает текст «helloworld». Функция local:print-word будет вызванна дважды, для каждого элемента.
В следующем выражении мы получим интересный результат
xquery version "1.0-ml";
(1,2) * (3,4)
результат (3, 4, 6, 8). В данном случает, также работает «Function Mapping», и результатом становятся результаты последовательного перемножения чисел.
Особое внимание стоит уделить результатам вызова таких функций, которым становится последовательность из результатов вызова функции для каждого элемента. Стоит отметить, что при вызове функции с пустой последовательностью
local:print-word( () )
результатом функции станет — (), что и следовало ожидать, но, при этом, сама функция не будет вызвана ни разу. Об этом стоит помнить.
«Function Mapping» доступен в MarkLogic server по умолчанию, но существует возможность принудительно отключить или включить его. Делается это следующим образом
Включение:
declare namespace xdmp="http://marklogic.com/xdmp";
declare option xdmp:mapping "true";
Выключение:
declare namespace xdmp="http://marklogic.com/xdmp";
declare option xdmp:mapping "false";
3. Точка с запятой — как разделитель транзакций
В Xquery 1.0-ml вы можете добавить символ ";" после одного или нескольких XQuery выражений, и это будет означать, что код, расположенный до этого символа, будет выполняться в одной транзакции, а все инструкции, расположенные после этого символа, будут выполнять в другой (следующей) транзакции. По умолчанию весь запрос к MarkLogic Server выполняется в одной транзакции, и при откате восстанавливаются все данные, измененные в этом запросе. Разделитель транзакций позволяет разбить запрос к MarkLogic Server на части, в случае если он очень сложный.
Также следует помнить, что новая версия документа не доступна из той транзакции, из которой он был изменен.
4. Приватные функции и определение переменных
При реализации библиотек вы можете запереть некоторые функции или переменные внутри модуля, сделав их приватными и не доступными из других библиотек. Делается это следующим образом
declare private function ....
declare private variable ....
Стоит отметить, что функции и переменные из «main» модуля по определению являются приватными, поэтому «private» справедливо только для библиотечных модулей.
5. Функции с побочным эффектом «Side эффектом»
Спецификация XQuery говорит о том, что функции могут только возвращать значение вместо вызова, и не допускается никаких побочных изменений из тела функции в данных. MarkLogic Server имеет много улучшений, которые противоречат спецификации XQuery и вызывают изменения данных помимо результата функций. Примером такого эфекта является изменение документа в базе данных, которое не только возвращает результат, но и меняет данные.
«Side эффект» очень часто используется при создании приложений, именно поэтому MarkLogic Server имеет много функций которые создают «Side эффект».
Пример таких функций
• xdmp:set
• Функции обновления (xdmp:document-load, xdmp:node-insert, и т.п.)
• Функции управления (xdmp:merge, Admin library, xdmp:shutdown, и т.п.)
6. Сокращенный предикат позиционирования
MarkLogic Server имеет сокращенный предикат позифионирования элементов в последовательности. Так, чтобы получить первые три элемента последовательности в XQuery 1.0-ml нужно выполнить
xquery version "1.0-ml";
(1, 2, 3, 4, 5, 5)[1 to 3]
а в XQuery 1.0
xquery version "1.0";
(1, 2, 3, 4, 5, 5)[fn:position() = (1 to 3)]
7. Конструктор бинарных объектов
XQuery 1.0-ml расширяет расширяет XQuery 1.0, вводя тип бинарных данных, который используется для сохранения бинарных документов. Для поддержки нового типа вводится конструктор бинарных данных «binary» и функция проверки типа binary(), которая может использоваться в конструкциях типа «typeswitch».
8. Выражение validate as
Еще одним нововведением является выражение «validate as», которое можно применять для указания типа в выражении «validate».
xquery version "1.0-ml";
validate as xs:boolean { <foo>{fn:true()}</foo> }
В принципе, это не такое уж и нововведение XQuery 1.0-ml. Аналогичную проверку в XQuery 1.0 можно сделать следующим образом
xquery version "1.0";
declare namespace xdmp="http://marklogic.com/xdmp";
(# xdmp:validate-type xs:boolean #) { <foo>{fn:true()}</foo> }
9. Опции сериализации
Опции сериализации можно указывать в XQuery, используя директиву «declare option».
10. Импорт XSLT стилей в модели XQuery
В XQuery 1.0-ml вы можете импортировать XSLT стили в модуль XQuery, и при этом получаете доступ ко всем функциям и переменным, объявленным в XSLT модуле.
Импортирование XSLT
xquery version "1.0-ml";
import stylesheet at "/path-to-stylesheet.xsl";
11. Семантика определяемая реализацией
Спецификация XQuery содержит набор пунктов, которые могут быть реализованы по разному в разных реализациях XQuery.
1. Предопределенные пространства имен.
Каждая реализация XQuery содержит свой набор пространств имен, которые можно использовать не импортируя его явно. Например, «fn:» является одним из таких пространств.
2. Внешние переменные
Внешними называются переменные, которые могут быть использованы из внешнего модуля. Пример объявления такой переменной
xquery version "1.0-ml";
declare namespace my="myNamespace";
declare variable $my:variable as xs:string* external;
fn:concat("The value of $my:variable is: ", $my:variable)
Устанавливать значение такой переменной могут функции xdmp:invoke, xdmp:eval, xdmp:spawn или через XCC.
>xquery version "1.0-ml";
declare namespace my="myNamespace";
xdmp:invoke("/extvar.xqy", (xs:QName("my:variable"), "my value"))
Использование таких переменных
The value of $my:variable is: my value
3. Параметры сортировки
Имена, параметры сортировки, а также параметры по умолчанию для каждой реализации XQuery индивидуальны. Для более подробной информации следует обратиться к «Search Developer’s Guide»
4. XQuery типы определяемые реализацией
MarkLogic Server расширяет XQuery дополнительными типами и функциями для взаимодействия с ними. Эти типы не являются обязательными в спецификации XQuery, но жизнь с ними становится лучше, и, поэтому, они присутствуют в MarkLogic Server.
Некоторые новые типы
•cts:query (с моножеством подтипов таких как cts:word-query, cts:element-query, и т.п.)
• map:map
• cts:region (с подтипами cts:box, cts:circle, cts:polygon, и cts:point)
• json:object
• json:array
• json:unquotedString
5. Точность десятичных дробей
MarkLogic Server не имеет настроек для ограничения точности десятичных дробей. Десячитные числа имеют точность не мение 18 десятичных цифр.
6. Пространство имен модуля является пространствоим его функций по умолчанию.
Пространство имен по умолчанию для модуля является и пространством имен по умолчанию для всех функций, расположенных внутри этого модуля. Это означает, что вы можете объявлять функции внутри модуля без явного указания их префикса (простанства имен).
Автор: SleepwalkerOne