All MarkLogic requests run in either query or update mode, based on a static analysis of the code. The mode is important, because query requests are able to run without locking database content. Accidentally running in update mode is a common cause of requests running slower than expected.
Verify that a MarkLogic statement is running in query mode.
Applies to MarkLogic versions 7+
Place this snippet as early in the code path as you can to make sure it is executed before MarkLogic spends too much time on other parts of your request.
let $assert-query-mode as xs:unsignedLong := xdmp:request-timestamp()
If a request that includes this line is run as an update, then this error will be thrown:
XDMP-AS: (err:XPTY0004) let $assert-query-mode as xs:unsignedLong := xdmp:request-timestamp() -- Invalid coercion: () as xs:unsignedLong
Sometimes MarkLogic’s static analysis may see something that triggers update mode, even if that was not the developer’s intent. The code in this recipe will throw an exception if it is run as an update, making it easy to notice the problem. Once this problem has been seen, find the code that caused the statement to run as an update. If the statement really should be running as an update, remove the assertion. If the update can be removed or isolated into an
xdmp:invoke() call, do that to allow the statement to run as a query. Using this function, we can specify the “different-transaction” option, causing the update to be separated from the main request.
See the Transaction Type section of the Application Developer’s Guide for more information about query or update modes.
It’s important to see that we can’t just call
xdmp:request-timestamp() and get the same effect. The magic is in the
as xs:unsignedLong — because that clause is present, MarkLogic will expect the value to be an unsigned long, or convertible to one. If the code returns the empty sequence, the conversion can’t happen, and the error is thrown.
The name is important too, in order to be self-documenting. What we don’t want to happen is that a developer runs into this exception and realizes that it can be “fixed” by removing the
as xs:unsignedLong, or by changing it to
as xs:unsignedLong? (making it optional). The presence of the word “assert” in the name provides a clue that we’re expecting something here, and silencing the message would be contrary to the original developer’s intent.