Этот вопрос возник из существующего здесь вопроса о сценарии использования, с которым я столкнулся при настройке плана TDE и Optic: MarkLogic Optic API: поддержка динамического обновления для конфигурации представления шаблона
У меня есть следующее поле в конфигурации представления шаблона для таблицы MyTable
и схемы MyView
:
<column>
<name>currentDateTime</name>
<scalar-type>dateTime</scalar-type>
<val>fn:current-dateTime()</val>
<nullable>true</nullable>
<invalid-values>ignore</invalid-values>
</column>
Я пытаюсь создать представление на основе запросов, эквивалентное этому столбцу, чтобы это значение обновлялось динамически каждый раз, когда оптический план запускается для этого представления, но у меня возникли проблемы с текущей доступной документацией MarkLogic.
Я создаю представление на основе запросов со следующим запросом, описанным ниже в документации, и вставляю его вывод XML в виде документа в мою базу данных схем:
op:from-view("MyTable", "MyView")
=> op:select(("currentDateTime"))
=> op:generate-view("DataHub", "myQBV")
Однако, когда я запрашиваю это новое представление, временная метка dateTime остается статической и не обновляется динамически.
Вот мой оптический запрос:
let $QBV := op:from-view("DataHub", "myQBV")
return $QBV
=>op:select((op:view-col("myQBV", "currentDateTime")))
=>op:result()
Есть ли дополнительный шаг, который я должен настроить, чтобы значение currentDateTime
динамически обновлялось после оптического плана?
Я сохраняю QBV XML как пользователь с ролью data-view-admin.
Динамическое поле должно быть настроено как часть оператора select или bind с помощью вызова op:as или op:bind-as. Это гарантирует, что оценка текущей даты и времени происходит во время запроса, а не во время индекса.
op:select(op:as("currentDateTime", ofn:current-dateTime()))
op:bind-as("currentDateTime",ofn:current-dateTime())
Хотя это возможно сделать в динамическом представлении, это может быть не самым эффективным. Обязательно профилируйте некоторые из ваших запросов, которые будут использовать это поле.
Оптика как функция: https://docs.marklogic.com/op:as
Руководство по оптике: https://docs.marklogic.com/10.0/guide/app-dev/OpticAPI
Библиотеки XQuery, необходимые для функций выражений : https://docs.marklogic.com/10.0/guide/app-dev/OpticAPI#id_94816
возможно ли расширение bind-as() для выполнения вычислений? Как можно было бы добавить следующее calucation к вашему bind-as? fn:floor((fn:current-dateTime() - xs:dateTime(./updateDate)) div xs:dayTimeDuration('P1D'))
Да, вы можете использовать произвольные выражения в op:bind-as(). Каждый вызов функции должен использовать отличающийся вызов функции, а не немедленно выполняемую версию (т. е.: ofn:floor(), а не fn:floor()). Вы также можете использовать op:call() для вызовов функций и такие вещи, как op:subtract() и op:divide() для операторов. docs.marklogic.com/op:call docs.marklogic.com/op:subtract docs.marklogic.com/op:divide
Вы хотите сделать что-то вроде этого:
op:from-view("MyTable", "MyView")
=> op:bind-as("currentDateTime",ofn:current-dateTime())
=> op:generate-view("DataHub", "myQBV")
Представление на основе запроса должно добавить новый сгенерированный столбец с помощью op:bind-as(). Затем это будет выполнено во время выполнения и даст вам дату и время выполнения (а не дату и время индексации).
возможно ли расширение bind-as() для выполнения вычислений? fn:floor((fn:current-dateTime() - xs:dateTime(./updateDate)) div xs:dayTimeDuration('P1D'))
Вам нужен отложенный вызов fn:current-dateTime(), то есть он должен запускаться во время выполнения запроса, а не во время создания QBV. Это означает, что вам нужно будет использовать ofn:current-dateTime().