Enterprise Search

The Enterprise Search component searches through a dedicated search index and presents the results to the user grouped by entity.

Set the setting EnterpriseSearchMenuItemId to the ID of an Enterprise Search menu item to activate the search box in the sidebar.

See the documentation for the API-objects starting with SoftadminApi.EnterpriseSearchIndex for information on how to work with its index.

Searchable Entities

Searchable Entitites control how rows are grouped when searching and presenting search results. You administer them from the Searchable Entities top-link from any enterprise search menu item.

SchemaName and TableName

Each searchable entity needs a schema name and table name, but those do not need to map against actual tables in the database. For example, if the database has a Contact-table with an IsPrivatePerson-column then you could map some rows to the entity Contact_Person and other rows to the entity Contact_Company.

The Security Model

You can restrict search results on two levels: entity level and row level.

Entity level

Each searchable entity must have a Security Menu Item and only users with access to this menu item will find the entity among their search results. Normally you should set the security menu item to the View xxx menu item that belongs to the entity.

Row level

If you need row level security then you use security groups. Each user is granted security groups through the SoftadminApi.UserSecurityGroup table and each entity row is assigned at most one security group by SoftadminApi.EnterpriseSearchIndex_InsertUpdate. If a row has a security group then only users with the same security group can find it among their search results.

Security Groups are unique to each system and you will need to choose a strategy for defining them. For performance reasons you should strive to have as few different security groups as possible.

You may need to use different security group models for different searchable entities.

Example: A single security group

Assume that the entity Person has a property Protected Identity. All users can view normal persons but only administrators can view persons with protected identity. Then you'd create a single security group, grant it to all administrators, and assign it to all rows with protected identity.

Or maybe you choose not to index persons with protected identity at all instead.

Example: Surrogates from combinations

Assume that each user in the system belongs to one or more Company Roles and each Knowledge Base Page is restricted so that several roles are allowed to view the page. For example, both Sales and IT are allowed to view the page Licensing Costs.

Since a row can only have a single security group you can't use company roles directly: instead you'll need to derive security groups from them. Create one security group for each combination of roles that is actually used, so that 1 would mean Sales, 2 would mean IT and 3 would mean Sales AND IT.

Super Users

Any user who has a single row in SoftadminApi.UserSecurityGroup with the security group ID -1 can see all search results regardless of row level permissions.

Examples

Column function

For each entity you need to create a table-valued function that returns the columns to present to the user.

Accepts the following special columns:
Row_ListViewTitle: Specifies a custom row title for the list grid (that is, the mobile grid). If you do not specify at least one of Row_ListViewTitle orRow_ListViewText then the first visible column will become the row title.

Row_ListViewText: Specifies the body for a custom row description for the list grid (that is, the mobile grid). Usually used together with Row_ListViewTitle.

CREATE FUNCTION MySchema.Contact_EnterpriseSearch
(
	@RowId		bigint,
	@LanguageId int
)
RETURNS TABLE
AS
RETURN
SELECT
	C.ContactId,
	C.Title AS Row_ListViewTitle
	...
FROM
	MySchema.Contact C
	JOIN ...
WHERE
	C.ContactId = @RowId