Loading TOC...
Getting Started With MarkLogic Server (PDF)

Getting Started With MarkLogic Server — Chapter 3

Getting Started with MarkLogic Server-Side JavaScript

This section describes the following procedures to get started creating and querying documents using JavaScript in MarkLogic:

About Query Console

Query Console is an interactive web-based query tool that is bundled with MarkLogic. Query Console enables you to write ad-hoc queries and view the results without using .sjs or .xqy files. You can view the results as formatted (Auto) or in plain-text (Raw) output. Query Console is designed for a modern web browser with JavaScript support.

Many of the examples in this document assume you are using Query Console. To learn more about Query Console, see the Query Console Walkthrough in the Query Console User Guide

JavaScript Examples

This section walks you through creating some simple documents in JavaScript and contains the following parts:

Create a Simple JSON Document

To create a simple document and query it, perform the following steps:

  1. Go to the following URL (substitute your hostname if MarkLogic is not running on your local machine):

    http://localhost:8000/

  2. When prompted, enter a username and password. The user should have the admin role (you can use the same user created when you installed MarkLogic).
  3. Optionally, in Query Console, create a new workspace. This will make it easier to come back to later.
  4. To create a JavaScript object and return the results, enter the following in the query text area of Query Console:
    const obj = {key1:"value1", key2:"value2"};
    obj;

    Click the Run button. You will see the object serialized in the results pane.

  5. To create a document, enter the following in the query text area of Query Console:
    declareUpdate();
    const obj = {key1:"value1", key2:"value2"};
    xdmp.documentInsert("/simple.json", obj);

    Click the Run button. You will see your query response was empty in the results pane. But what actually happened is you created a document in the database. The declareUpdate() function is required everytime your program includes an update to the database (otherwise an exception is thrown--try it).

  6. Look at the document you just created by entering the following in the query text area of Query Console:
    cts.doc("/simple.json");

    Click the Run button. You will see the JSON document you created in the results pane.

  7. To see the key1 property, enter the following and then click the Run button:
    cts.doc("/simple.json").root.key1;

    You will see the value for the key1 property (value1) in the results pane. Note that cts.doc returns a document node, so you first have to navigate to the root to get to the JSON node, and then you can navigate to the key1 property.

Creating and Searching Documents

To create some documents and then perform some searches against them, perform the following steps:

  1. In Query Console, run the following:
    // create some documents to search over
    declareUpdate();
    const phrase1 = "The quick brown fox jumps over the lazy dog.";
    const fox = {fox: phrase1};
    const phrase2 = "The huge white elephant walked in the mud.";
    const elephant = {elephant: phrase2};
    const phrase3 = "The fast electric car drove down the highway.";
    const car = { car: phrase3};
    const obj1 = { fox: {colors:["brown", "red", "yellow"],
                       actions:["jump", "sleep", "eat"]} ,
                elephant: {colors:["brown", "white", "green"],
                       actions:["blow horn", "sleep", "eat", "walk"]},
                car: {colors:["brown", "red", "yellow", "green", "grey"],
                       actions:["speed", "drive", "stop", "accelerate"]}
               };
    const col = "my-phrases";
    const perms = [xdmp.permission("qconsole-user", "read"),
                 xdmp.permission("qconsole-user", "update")];
    xdmp.documentInsert("/fox.json", fox, perms, col);
    xdmp.documentInsert("/elephant.json", elephant, perms, col);
    xdmp.documentInsert("/car.json", car, perms, col);
    xdmp.documentInsert("/stuff.json", obj1, perms, col);
  2. Click the Explore button in query console. You should see the four new documents you just created. You can click on them to see their contents.
  3. Now in another Query Console buffer, run the following:
    // find all documents with the word "the" in the "my-phrases"
    // collection and count them
    let count = 0;
    const results = new Array();
    for (const result of cts.search(
           cts.andQuery(["the", cts.collectionQuery("my-phrases")]))) {
      count++;
      results.push(result); };
    results.push(fn.concat("Count = ", count));
    results;

    This returns the following array:

    [
     {"car":"The fast electric car drove down the highway."}, 
     {"fox":"The quick brown fox jumps over the lazy dog."},
     {"elephant":"The huge white elephant walked in the mud."}, 
     "Count = 3"
    ]
  4. Now in another Query Console buffer, run the following:
    // find all documents in the "my-phrases" collection 
    // with the word "car" and count them
    let count = 0;
    const results = new Array();
    for (const result of cts.search(cts.andQuery([
            cts.collectionQuery("my-phrases"),
            cts.wordQuery("car")])) ) {
      count++;
      results.push(result); };
    results.push(fn.concat("Count = ", count));
    results;

    This returns the following array:

    [
     {"car":"The fast electric car drove down the highway."},
     "Count = 1"
    ]
  5. Try changing some of the values in the cts.collectionQuery or the cts.wordQuery to see what different results you get.
  6. Now in another Query Console buffer, run the following:
    // find all documents with the word "car" and count them
    let count = 0;
    const results = new Array();
    for (const result of fn.collection() ) {
      let res = result.root.car;
      let x = res;
      count++;
      results.push(x); };
    results.push(fn.concat("Count = ", count));
    results;

    This returns the following array:

    [
     "The fast electric car drove down the highway.", 
     null, null, 
     {"colors":["brown", "red", "yellow", "green", "grey"],
      "actions":["speed", "drive", "stop", "accelerate"]}, 
     "Count = 4"
    ]
  7. A simpler way to find the number of documents with the word car in it is to perform the following:
    cts.estimate("car");

    This is an estimate of the number of documents that match the query, which means it is the number of documents that the indexes indicate are a match. For many searches, this will be accurate. For details about search, see the Search Developer's Guide.

  8. You can also use the jsearch API to perform the search as follows:
    import * as jsearch from '/MarkLogic/jsearch.mjs';
    jsearch.documents()
      .where([cts.collectionQuery('my-phrases'), cts.wordQuery('car')])
      .map({snippet: true})
      .result();

    This returns two objects, the first is the HTTP header and the second contains the response from the endpoint, which contains a report detailing what matches the search.

    {"results":
      [{"score":108544, 
        "fitness":0.670031011104584, 
        "uri":"/car.json", 
        "path":"fn:doc(\"/car.json\")", 
        "confidence":0.497606456279755, 
        "index":0,
        "matches":
          [{"path":"fn:doc(\"/car.json\")/text(\"car\")",
            "matchText":
              ["The fast electric ", {"highlight":"car"}, 
               " drove down the highway."]
            }]
      }], 
     "estimate":1
    }

    For details about jsearch, see jsearch API Documentation and Creating JavaScript Search Applications in the Search Developer's Guide.

This is just a very brief introduction to how you can search in documents. For information about the search functionality possible in MarkLogic, see the Search Developer's Guide.

Module Programs and Other Considerations

This section walks you through some Javascript changes that are implemented with a view towards improving Javascript performance:

Converting Scripts to Modules

Evaluating a JavaScript program may generate side-effects on the JavaScript global environment; therefore, each JavaScript program is evaluated in a separate v8 context. The overhead of creating such a context is significant, and in the recent v8 version that overhead has increased by roughly 40%.

To compensate for this overhead, it is suggested that you convert your Javascript scripts to Javascript modules. A Javascript module program is one that adheres to the following:

  1. A program that uses strict JavaScript syntax and can be compiled as a JavaScript module.
  2. A program that contains a main module with .mjs extension.
  3. Is any adhoc program that uses import or export syntax.

For further reading on the details of converting script programs into module programs, please see our Javascript Reference Guide.

New Mimetype for Javascript Modules

In order to support Javascript module programs, a new server mimetype has been created. All module URIs must conform to the new mimetype:

  • name: application/vnd.marklogic-js-module
  • Extension: mjs

You may view this new mimetype by navigating to the Admin UI and selecting the Mimetypes from the explorer pane.

The extension for a module URI in the import statement may be omitted. When the module URI in an import statement doesn't contain an extension, an extension mapping to any of the above MIME types must be added to resolve the specified module. For example:

import { square, diag } from 'lib/top'; // map to lib/top.js or lib/top.mjs

« Previous chapter
Next chapter »