This chapter describes how to use the MarkLogic built-in functions, and describes how to import and use XQuery libraries in your JavaScript program. It includes the following sections:
MarkLogic contains many built-in functions that offer fast and convenient programmatic access to MarkLogic functionality. The built-in functions are available as JavaScript functions without the need to import or require any libraries (that is why they are called built-in). You can find the functions in the Server-Side JavaScript API Documentation.
The functions are available via the following global objects:
for example, to get the current time, you can call the following:
fn.currentDateTime();
There are MarkLogic-specific functions that are part of the global JavaScript object (without a namespace prefix). This section calls out the following global functions:
In order to perform an update to a document, you must declare the transaction as an update; if declareUpdate
is not called at the beginning of a statement, the statement is run as a query. The following is the syntax of the declareUpdate
function (see Global-Object.declareUpdate
):
declareUpdate(Object options)
where options
is an optional argument as follows:
{explicitCommit: true/false}
If the options
argument is omitted or explicitCommit
property is set to false
, the transaction is automatically committed. If the explicitCommit
property is set to true
, then it starts a multi-statement transaction and requires an explicit xdmp.commit or xdmp.rollback to complete the transaction.
For details on transactions, see Understanding Transactions in MarkLogic Server in the Application Developer's Guide.
The following is an example of an update transaction in JavaScript:
declareUpdate(); const myDoc = {"foo":"bar"}; xdmp.documentInsert("/myDoc.json", myDoc); // creates the /myDoc.json document
The following runs as a multi-statement transaction (although this transaction only has a single statement):
declareUpdate({explicitCommit: true}); const myDoc = {"foo":"bar"}; xdmp.documentInsert("/myDoc.json", myDoc); xdmp.commit(); // creates the /myDoc.json document
The require
function (see Global-Object.require
) is available in the global object, and it allows you to import a library into your JavaScript program. For details, see require Function.
You can import XQuery library modules into a Server-Side JavaScript program and then call those functions and/or variables from JavaScript. Importing XQuery libraries is useful if you have existing XQuery code that you want to use in your JavaScript programs, and it is also useful if you want to perform a task that is well-suited to XQuery from your JavaScript Program. This section describes how to use XQuery modules with your JavaScript programs and includes the following parts:
You can import an XQuery or JavaScript library by using the following JavaScript function:
require(String location)
where location
is the path to the JavaScript or XQuery file. The extension of the path can be omitted for simplicity. The path obeys the same rules for XQuery defined in Rules for Resolving Import, Invoke, and Spawn Paths in the Application Developer's Guide.
Typically, the require
function is the first line of the JavaScript program, and a program can have 0 or more require
functions. When importing an XQuery library, a common practice is to name your JavaScript variable as you would name your namespace prefix. For example, if you are importing the Search API library, your require statement might look as follows:
const search = require("/MarkLogic/appservices/search/search.xqy"); search.search("hello"); // returns a search response for documents matching "hello"
MarkLogic has a rich set of XQuery library modules to make it easy to write programs to do a variety of things, such as building a search application, building an alerting application, adding spelling correction to your application, and so on. You might have created your own rich sets of XQuery libraries. There might be something (such as an XPath statement) that is convenient to write in XQuery but might be less convenient to write in JavaScript.
You can make use of these XQuery libraries in MarkLogic Server-Side JavaScript programs by using the require
function. This section describes the mapping of names and types from an XQuery environment to a JavaScript environment and includes the following parts:
In XQuery, it is common to create function and variable names with hyphens (-) in them; in JavaScript, a hyphen (-) is a subtraction operator, so the names are not compatible. In JavaScript, camelCase is a common way to name functions and variables. To deal with these differences between the languages, any XQuery function or variable imported to a JavaScript program with the require
function is accessible according to the following rules:
my-function
is available to JavaScript with the name myFunction
. hello:my-world
(that is, a function bound to the hello
prefix with the local name my-world
) can be accessed with the following JavaScript notation: hello["my-world"]()
.You can use these rules to access any public XQuery function or variable from your JavaScript program.
JavaScript has looser typing rules that XQuery, and also has fewer types than XQuery. MarkLogic automatically maps types from XQuery to JavaScript. The following table shows how XQuery types are mapped to JavaScript types.
You can use the require
function to import a Server-Side JavaScript library into a Server-Side JavaScript program. When you import a JavaScript library using the require
function, all of the functions and global variables in the JavaScript library are available via the exports
object, which is returned by the require
function. For example:
const circle = require("circle.js"); circle.area(4); // evaluates the area function from circle.js, // passing 4 as its parameter
You can import JavaScript libraries with either the .js
or .sjs
extension (with corresponding mimetypes application/javascript
and application/vnd.marklogic-javascript
). You cannot, however, serve up directly from the App Server a Server-Side JavaScript module with a .js
file extension; directly served modules need a .sjs
extension. For more details about the require function, see require Function.
There are a number of MarkLogic objects available in JavaScript to make it easier to work with nodes and documents in JavaScript. For details on these objects, see MarkLogic JavaScript Object API.
You can create amped functions in JavaScript. An amped function is a function that evaluates with amplified privileges based on the role to which an amp is configured. Amps require a function that is in the Modules database or under the <marklogic-dir>/Modules directory, as well as a piece of configuration (the amp) in the security database. For details on amps, see Temporarily Increasing Privileges with Amps in the Security Guide. This section describes JavaScript amps and includes the following parts:
The module.amp function has the following signature:
module.amp(Function namedFunction)
It must be used in an exports statement that is in a JavaScript module that is in the Modules database or is under the <marklogic-dir>/Modules directory. A sample exports statement is as follows:
exports.ampedFunctionName = module.amp(ampedFunctionName);
where ampedFunctionName
is the name of the function in your library to be amped.
Use the import.meta.amp() function to amp with ES6 modules. Use the style shown in the following sample statement:
export function fileExists(filename) { xdmp.filesystemFileExists(filename); } export const fileExistsAmped = import.meta.amp(fileExists);
The following creates a JavaScript module for an amp, creates an amp to reference the module, and then calls the function from another module. The result is that the function can be run by an unprivileged user, even though the function requires privileges.
/opt/MarkLogic/test-amp.sjs
(you will need to make sure the file is readable by MarkLogic):// This is a simple amp module // It requires creating an amp to the URI of this sjs file with the // function name. function ampedInsert() { xdmp.documentInsert("/amped.json", {prop:"this was produced by an \n\ amped function"}, [xdmp.permission("qconsole-user", "read"), xdmp.permission("qconsole-user", "update")]); }; exports.ampedInsert = module.amp(ampedInsert);
ampedInsert
), leave the namespace blank, enter the path to the JavaScript module (for example, /test-amp.sjs
), select filesystem for the database, and finally assign it a role to which the function amps. For this example, sect the admin
role. declareUpdate(); const mod = require("/test-amp.sjs"); mod.ampedInsert();
/space/appserver/test.sjs
, and your App Server root on port 8005 is /space/appserver
, then access http://localhost:8005/test.sjs
. You can create an unprivileged user in the Admin Interface by creating a user without giving it any roles.
You can then go to Query Console and see that it created the document called /amped.json
.
This example is simplified from a real-world example in two ways. First, it places the amped module under the Modules directory. The best practice is to use a modules database to store your amped function. Note that when using a modules database, you need to insert the module into that database with the needed permissions on the document. Second, the example amps to the admin
role. In a real-world example, it is best practice to create a role that has the minimal privileges needed to perform the functions that users with the role require.
There are MarkLogic-specific constructors added to the JavaScript environment to allow you to construct XQuery types in JavaScript. The constructors have the same names as their XQuery counterparts, but with a dot (.) instead of a colon(:) to separate the namespace from the constructor name. For constructors that have a minus sign (-) in them, you will have to put square brackets around the local name to call it (for example, cts['complex-polygon']
).
To use each constructor, pass a constructible object into the constructor. The following example shows how to use the xs.QName
constructor:
fn.namespaceUriFromQName(xs.QName("xdmp:foo")) => http://marklogic.com/xdmp (because the xdmp namespace is always in scope)
The following is a list of MarkLogic constructors that you can call from JavaScript.
xs.simpleDerivationSet xs.gYear xs.public xs.language xs.short xs.decimal xs.reducedDerivationControl xs.gYearMonth xs.date xs.double xs.nonPositiveInteger xs.positiveInteger xs.blockSet xs.normalizedString xs.namespaceList xs.gMonth xs.integer xs.int xs.anyAtomicType xs.gMonthDay xs.NCName xs.unsignedShort xs.derivationControl xs.IDREFS xs.derivationSet xs.token xs.ID xs.nonNegativeInteger xs.anyURI xs.NMTOKEN xs.allNNI xs.QName xs.base64Binary xs.boolean xs.long xs.Name xs.yearMonthDuration xs.duration xs.NMTOKENS xs.dayTimeDuration xs.negativeInteger xs.NOTATION xs.unsignedInt xs.unsignedLong xs.untypedAtomic xs.formChoice xs.dateTime xs.float xs.ENTITY xs.byte xs.time xs.unsignedByte xs.ENTITIES xs.string xs.IDREF xs.hexBinary xs.gDay cts.andNotQuery cts.andQuery cts.boostQuery cts.box cts.circle cts.collectionQuery cts.collectionReference cts.complexPolygon cts.confidenceOrder cts.directoryQuery cts.documentFragmentQuery cts.documentOrder cts.documentQuery cts.elementAttributePairGeospatialQuery cts.elementAttributeRangeQuery cts.elementAttributeReference cts.elementAttributeValueQuery cts.elementAttributeWordQuery cts.elementChildGeospatialQuery cts.elementGeospatialQuery cts.elementPairGeospatialQuery cts.elementQuery cts.elementRangeQuery cts.elementReference cts.elementValueQuery cts.elementWordQuery cts.falseQuery cts.fieldRangeQuery cts.fieldReference cts.fieldValueQuery cts.fieldWordQuery cts.fitnessOrder cts.geospatialElementAttributePairReference cts.geospatialElementChildReference cts.geospatialElementPairReference cts.geospatialElementReference cts.geospatialJsonPropertyChildReference cts.geospatialJsonPropertyPairReference cts.geospatialJsonPropertyReference cts.geospatialPathReference cts.indexOrder cts.jsonPropertyChildGeospatialQuery cts.jsonPropertyGeospatialQuery cts.jsonPropertyPairGeospatialQuery cts.jsonPropertyRangeQuery cts.jsonPropertyReference cts.jsonPropertyScopeQuery cts.jsonPropertyValueQuery cts.jsonPropertyWordQuery cts.linestring cts.locksFragmentQuery cts.longLatPoint cts.lsqtQuery cts.nearQuery cts.notInQuery cts.notQuery cts.order cts.orQuery cts.pathGeospatialQuery cts.pathRangeQuery cts.pathReference cts.period cts.periodCompareQuery cts.periodRangeQuery cts.point cts.polygon cts.propertiesFragmentQuery cts.punctuation cts.qualityOrder cts.query cts.reference cts.region cts.registeredQuery cts.reverseQuery cts.scoreOrder cts.searchOption cts.similarQuery cts.space cts.special cts.termQuery cts.token cts.tripleRangeQuery cts.trueQuery cts.unordered cts.uriReference cts.word cts.wordQuery dir.type math.coefficients sem.iri sem.variable sem.blank