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:
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 thatfromDocUris()
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 columnuri
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 whoseSurname
property matches each of the last names in theIntegration
array.
With these CTS functions as parameters,
fromDocUris()
produces 5 rows with theuri
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()
usesas()
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.
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.
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:The Operator Function
write()
writes just the data provided in the specified columns--in this case, justcollections
--to the document specified byuri
.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 thatfromDocDescriptors()
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 thepermissions
column offromDocDescriptors()
.write()
replaces the existing metadata rather than appending what is provided to what is already there.