Tanner B
Tanner B

Reputation: 25

MarkLogic Query Based Views: Constructing dynamic columns

This question has come up from an existing question here on a use case I am facing with my TDE and Optic plan setup: MarkLogic Optic API: Dynamic update support for Template View Configuration

I have the following field in my template view configuration for Table MyTable and Schema MyView:

<column>
   <name>currentDateTime</name>
   <scalar-type>dateTime</scalar-type>
   <val>fn:current-dateTime()</val>
   <nullable>true</nullable>
   <invalid-values>ignore</invalid-values>
</column>

I am attempting to create a Query-Based View equivalent of this column to have this value update dynamically everytime an optic plan is run against this view, but am having trouble with the current documentation MarkLogic has available.

I create the Query Based View with the following query below outlined in the documentation and insert it the XML output as a document into my Schemas database:

op:from-view("MyTable", "MyView")
   => op:select(("currentDateTime"))
   => op:generate-view("DataHub", "myQBV")

However when I query against this new view, the dateTime timestamp remains static and does not update dynamically.

Here is my optic query:

let $QBV := op:from-view("DataHub", "myQBV")
return $QBV
 =>op:select((op:view-col("myQBV", "currentDateTime")))
 =>op:result()

Is there an extra step I must setup to get the currentDateTime value to update dynamically after an optic plan?

I am persisting the QBV XML as a user with the data-view-admin role.

Upvotes: 1

Views: 299

Answers (2)

John Snelson
John Snelson

Reputation: 958

You want to do something like this:

op:from-view("MyTable", "MyView")
   => op:bind-as("currentDateTime",ofn:current-dateTime())
   => op:generate-view("DataHub", "myQBV")

The query based view needs to add a new generated column using op:bind-as(). This will then be executed at runtime, and give you the date and time of execution (rather than the date and time of indexing).

Upvotes: 2

Andrew Wanczowski
Andrew Wanczowski

Reputation: 383

The dynamic field should be configured as part of your select or bind statement using the op:as or op:bind-as call. This will ensure that the evaluation of the current date time happens at query time instead of index time.

op:select(op:as("currentDateTime", ofn:current-dateTime()))
op:bind-as("currentDateTime",ofn:current-dateTime())

While this is possible to do in the dynamic view it may not be the most performant. Be sure to profile some of your queries that will leverage this field.

Optic As Function: https://docs.marklogic.com/op:as

Optic Guide: https://docs.marklogic.com/10.0/guide/app-dev/OpticAPI

XQuery Libraries Required for Expression Functions : https://docs.marklogic.com/10.0/guide/app-dev/OpticAPI#id_94816

Upvotes: 5

Related Questions