Skip to main content

Information model and API

Indices#

AIH Search v1.0#

The following endpoints are available for Indices in AIH Search v1.0:

Indices

AIH Search v1.1#

The following endpoints are available in AIH Search v1.1:

Indices

Standard Indices#

There are several standard indices with built-in mappings in Search API:

  • aih-risks - Risks and their related objects, such as mitigations, risk assessment results, techniques, population items and relationships
  • aih-deviations - Deviations and their related objects, such as risks, main systems and equipment
  • aih-equipment - Equipment and their related objects, such as plants, main systems, organizations, design objects and deviations
  • aih-main-systems - Main systems and their related objects, such as plants, organizations, equipment and deviations
  • aih-channels - Channels and their related objects, such as main systems, channel availabilities, data origins and also structure node references
  • aih-work-items - Work items and their related objects, such as resources, activities, deviations and primary assets
  • aih-structure-node-reference - Objects which have structure node reference, such as risks, deviations, channels, equipment and activities
  • activity-inputs - There are 3 indices for activity inputs. They all contain activities and asset references linked with the activity. The difference between the 3 indices is only in the value field type
    • aih-activity-date-inputs - Activity inputs which have format date
    • aih-activity-number-inputs - Activity inputs which have format integer or decimal
    • aih-activity-text-inputs - All other inputs
  • aih-plants - Plants and their related main systems
  • aih-main-system-objects - Design objects in main system and their related structure nodes
  • aih-activities - Activities and their related objects, such as deviations, main systems and equipment

Standard indices are synchronized daily and additionally updated by AIH events to maintain data consistency.


Custom Index#

The Search API v1.1 gives an opportunity to create custom indices. To upload the DLL file and create the index, the following endpoint is used:

Indices

  • Name
  • DisplayName
  • ObjectOwnerId - if the field is not set, objectOwner will be the current user
  • TriggerSchedule - the schedule for updating the index (how often this job will run)
  • File - a DLL file that contains the relevant data for the index

The following endpoint is used to update the custom index:

PUT /Indices

{  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",  "name": "string",  "displayName": "string",  "objectOwner": {    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",    "name": "string"  },  "triggerSchedule": "string",  "type": "custom"}

The type field cannot be updated as it determines whether the index is custom or standard.

Note : For standard indices, only objectOwner field can be updated.

The following endpoint is used to update the custom index DLL file:

PUT /Indices/{id}/File

Indices

The following endpoint is used to delete the custom index:

DELETE /Indices/{id}

  • An index cannot be deleted if it is not a custom index.

Create Custom Index#

The following NuGet package is required to create a custom index:

  • AIH.Search.Abstractions

The class that creates the index must inherit from the CustomIndexBase generic abstract class, and its constructor must contain 2 parameters (first: ICustomServiceProvider, second: ILogger).

  • CustomIndexBase - generic abstract class included in the AIH.Search.Abstractions NuGet package (Version >= 6.0.10).
  • ICustomServiceProvider - used to get services through dependency injection. It only returns AIH ReadOnly SDK clients (IReadOnlyAssetsClient, IReadOnlyQualityClient, etc.).
  • ILogger - Represents a type used to perform logging. The logs will be added to the Search API logs.

Note: Only AIH.Search.Abstractions NuGet package and AIH SDK Clients NuGet packages are allowed to be installed.

Note : The default maximum number of fields that can be added to the custom index is 5000.

Code Example#

This is a code example that creates an index with a mapping and some data.

using AIH.Quality.Clients.v1_0;using AIH.Search.Abstractions;using AIH.Search.Abstractions.CustomServiceProvider;using Microsoft.Extensions.Logging;using OpenSearch.Client;
namespace Example{    public class CreateSomeIndex : CustomIndexBase<SomeIndex>    {        private readonly IReadOnlyQualityClient _qualityClient;
        public CreateSomeIndex(ICustomServiceProvider customServiceProvider, ILogger logger) : base(customServiceProvider, logger)        {            _qualityClient = customServiceProvider.GetRequiredService<IReadOnlyQualityClient>();        }
        public override TypeMappingDescriptor<object> GetMappingDescriptor()        {            var typeMappingDesctiptor = new TypeMappingDescriptor<object>();
            return typeMappingDesctiptor                        //The alwaysShow meta specifies the fields that should be displayed in FE by default                        .Meta(x => x.Add("alwaysShow", new List<string>() { "name", "createdDate" }))                        .Properties<SomeIndex>(ps => ps.Keyword(x => x.Name(x => x.Id).Meta(a => a.Add("displayName", "Id")))                            .Keyword(x => x.Name(x => x.Name).Fields(f => f.Text(t => t.Name("asText"))).Meta(a => a.Add("displayName", "Name")))                            .Date(x => x.Name(x => x.CreatedDate).Meta(a => a.Add("displayName", "Created date")))
                        #region Object owner
                            //The isIdentity meta indicates that the field is an objectOwner name and can be used as "equal to me (myTeams)".                            .Object<Reference>(o => o.Name(x => x.ObjectOwner)                                .Properties(ps => ps.Keyword(x => x.Name(x => x.Id).Meta(a => a.Add("displayName", "Id")))                                    .Keyword(x => x.Name(x => x.Name).Fields(f => f.Text(t => t.Name("asText"))).Meta(a => a.Add("displayName", "Name").Add("isIdentity", "true")))))
                        #endregion
                        #region Nested property
                            .Nested<NestedProp>(x => x.Name(a => a.NestedProps)                                .Properties(ps => ps.Keyword(x => x.Name(x => x.Name).Fields(f => f.Text(t => t.Name("asText"))).Meta(a => a.Add("displayName", "Name")))                                    .Keyword(x => x.Name(x => x.Value).Fields(f => f.Text(t => t.Name("asText"))).Meta(a => a.Add("displayName", "Value"))))));
                        #endregion        }
        public override async Task<IEnumerable<SomeIndex>> GetEntriesAsync(CancellationToken cancellationToken)        {            var entries = new List<SomeIndex>();
            var deviations = await _qualityClient.DeviationsGetAsync(take: 10, cancellationToken: cancellationToken);
            if (deviations.Any())            {                foreach (var deviation in deviations)                {                    entries.Add(new SomeIndex                    {                        Id = deviation.Id.Value,                        Name = deviation.ReferenceId,                        CreatedDate = deviation.CreatedDate,                        Status = (Status?)deviation.Status,
                        ObjectOwner = new()                        {                            Id = deviation.ObjectOwner.Id,                            Name = deviation.ObjectOwner.Name,                        },
                        NestedProps = deviation.Properties.Select(p => new NestedProp                        {                            Name = p.Name,                            Value = p.Value?.ToString(),                        }).ToList()                    });                }
                //The logs will be added to the Search API logs                _logger.LogInformation("Custom index log: The list of deviations is not empty.");            }            else            {                for (int i = 0; i < 10; i++)                {                    var entry = new SomeIndex                    {                        Id = Guid.NewGuid(),                        Name = $"Index {i + 1}",                        CreatedDate = DateTime.UtcNow,                        Status = Status.None,                        ObjectOwner = null                    };
                    AddNestedProps(entry, i);
                    entries.Add(entry);                }
                //The logs will be added to the Search API logs                _logger.LogInformation("Custom index log: The list of deviations is empty.");            }
            return entries;        }
        private static void AddNestedProps(SomeIndex entry, int count)        {            for (int j = 0; j < count; j++)            {                var nestedProp = new NestedProp                {                    Name = $"Nested prop {j + 1}",                    Value = null                };
                entry.NestedProps.Add(nestedProp);            }        }    }
    public class SomeIndex    {        public Guid Id { get; set; }        public string Name { get; set; }        public DateTime? CreatedDate { get; set; }        public Status? Status { get; set; }        public Reference ObjectOwner { get; set; }        public List<NestedProp> NestedProps { get; set; } = new();    }
    public class NestedProp    {        public string Name { get; set; }        public string Value { get; set; }    }
    public class Reference    {        public Guid Id { get; set; }        public string Name { get; set; }    }
    [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]    public enum Status    {        New,        Active,        Closed,        Removed,        None    }}

Index resynchronization#

Index synchronization is controlled by the given triggerSchedule (Cron expression) but the index can be resynchronized.

The following endpoint is used to resynchronize the index:

PUT /Indices/{id}/Resynchronization

This is also available in Search v1.0 but the endpoint is different:

PUT /Indices/{indexName}/Resynchronization

Saved queries#

In Search API there is an opportunity to save queries that user wants to keep for later usage.

The following endpoints are available for saving queries:

Queries

Query object#

The information in Query:

  • Id
  • Name
  • ObjectOwner - user who owns the query
  • Index - index the query should run for
  • Description - query description
  • QueryObject - query for search
  • Metadata - json field without validation for keeping additional data

For controlling My Actions page in Metadata we have a field called action

{  "action": {    "isVisible": true,    "order": 1  }}
  • IsVisible - if the query is visible in My Actions page
  • Order - order within My Actions page

User can execute saved query by calling following endpoint:

POST /Queries/{id}/Execution

This endpoint will execute saved query and will return search result.

Note : To execute a saved query and see index data, the user will need at least 2 permissions: index_read_owned (to access index data) and query_read_owned (to see the saved query).