Searching for Assets in Tenovos

This source file includes a function runKeywordSearch() that performs the following steps:

  • Prepares an authorized HTTP request to perform an Asset Keyword Search.
  • Submits the API request and receives a response.
  • Extracts the search result from the response.
  • Returns the search result.

Requirements

  • The following properties must be included in the function’s request parameter:
    • endpointUrl
    • apiKey
    • Authorization
  • Optional request properties:
    • search - Search query object. The included properties will override the default properties provided by this function.
  • Populate the search request body properties:
    • excludes: (Optional) List of properties, using dot-notation, to exclude from the result set to minimize the amount of data returned.
    • from: 0-based offset of first Asset to return from search result.
    • filters: Array of Search Filters to constrain the search results.
      • Format: '("Dropdown Attribute Name":”Value”)'
    • limit: Number of Assets to return starting from the from index position of the search result. (Max: 100)
    • searchTerm: Array of search terms.
    • sortBy: Asset property or sortable Metadata Attribute used to sort search results.
    • metadataDefinitionSearchField: createdEpoch | lastUpdatedEpoch |
    • order: asc | desc

Constraints

  • The user account used to obtain the auth token must have access to the Metadata Template applied to the asset. Access Templates when applied may revoke this.
  • The user account used to obtain the auth token must be part of a user group that has the Apply Security Template permission on the Security Template being used.
  • Results are paginated using the from property in your request. The maximum number of search results is limited to 10,000 .

Process

The sequence diagram below shows the typical process to search for assets using keywords and/or filters within Tenovos using the REST API.

Customerauth/tokensearch/keywordGet TokensReturn TokensPerform keyword search operationReturn Search ResultsCustomerauth/tokensearch/keyword

Code Example

The below example assumes use of the HTTP Utility and that you have a valid token returned from the authentication service, as described in Getting Started with Authentication and HTTP Utility

service/asset-search.js

Copy
Copied
    const HttpUtil = require('./util/http');
    const AssetSearchConfig = require('../config/asset-search');
    const runKeywordSearch = async (request) => {
    // Extract Parameters from Request
    const { endpointUrl, apiKey, authorization, search } = request;

    // Prepare Request Body
    const body = {
    from: 0,
    searchTerm: ['*'],
    sortBy: [
        {
        metadataDefinitionSearchField: 'createdepoch',
        order: 'desc',
     },
   ],
   operation: 'AND',
   limit: 50,
   filters: [],
   excludes: [
     'technicalMetadataDocument',
     'metadataDocument.text_content',
   ],
 };
 // Override Default Search with Custom Search Parameters
 if (search) {
   Object.assign(body, search);
 }
 // Get Body Content Length
 const bodyLength = Buffer.byteLength(JSON.stringify(body));

 // Prepare HTTP Request
 const httpRequest = {
   method: 'POST',
   url: `${endpointUrl}/search/keyword`,
   headers: {
     Accept: 'application/json',
     Authorization: authorization,
     'Content-Length': bodyLength,
     'Content-Type': 'application/json',
     'x-api-key': apiKey,
   },
   body,
 };
 // Send HTTP Request, Get HTTP Result
 const result = await HttpUtil.sendHttpRequest(httpRequest);
 // Extract Search Result from HTTP Result
 const searchResult = result.body;
 // Return Search Result
 return searchResult;
};

/**
* @description Retrieve Assets given an Array of Asset Search Requests.
* Iterate over all Search Results and aggregate Assets into a unique Array of Assets.
* Return the unique Asset Array.
* @param {{assetSearches, requestContext}} request
* @returns {Promise<Array>} Array of Assets
*/
const runAssetSearches = async (request) => {
 const { assetSearches, requestContext } = request;
 const assetMap = {};
 // Validate Parameters
 if (!(Array.isArray(assetSearches) && assetSearches.length)) {
   throw new Error('assetSearches must be a non-empty Array');
 }
 if (!requestContext) {
   throw new Error('Missing requestContext');
 }
 // Loop to Search for Assets and Aggregate in a Map to Prevent Duplicates
 for (let i = 0; i < assetSearches.length; i += 1) {
   const assetSearch = assetSearches[i];
   // Get Search Parameters
   const { searchTerm } = assetSearch;
   // Start from Asset 0
   let searchIndex = 0;
   const searchResultLimit = AssetSearchConfig.common.SEARCH_RESULT_LIMIT;
   // Search for Assets using Search Terms
   while (searchIndex >= 0) {
     // Prepare Search Request
     const search = {
       from: searchIndex,
       limit: searchResultLimit,
       searchTerm,
     };
     const searchRequest = {
       ...requestContext,
       search,
     };
     // Run Asset Search
     // eslint-disable-next-line no-await-in-loop
     const searchResult = await runKeywordSearch(searchRequest);
     // Loop to Add Search Result Assets to Map
     searchResult.result.forEach((asset) => {
       const { objectId } = asset;
       // Add Asset to Map
       assetMap[objectId] = asset;
     });
     // If Current Result Hit Count Equal to Batch Size, Get Next Search Result Page
     if (searchResult.hitCount === searchResultLimit) {
       searchIndex += searchResultLimit;
     } else {
       // Else Stop Searching
       searchIndex = -1;
     }
   }
 }
 const assets = [];
 // Convert Asset Map to Array
 Object.values(assetMap).forEach((asset) => {
   assets.push(asset);
 });
 // Return Assets
 return assets;
};
module.exports = {
 runKeywordSearch,
 runAssetSearches,
};