[Enterprise Search] Create search results provider (#155641)

## Summary

This adds a global search provider for Enterprise Search results,
returning the web crawler and connectors.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Sander Philipse 2023-04-25 16:03:17 +02:00 committed by GitHub
parent ddd09ac271
commit 6e612b5622
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 518 additions and 140 deletions

View file

@ -0,0 +1,120 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { i18n } from '@kbn/i18n';
export interface ConnectorServerSideDefinition {
iconPath: string;
isBeta: boolean;
isNative: boolean;
keywords: string[];
name: string;
serviceType: string;
}
export const CONNECTOR_DEFINITIONS: ConnectorServerSideDefinition[] = [
{
iconPath: 'mongodb.svg',
isBeta: false,
isNative: true,
keywords: ['mongo', 'mongodb', 'database', 'nosql', 'connector'],
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.mongodb.name', {
defaultMessage: 'MongoDB',
}),
serviceType: 'mongodb',
},
{
iconPath: 'mysql.svg',
isBeta: false,
isNative: true,
keywords: ['mysql', 'sql', 'database', 'connector'],
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.mysql.name', {
defaultMessage: 'MySQL',
}),
serviceType: 'mysql',
},
{
iconPath: 'azure_blob_storage.svg',
isBeta: true,
isNative: false,
keywords: ['cloud', 'azure', 'blob', 's3', 'connector'],
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.azureBlob.name', {
defaultMessage: 'Azure Blob Storage',
}),
serviceType: 'azure_blob_storage',
},
{
iconPath: 'google_cloud_storage.svg',
isBeta: true,
isNative: false,
keywords: ['google', 'cloud', 'blob', 's3', 'connector'],
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.googleCloud.name', {
defaultMessage: 'Google Cloud Storage',
}),
serviceType: 'google_cloud_storage',
},
{
iconPath: 'mssql.svg',
isBeta: true,
isNative: false,
keywords: ['mssql', 'microsoft', 'sql', 'database', 'connector'],
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.microsoftSQL.name', {
defaultMessage: 'Microsoft SQL',
}),
serviceType: 'mssql',
},
{
iconPath: 'network_drive.svg',
isBeta: true,
isNative: false,
keywords: ['network', 'drive', 'file', 'directory', 'connector'],
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.networkDrive.name', {
defaultMessage: 'Network drive',
}),
serviceType: 'network_drive',
},
{
iconPath: 'oracle.svg',
isBeta: true,
isNative: false,
keywords: ['oracle', 'sql', 'database', 'connector'],
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.oracle.name', {
defaultMessage: 'Oracle',
}),
serviceType: 'oracle',
},
{
iconPath: 'postgresql.svg',
isBeta: true,
isNative: false,
keywords: ['postgresql', 'sql', 'database', 'connector'],
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.postgresql.name', {
defaultMessage: 'Postgresql',
}),
serviceType: 'postgresql',
},
{
iconPath: 's3.svg',
isBeta: true,
isNative: false,
keywords: ['s3', 'cloud', 'amazon', 'connector'],
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.s3.name', {
defaultMessage: 'S3',
}),
serviceType: 's3',
},
{
iconPath: 'custom.svg',
isBeta: true,
isNative: false,
keywords: ['custom', 'connector', 'code'],
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.customConnector.name', {
defaultMessage: 'Customized connector',
}),
serviceType: '',
},
];

View file

@ -26,6 +26,7 @@
],
"optionalPlugins": [
"customIntegrations",
"globalSearch",
"home",
"ml",
"spaces",

View file

@ -7,9 +7,9 @@
import { INGESTION_METHOD_IDS } from '../../../../../common/constants';
import connectorLogo from '../../../../assets/enterprise_search_features/connector.svg';
import connectorLogo from '../../../../assets/source_icons/connector.svg';
import crawlerLogo from '../../../../assets/enterprise_search_features/crawler.svg';
import crawlerLogo from '../../../../assets/source_icons/crawler.svg';
import { UNIVERSAL_LANGUAGE_VALUE } from './constants';
import { LanguageForOptimization } from './types';

View file

@ -5,137 +5,83 @@
* 2.0.
*/
import { i18n } from '@kbn/i18n';
import { CONNECTOR_ICONS } from '../../../../../assets/source_icons/native_connector_icons';
import { CONNECTOR_DEFINITIONS } from '../../../../../../common/connectors/connectors';
import { docLinks } from '../../../../shared/doc_links';
import { CONNECTOR_ICONS } from '../../../../shared/icons/connector_icons';
import { ConnectorDefinition } from './types';
import { ConnectorClientSideDefinition } from './types';
export const CONNECTORS: ConnectorDefinition[] = [
{
docsUrl: docLinks.connectorsMongoDB,
externalAuthDocsUrl: 'https://www.mongodb.com/docs/atlas/app-services/authentication/',
externalDocsUrl: 'https://www.mongodb.com/docs/',
icon: CONNECTOR_ICONS.mongodb,
isBeta: false,
isNative: true,
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.mongodb.name', {
defaultMessage: 'MongoDB',
}),
serviceType: 'mongodb',
},
{
docsUrl: docLinks.connectorsMySQL,
externalDocsUrl: 'https://dev.mysql.com/doc/',
icon: CONNECTOR_ICONS.mysql,
isBeta: false,
isNative: true,
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.mysql.name', {
defaultMessage: 'MySQL',
}),
serviceType: 'mysql',
},
{
export const CONNECTORS_DICT: Record<string, ConnectorClientSideDefinition> = {
azure_blob_storage: {
docsUrl: docLinks.connectorsAzureBlobStorage,
externalAuthDocsUrl: 'https://learn.microsoft.com/azure/storage/common/authorize-data-access',
externalDocsUrl: 'https://learn.microsoft.com/azure/storage/blobs/',
icon: CONNECTOR_ICONS.azure_blob_storage,
isBeta: true,
isNative: false,
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.azureBlob.name', {
defaultMessage: 'Azure Blob Storage',
}),
serviceType: 'azure_blob_storage',
},
{
custom: {
docsUrl: docLinks.connectors,
externalAuthDocsUrl: '',
externalDocsUrl: '',
icon: CONNECTOR_ICONS.custom,
},
google_cloud_storage: {
docsUrl: docLinks.connectorsGoogleCloudStorage,
externalAuthDocsUrl: 'https://cloud.google.com/storage/docs/authentication',
externalDocsUrl: 'https://cloud.google.com/storage/docs',
icon: CONNECTOR_ICONS.google_cloud_storage,
isBeta: true,
isNative: false,
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.googleCloud.name', {
defaultMessage: 'Google Cloud Storage',
}),
serviceType: 'google_cloud_storage',
},
{
mongodb: {
docsUrl: docLinks.connectorsMongoDB,
externalAuthDocsUrl: 'https://www.mongodb.com/docs/atlas/app-services/authentication/',
externalDocsUrl: 'https://www.mongodb.com/docs/',
icon: CONNECTOR_ICONS.mongodb,
},
mssql: {
docsUrl: docLinks.connectorsMicrosoftSQL,
externalAuthDocsUrl:
'https://learn.microsoft.com/sql/relational-databases/security/authentication-access/getting-started-with-database-engine-permissions',
externalDocsUrl: 'https://learn.microsoft.com/sql/',
icon: CONNECTOR_ICONS.microsoft_sql,
isBeta: true,
isNative: false,
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.microsoftSQL.name', {
defaultMessage: 'Microsoft SQL',
}),
serviceType: 'mssql',
},
{
mysql: {
docsUrl: docLinks.connectorsMySQL,
externalDocsUrl: 'https://dev.mysql.com/doc/',
icon: CONNECTOR_ICONS.mysql,
},
network_drive: {
docsUrl: docLinks.connectorsNetworkDrive,
externalAuthDocsUrl: '',
externalDocsUrl: '',
icon: CONNECTOR_ICONS.network_drive,
isBeta: true,
isNative: false,
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.networkDrive.name', {
defaultMessage: 'Network drive',
}),
serviceType: 'network_drive',
},
{
oracle: {
docsUrl: docLinks.connectorsOracle,
externalAuthDocsUrl:
'https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/index.html',
externalDocsUrl: 'https://docs.oracle.com/database/oracle/oracle-database/',
icon: CONNECTOR_ICONS.oracle,
isBeta: true,
isNative: false,
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.oracle.name', {
defaultMessage: 'Oracle',
}),
serviceType: 'oracle',
},
{
postgresql: {
docsUrl: docLinks.connectorsPostgreSQL,
externalAuthDocsUrl: 'https://www.postgresql.org/docs/15/auth-methods.html',
externalDocsUrl: 'https://www.postgresql.org/docs/',
icon: CONNECTOR_ICONS.postgresql,
isBeta: true,
isNative: false,
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.postgresql.name', {
defaultMessage: 'Postgresql',
}),
serviceType: 'postgresql',
},
{
s3: {
docsUrl: docLinks.connectorsS3,
externalAuthDocsUrl: 'https://docs.aws.amazon.com/s3/index.html',
externalDocsUrl: '',
icon: CONNECTOR_ICONS.amazon_s3,
isBeta: true,
isNative: false,
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.s3.name', {
defaultMessage: 'S3',
}),
serviceType: 's3',
},
{
docsUrl: docLinks.connectors,
externalAuthDocsUrl: '',
externalDocsUrl: '',
icon: CONNECTOR_ICONS.custom,
isBeta: true,
isNative: false,
name: i18n.translate('xpack.enterpriseSearch.content.nativeConnectors.customConnector.name', {
defaultMessage: 'Custom connector',
}),
serviceType: '',
},
];
};
export const CONNECTORS = CONNECTOR_DEFINITIONS.map((connector) => ({
...connector,
...(connector.serviceType && CONNECTORS_DICT[connector.serviceType]
? CONNECTORS_DICT[connector.serviceType]
: CONNECTORS_DICT.custom),
}));
export const CUSTOM_CONNECTORS = CONNECTORS.filter(({ isNative }) => !isNative);

View file

@ -5,13 +5,13 @@
* 2.0.
*/
export interface ConnectorDefinition {
import { ConnectorServerSideDefinition } from '../../../../../../common/connectors/connectors';
export interface ConnectorClientSideDefinition {
docsUrl?: string;
externalAuthDocsUrl?: string;
externalDocsUrl: string;
icon: string;
isBeta: boolean;
isNative: boolean;
name: string;
serviceType: string;
}
export type ConnectorDefinition = ConnectorClientSideDefinition & ConnectorServerSideDefinition;

View file

@ -0,0 +1,30 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import azure_blob_storage from '../../../assets/source_icons/azure_blob_storage.svg';
import custom from '../../../assets/source_icons/custom.svg';
import google_cloud_storage from '../../../assets/source_icons/google_cloud_storage.svg';
import mongodb from '../../../assets/source_icons/mongodb.svg';
import microsoft_sql from '../../../assets/source_icons/mssql.svg';
import mysql from '../../../assets/source_icons/mysql.svg';
import network_drive from '../../../assets/source_icons/network_drive.svg';
import oracle from '../../../assets/source_icons/oracle.svg';
import postgresql from '../../../assets/source_icons/postgresql.svg';
import amazon_s3 from '../../../assets/source_icons/s3.svg';
export const CONNECTOR_ICONS = {
amazon_s3,
azure_blob_storage,
custom,
google_cloud_storage,
microsoft_sql,
mongodb,
mysql,
network_drive,
oracle,
postgresql,
};

View file

@ -1,30 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import amazon_s3 from './amazon_s3.svg';
import azure_blob_storage from './azure_blob_storage.svg';
import custom from './custom.svg';
import google_cloud_storage from './google_cloud_storage.svg';
import microsoft_sql from './microsoft_sql.svg';
import mongodb from './mongodb.svg';
import mysql from './mysql.svg';
import network_drive from './network_drive.svg';
import oracle from './oracle.svg';
import postgresql from './postgresql.svg';
export const CONNECTOR_ICONS = {
amazon_s3,
azure_blob_storage,
custom,
google_cloud_storage,
microsoft_sql,
mongodb,
mysql,
network_drive,
oracle,
postgresql,
};

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before After
Before After

View file

@ -588,9 +588,7 @@ export const registerEnterpriseSearchIntegrations = (
icons: [
{
type: 'svg',
src: http.basePath.prepend(
'/plugins/enterpriseSearch/assets/source_icons/microsoft_sql.svg'
),
src: http.basePath.prepend('/plugins/enterpriseSearch/assets/source_icons/mssql.svg'),
},
],
shipper: 'enterprise_search',
@ -651,7 +649,7 @@ export const registerEnterpriseSearchIntegrations = (
icons: [
{
type: 'svg',
src: http.basePath.prepend('/plugins/enterpriseSearch/assets/source_icons/amazon_s3.svg'),
src: http.basePath.prepend('/plugins/enterpriseSearch/assets/source_icons/s3.svg'),
},
],
shipper: 'enterprise_search',

View file

@ -18,6 +18,7 @@ import {
import { CustomIntegrationsPluginSetup } from '@kbn/custom-integrations-plugin/server';
import { DataPluginStart } from '@kbn/data-plugin/server/plugin';
import { PluginSetupContract as FeaturesPluginSetup } from '@kbn/features-plugin/server';
import { GlobalSearchPluginSetup } from '@kbn/global-search-plugin/server';
import type { GuidedOnboardingPluginSetup } from '@kbn/guided-onboarding-plugin/server';
import { InfraPluginSetup } from '@kbn/infra-plugin/server';
import type { MlPluginSetup } from '@kbn/ml-plugin/server';
@ -76,31 +77,34 @@ import { workplaceSearchTelemetryType } from './saved_objects/workplace_search/t
import { uiSettings as enterpriseSearchUISettings } from './ui_settings';
import { getSearchResultProvider } from './utils/search_result_provider';
import { ConfigType } from '.';
interface PluginsSetup {
usageCollection?: UsageCollectionSetup;
security: SecurityPluginSetup;
features: FeaturesPluginSetup;
infra: InfraPluginSetup;
customIntegrations?: CustomIntegrationsPluginSetup;
ml?: MlPluginSetup;
features: FeaturesPluginSetup;
globalSearch: GlobalSearchPluginSetup;
guidedOnboarding: GuidedOnboardingPluginSetup;
infra: InfraPluginSetup;
ml?: MlPluginSetup;
security: SecurityPluginSetup;
usageCollection?: UsageCollectionSetup;
}
interface PluginsStart {
spaces?: SpacesPluginStart;
security: SecurityPluginStart;
data: DataPluginStart;
security: SecurityPluginStart;
spaces?: SpacesPluginStart;
}
export interface RouteDependencies {
router: IRouter;
config: ConfigType;
log: Logger;
enterpriseSearchRequestHandler: IEnterpriseSearchRequestHandler;
getSavedObjectsService?(): SavedObjectsServiceStart;
log: Logger;
ml?: MlPluginSetup;
router: IRouter;
}
export class EnterpriseSearchPlugin implements Plugin {
@ -118,6 +122,7 @@ export class EnterpriseSearchPlugin implements Plugin {
usageCollection,
security,
features,
globalSearch,
infra,
customIntegrations,
ml,
@ -284,6 +289,14 @@ export class EnterpriseSearchPlugin implements Plugin {
if (config.hasNativeConnectors) {
guidedOnboarding.registerGuideConfig(databaseSearchGuideId, databaseSearchGuideConfig);
}
/**
* Register our integrations in the global search bar
*/
if (globalSearch) {
globalSearch.registerResultProvider(getSearchResultProvider(http.basePath, config));
}
}
public start() {}

View file

@ -0,0 +1,196 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { NEVER } from 'rxjs';
import { TestScheduler } from 'rxjs/testing';
import { ENTERPRISE_SEARCH_CONTENT_PLUGIN } from '../../common/constants';
import { getSearchResultProvider } from './search_result_provider';
const getTestScheduler = () => {
return new TestScheduler((actual, expected) => {
return expect(actual).toEqual(expected);
});
};
describe('Enterprise Search search provider', () => {
const basePathMock = {
prepend: (input: string) => `/kbn${input}`,
} as any;
const crawlerResult = {
icon: '/kbn/plugins/enterpriseSearch/assets/source_icons/crawler.svg',
id: 'elastic-crawler',
score: 75,
title: 'Elastic Web Crawler',
type: 'Enterprise Search',
url: {
path: `${ENTERPRISE_SEARCH_CONTENT_PLUGIN.URL}/search_indices/new_index/crawler`,
prependBasePath: true,
},
};
const mongoResult = {
icon: '/kbn/plugins/enterpriseSearch/assets/source_icons/mongodb.svg',
id: 'mongodb',
score: 75,
title: 'MongoDB',
type: 'Enterprise Search',
url: {
path: `${ENTERPRISE_SEARCH_CONTENT_PLUGIN.URL}/search_indices/new_index/connector?service_type=mongodb`,
prependBasePath: true,
},
};
const searchResultProvider = getSearchResultProvider(basePathMock, {
hasConnectors: true,
hasWebCrawler: true,
} as any);
beforeEach(() => {});
afterEach(() => {
jest.clearAllMocks();
});
describe('find', () => {
it('returns formatted results', () => {
getTestScheduler().run(({ expectObservable }) => {
expectObservable(
searchResultProvider.find(
{ term: 'crawler' },
{ aborted$: NEVER, maxResults: 100, preference: '' },
{} as any
)
).toBe('(a|)', {
a: [crawlerResult],
});
});
});
it('returns everything on empty string', () => {
getTestScheduler().run(({ expectObservable }) => {
expectObservable(
searchResultProvider.find(
{ term: '' },
{ aborted$: NEVER, maxResults: 100, preference: '' },
{} as any
)
).toBe('(a|)', {
a: expect.arrayContaining([
{ ...crawlerResult, score: 80 },
{ ...mongoResult, score: 80 },
]),
});
});
});
it('respect maximum results', () => {
getTestScheduler().run(({ expectObservable }) => {
expectObservable(
searchResultProvider.find(
{ term: '' },
{ aborted$: NEVER, maxResults: 1, preference: '' },
{} as any
)
).toBe('(a|)', {
a: [{ ...crawlerResult, score: 80 }],
});
});
});
it('omits crawler if config has crawler disabled', () => {
const searchProvider = getSearchResultProvider(basePathMock, {
hasConnectors: true,
hasWebCrawler: false,
} as any);
getTestScheduler().run(({ expectObservable }) => {
expectObservable(
searchProvider.find(
{ term: '' },
{ aborted$: NEVER, maxResults: 100, preference: '' },
{} as any
)
).toBe('(a|)', {
a: expect.not.arrayContaining([{ ...crawlerResult, score: 80 }]),
});
});
});
it('omits connectors if config has connectors disabled', () => {
const searchProvider = getSearchResultProvider(basePathMock, {
hasConnectors: false,
hasWebCrawler: true,
} as any);
getTestScheduler().run(({ expectObservable }) => {
expectObservable(
searchProvider.find(
{ term: '' },
{ aborted$: NEVER, maxResults: 100, preference: '' },
{} as any
)
).toBe('(a|)', {
a: expect.not.arrayContaining([{ mongoResult, score: 80 }]),
});
});
});
it('returns nothing if tag is specified', () => {
getTestScheduler().run(({ expectObservable }) => {
expectObservable(
searchResultProvider.find(
{ tags: ['tag'], term: '' },
{ aborted$: NEVER, maxResults: 1, preference: '' },
{} as any
)
).toBe('(a|)', {
a: [],
});
});
});
it('returns nothing if unknown type is specified', () => {
getTestScheduler().run(({ expectObservable }) => {
expectObservable(
searchResultProvider.find(
{ term: '', types: ['tag'] },
{ aborted$: NEVER, maxResults: 1, preference: '' },
{} as any
)
).toBe('(a|)', {
a: [],
});
});
});
it('returns results for integrations tag', () => {
getTestScheduler().run(({ expectObservable }) => {
expectObservable(
searchResultProvider.find(
{ term: 'crawler', types: ['integration'] },
{ aborted$: NEVER, maxResults: 1, preference: '' },
{} as any
)
).toBe('(a|)', {
a: [crawlerResult],
});
});
});
it('returns results for enterprise search tag', () => {
getTestScheduler().run(({ expectObservable }) => {
expectObservable(
searchResultProvider.find(
{ term: 'crawler', types: ['enterprise search'] },
{ aborted$: NEVER, maxResults: 1, preference: '' },
{} as any
)
).toBe('(a|)', {
a: [crawlerResult],
});
});
});
});
});

View file

@ -0,0 +1,103 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { from, takeUntil } from 'rxjs';
import { IBasePath } from '@kbn/core-http-server';
import { GlobalSearchResultProvider } from '@kbn/global-search-plugin/server';
import { ConfigType } from '..';
import { CONNECTOR_DEFINITIONS } from '../../common/connectors/connectors';
import {
ENTERPRISE_SEARCH_CONNECTOR_CRAWLER_SERVICE_TYPE,
ENTERPRISE_SEARCH_CONTENT_PLUGIN,
} from '../../common/constants';
export function toSearchResult({
basePath,
iconPath,
name,
score,
serviceType,
}: {
basePath: IBasePath;
iconPath: string;
name: string;
score: number;
serviceType: string;
}) {
return {
icon: iconPath
? basePath.prepend(`/plugins/enterpriseSearch/assets/source_icons/${iconPath}`)
: 'logoEnterpriseSearch',
id: serviceType,
score,
title: name,
type: 'Enterprise Search',
url: {
path: `${ENTERPRISE_SEARCH_CONTENT_PLUGIN.URL}/search_indices/new_index/${
serviceType === ENTERPRISE_SEARCH_CONNECTOR_CRAWLER_SERVICE_TYPE
? 'crawler'
: `connector?service_type=${serviceType}`
}`,
prependBasePath: true,
},
};
}
export function getSearchResultProvider(
basePath: IBasePath,
config: ConfigType
): GlobalSearchResultProvider {
return {
find: ({ term, types, tags }, { aborted$, maxResults }) => {
if (
tags ||
(types && !(types.includes('integration') || types.includes('enterprise search')))
) {
return from([[]]);
}
const result = [
...(config.hasWebCrawler
? [
{
iconPath: 'crawler.svg',
keywords: ['crawler', 'web', 'website', 'internet', 'google'],
name: 'Elastic Web Crawler',
serviceType: ENTERPRISE_SEARCH_CONNECTOR_CRAWLER_SERVICE_TYPE,
},
]
: []),
...(config.hasConnectors ? CONNECTOR_DEFINITIONS : []),
]
.map(({ iconPath, keywords, name, serviceType }) => {
let score = 0;
const searchTerm = (term || '').toLowerCase();
const searchName = name.toLowerCase();
if (!searchTerm) {
score = 80;
} else if (searchName === searchTerm) {
score = 100;
} else if (searchName.startsWith(searchTerm)) {
score = 90;
} else if (searchName.includes(searchTerm)) {
score = 75;
} else if (serviceType === searchTerm) {
score = 65;
} else if (keywords.some((keyword) => keyword.includes(searchTerm))) {
score = 50;
}
return toSearchResult({ basePath, iconPath, name, score, serviceType });
})
.filter(({ score }) => score > 0)
.slice(0, maxResults);
return from([result]).pipe(takeUntil(aborted$));
},
getSearchableTypes: () => ['enterprise search', 'integration'],
id: 'enterpriseSearch',
};
}

View file

@ -59,5 +59,6 @@
"@kbn/field-types",
"@kbn/core-elasticsearch-server-mocks",
"@kbn/shared-ux-link-redirect-app",
"@kbn/global-search-plugin",
]
}