Skip to main content

Getting Started with Optic

To Update Document Metadata

You can update a document's metadata without updating the document itself.

We received the list of employees to place in our new departments:

Integration:

  • Engineering: Brandy Pace

  • Marketing: Thomas Shaner

  • R&D: Sage Sutton

  • Sales: Eric Molina

  • Training: Roseann Seals

Attrition:

  • Engineering: Claude Ashe

  • Marketing: Mary Lewin

  • R&D: Richard Kemble

  • Sales: Juana Levenson

  • Training: Michael Troxel

To add these employees to their temporary departments, we will add them to collections representing those departments. That way, we do not have to change the employee documents themselves.

An Optic update like this one searches for the employee documents containing each last name then uses the found documents' URIs to update the collections for each document:

declareUpdate();
const op = require('/MarkLogic/optic');

const Integration = ['Pace', 'Shaner', 'Sutton', 'Molina', 'Seales'];
const Attrition = ['Ashe', 'Lewin', 'Kemble', 'Levenson', 'Troxel'];
const collection = 'https://example.com/content/employee';

const integrationDescriptors = op.fromDocUris(cts.andQuery([
  cts.collectionQuery(collection),
  cts.jsonPropertyValueQuery("Surname", Integration)
]))
.bind(op.as("collections", [collection, "https://example.com/content/department/Integration"]))
.result();

const attritionDescriptors = op.fromDocUris(cts.andQuery([
  cts.collectionQuery(collection),
  cts.jsonPropertyValueQuery("Surname", Attrition)
]))
.bind(op.as("collections", [collection, "https://example.com/content/department/Attrition"]))
.result();

op.fromDocDescriptors(integrationDescriptors.toArray().concat(attritionDescriptors.toArray()))
  .write()
  .result();

We used this update to update the collections associated with the 10 employee documents, adding the new collection for the relevant new department.

This update has three main parts:

  1. Creating a row sequence containing one column for the URIs of the 5 Integration employees' documents and another column for their 2 collections, employee and Integration:

    • The constant Integration is an array containing the surnames of the employees to be added to the Integration Department.

    • The constant collection contains the employee collection URI, which all 10 employees currently belong to and should continue belonging to after this update is executed.

    • The constant integrationDescriptors contains a 5-row x 2-column row sequence: one row for each employee to be added to Integration. Each row contains the column that fromDocUris() naturally produces and the additional column, collections, containing both the employee collection and the Integration collection:

      • The Data Accessor Function fromDocUris() produces a row for each document with the column uri containing document URIs:

        • The CTS Function cts.andQuery() returns the intersection of matches that each of its parameter functions finds:

          • cts.collectionQuery() finds all the data from documents in the specified collection, our employee collection.

          • cts.jsonPropertyValueQuery() finds all the data--including the URI--for documents whose Surname property matches each of the last names in the Integration array.

        • With these CTS functions as parameters, fromDocUris() produces 5 rows with the uri column containing the URIs found for the employee collection documents containing the 5 specified surnames of the employees to add to the Integration collection.

      • The Operator Function bind() uses as() to define an additional column, collections, to hold both the current collection, employee, and the new collection, Integration, for each row in turn.

      • The Executor Function result() executes the update and returns the 5-row x 2-column row sequence.

  2. Creating a row sequence containing one column for the URIs of the 5 Attrition employees' documents and another column for their 2 collections, employee and Attrition. This part is a repeat of the first part with Attrition instead of Integration.

  3. Writing these two row collections, converted to a single array, which adds the proper new collections to the proper employee documents:

    • The Data Accessor Function fromDocDescriptors() creates a 10-row x 2-column row sequence, one column holding the URIs of the 10 employee documents to update, and the other column holding the collections to update them with:

      • toArray() converts a row sequence into an array.

      • concat() concatenates a second parameter to the first of the same type.

      • fromDocDescriptors() then uses the array to produce a row sequence with just the uri and collections columns for the 10 employee documents whose collections need to be updated.

    • The Operator Function write() writes just the data provided in the specified columns--in this case, just collections--to the document specified by uri.

    • The Executor Function result() executes the update and returns the 10-row x 2-column row sequence.

    • Before executing this update, you can check that it will affect only the metadata you choose for only the documents you choose by commenting out write(). The resulting update returns the rows that fromDocDescriptors() accesses.

Here are row 5 and row 6 from the 10-row x 2-column result, one row to represent an employee document for each new collection:

{
    "collections": [
    "https://example.com/content/employee", 
    "https://example.com/content/department/Integration"
  ], 
  "uri": "/data/employees/58fdfd5b-2956-4c7f-a888-8875ff659752.json"
}
{
    "collections": [
    "https://example.com/content/employee", 
    "https://example.com/content/department/Attrition"
  ], 
  "uri": "/data/employees/67ba986d-af98-49ee-b731-5b230853ad53.json"
}
  • To add metadata like collections and permissions, you must include all collections for the document in the collections column and all permissions for the document in the permissions column of fromDocDescriptors(). write() replaces the existing metadata rather than appending what is provided to what is already there.