diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.test.tsx
index fad4e54721bb35..80d5a874c81025 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.test.tsx
@@ -5,6 +5,8 @@
* 2.0.
*/
+import { setMockValues } from '../../../../../__mocks__/kea_logic';
+
import React from 'react';
import { shallow } from 'enzyme';
@@ -14,6 +16,13 @@ import { Result } from '../../../result';
import { CurationResultPanel } from './curation_result_panel';
describe('CurationResultPanel', () => {
+ const values = {
+ isMetaEngine: true,
+ engine: {
+ schema: {},
+ },
+ };
+
const results = [
{
id: { raw: 'foo' },
@@ -25,6 +34,10 @@ describe('CurationResultPanel', () => {
},
];
+ beforeAll(() => {
+ setMockValues(values);
+ });
+
beforeEach(() => {
jest.clearAllMocks();
});
@@ -33,6 +46,11 @@ describe('CurationResultPanel', () => {
const wrapper = shallow();
expect(wrapper.find('[data-test-subj="suggestedText"]').exists()).toBe(false);
expect(wrapper.find(Result).length).toBe(2);
+ expect(wrapper.find(Result).at(0).props()).toEqual({
+ result: results[0],
+ isMetaEngine: true,
+ schemaForTypeHighlights: values.engine.schema,
+ });
});
it('renders a no results message when there are no results', () => {
@@ -41,6 +59,11 @@ describe('CurationResultPanel', () => {
expect(wrapper.find(Result).length).toBe(0);
});
+ it('renders the correct count', () => {
+ const wrapper = shallow();
+ expect(wrapper.find('[data-test-subj="curationCount"]').prop('children')).toBe(2);
+ });
+
it('shows text about automation when variant is "suggested"', () => {
const wrapper = shallow();
expect(wrapper.find('[data-test-subj="suggestedText"]').exists()).toBe(true);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.tsx
index 12bbf07f97bb35..b61355d0b85557 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.tsx
@@ -7,6 +7,8 @@
import React from 'react';
+import { useValues } from 'kea';
+
import {
EuiFlexGroup,
EuiFlexItem,
@@ -17,6 +19,8 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
+import { EngineLogic } from '../../../engine';
+
import { Result } from '../../../result';
import { Result as ResultType } from '../../../result/types';
import './curation_result_panel.scss';
@@ -27,14 +31,14 @@ interface Props {
}
export const CurationResultPanel: React.FC = ({ variant, results }) => {
- // TODO wire up
- const count = 3;
+ const { isMetaEngine, engine } = useValues(EngineLogic);
+ const count = results.length;
return (
<>
- {count}
+ {count}
@@ -70,7 +74,11 @@ export const CurationResultPanel: React.FC = ({ variant, results }) => {
{results.length > 0 ? (
results.map((result) => (
-
+
))
) : (
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.test.tsx
index 9bfc12dfe7cc20..2dcefa7273c728 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.test.tsx
@@ -5,6 +5,8 @@
* 2.0.
*/
+import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic';
+import '../../../../../__mocks__/shallow_useeffect.mock';
import { mockUseParams } from '../../../../../__mocks__/react_router';
import '../../../../__mocks__/engine_logic.mock';
@@ -14,12 +16,65 @@ import { shallow } from 'enzyme';
import { AppSearchPageTemplate } from '../../../layout';
+import { Result } from '../../../result';
+
+import { CurationResultPanel } from './curation_result_panel';
import { CurationSuggestion } from './curation_suggestion';
describe('CurationSuggestion', () => {
+ const values = {
+ suggestion: {
+ query: 'foo',
+ updated_at: '2021-07-08T14:35:50Z',
+ promoted: ['1', '2', '3'],
+ },
+ suggestedPromotedDocuments: [
+ {
+ id: {
+ raw: '1',
+ },
+ _meta: {
+ id: '1',
+ engine: 'some-engine',
+ },
+ },
+ {
+ id: {
+ raw: '2',
+ },
+ _meta: {
+ id: '2',
+ engine: 'some-engine',
+ },
+ },
+ {
+ id: {
+ raw: '3',
+ },
+ _meta: {
+ id: '3',
+ engine: 'some-engine',
+ },
+ },
+ ],
+ isMetaEngine: true,
+ engine: {
+ schema: {},
+ },
+ };
+
+ const actions = {
+ loadSuggestion: jest.fn(),
+ };
+
+ beforeAll(() => {
+ setMockValues(values);
+ setMockActions(actions);
+ });
+
beforeEach(() => {
jest.clearAllMocks();
- mockUseParams.mockReturnValue({ query: 'some%20query' });
+ mockUseParams.mockReturnValue({ query: 'foo' });
});
it('renders', () => {
@@ -28,19 +83,21 @@ describe('CurationSuggestion', () => {
expect(wrapper.is(AppSearchPageTemplate)).toBe(true);
});
- it('displays the decoded query in the title', () => {
- const wrapper = shallow();
-
- expect(wrapper.prop('pageHeader').pageTitle).toEqual('some query');
+ it('loads data on initialization', () => {
+ shallow();
+ expect(actions.loadSuggestion).toHaveBeenCalled();
});
- // TODO This will need to come from somewhere else when wired up
- it('displays an empty query if "" is encoded in as the qery', () => {
- mockUseParams.mockReturnValue({ query: '%22%22' });
+ it('shows suggested promoted documents', () => {
+ const wrapper = shallow();
+ const suggestedResultsPanel = wrapper.find(CurationResultPanel).at(1);
+ expect(suggestedResultsPanel.prop('results')).toEqual(values.suggestedPromotedDocuments);
+ });
+ it('displays the query in the title', () => {
const wrapper = shallow();
- expect(wrapper.prop('pageHeader').pageTitle).toEqual('""');
+ expect(wrapper.prop('pageHeader').pageTitle).toEqual('foo');
});
it('displays has a button to display organic results', () => {
@@ -52,4 +109,24 @@ describe('CurationSuggestion', () => {
wrapper.find('[data-test-subj="showOrganicResults"]').simulate('click');
expect(wrapper.find('[data-test-subj="organicResults"]').exists()).toBe(false);
});
+
+ it('displays proposed organic results', () => {
+ const wrapper = shallow();
+ wrapper.find('[data-test-subj="showOrganicResults"]').simulate('click');
+ expect(wrapper.find('[data-test-subj="proposedOrganicResults"]').find(Result).length).toBe(4);
+ expect(wrapper.find(Result).at(0).prop('isMetaEngine')).toEqual(true);
+ expect(wrapper.find(Result).at(0).prop('schemaForTypeHighlights')).toEqual(
+ values.engine.schema
+ );
+ });
+
+ it('displays current organic results', () => {
+ const wrapper = shallow();
+ wrapper.find('[data-test-subj="showOrganicResults"]').simulate('click');
+ expect(wrapper.find('[data-test-subj="currentOrganicResults"]').find(Result).length).toBe(4);
+ expect(wrapper.find(Result).at(0).prop('isMetaEngine')).toEqual(true);
+ expect(wrapper.find(Result).at(0).prop('schemaForTypeHighlights')).toEqual(
+ values.engine.schema
+ );
+ });
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.tsx
index 4fab9db47af908..ade78e4914e84a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.tsx
@@ -5,7 +5,9 @@
* 2.0.
*/
-import React, { useState } from 'react';
+import React, { useEffect, useState } from 'react';
+
+import { useActions, useValues } from 'kea';
import {
EuiButtonEmpty,
@@ -19,6 +21,7 @@ import {
import { i18n } from '@kbn/i18n';
import { useDecodedParams } from '../../../../utils/encode_path_params';
+import { EngineLogic } from '../../../engine';
import { AppSearchPageTemplate } from '../../../layout';
import { Result } from '../../../result';
import { Result as ResultType } from '../../../result/types';
@@ -27,26 +30,37 @@ import { getCurationsBreadcrumbs } from '../../utils';
import { CurationActionBar } from './curation_action_bar';
import { CurationResultPanel } from './curation_result_panel';
+import { CurationSuggestionLogic } from './curation_suggestion_logic';
import { DATA } from './temp_data';
export const CurationSuggestion: React.FC = () => {
const { query } = useDecodedParams();
+ const curationSuggestionLogic = CurationSuggestionLogic({ query });
+ const { loadSuggestion } = useActions(curationSuggestionLogic);
+ const { engine, isMetaEngine } = useValues(EngineLogic);
+ const { suggestion, suggestedPromotedDocuments, dataLoading } =
+ useValues(curationSuggestionLogic);
const [showOrganicResults, setShowOrganicResults] = useState(false);
const currentOrganicResults = [...DATA].splice(5, 4);
const proposedOrganicResults = [...DATA].splice(2, 4);
- const queryTitle = query === '""' ? query : `${query}`;
+ const suggestionQuery = suggestion?.query || '';
+
+ useEffect(() => {
+ loadSuggestion();
+ }, []);
return (
{
- Current
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.currentTitle',
+ { defaultMessage: 'Current' }
+ )}
+
- Suggested
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.suggestionTitle',
+ { defaultMessage: 'Suggested' }
+ )}
+
-
+
@@ -81,7 +105,15 @@ export const CurationSuggestion: React.FC = () => {
onClick={() => setShowOrganicResults(!showOrganicResults)}
data-test-subj="showOrganicResults"
>
- {showOrganicResults ? 'Collapse' : 'Expand'} organic search results
+ {showOrganicResults
+ ? i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.collapseButtonLabel',
+ { defaultMessage: 'Collapse organic search results' }
+ )
+ : i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.expandButtonLabel',
+ { defaultMessage: 'Expand organic search results' }
+ )}
{showOrganicResults && (
<>
@@ -90,10 +122,18 @@ export const CurationSuggestion: React.FC = () => {
{currentOrganicResults.length > 0 && (
-
+
{currentOrganicResults.map((result: ResultType) => (
-
+
))}
@@ -101,10 +141,18 @@ export const CurationSuggestion: React.FC = () => {
{proposedOrganicResults.length > 0 && (
-
+
{proposedOrganicResults.map((result: ResultType) => (
-
+
))}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion_logic.test.ts
new file mode 100644
index 00000000000000..9edeab4b658ef8
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion_logic.test.ts
@@ -0,0 +1,230 @@
+/*
+ * 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 {
+ LogicMounter,
+ mockFlashMessageHelpers,
+ mockHttpValues,
+} from '../../../../../__mocks__/kea_logic';
+
+import '../../../../__mocks__/engine_logic.mock';
+
+import { nextTick } from '@kbn/test/jest';
+
+import { CurationSuggestion } from '../../types';
+
+import { CurationSuggestionLogic } from './curation_suggestion_logic';
+
+const DEFAULT_VALUES = {
+ dataLoading: true,
+ suggestion: null,
+ suggestedPromotedDocuments: [],
+};
+
+const suggestion: CurationSuggestion = {
+ query: 'foo',
+ updated_at: '2021-07-08T14:35:50Z',
+ promoted: ['1', '2', '3'],
+ status: 'applied',
+};
+
+const suggestedPromotedDocuments = [
+ {
+ id: {
+ raw: '1',
+ },
+ _meta: {
+ id: '1',
+ engine: 'some-engine',
+ },
+ },
+ {
+ id: {
+ raw: '2',
+ },
+ _meta: {
+ id: '2',
+ engine: 'some-engine',
+ },
+ },
+ {
+ id: {
+ raw: '3',
+ },
+ _meta: {
+ id: '3',
+ engine: 'some-engine',
+ },
+ },
+];
+
+const MOCK_RESPONSE = {
+ meta: {
+ page: {
+ current: 1,
+ size: 10,
+ total_results: 1,
+ total_pages: 1,
+ },
+ },
+ results: [suggestion],
+};
+
+const MOCK_DOCUMENTS_RESPONSE = {
+ results: [
+ {
+ id: {
+ raw: '2',
+ },
+ _meta: {
+ id: '2',
+ engine: 'some-engine',
+ },
+ },
+ {
+ id: {
+ raw: '1',
+ },
+ _meta: {
+ id: '1',
+ engine: 'some-engine',
+ },
+ },
+ ],
+};
+
+describe('CurationSuggestionLogic', () => {
+ const { mount } = new LogicMounter(CurationSuggestionLogic);
+ const { flashAPIErrors } = mockFlashMessageHelpers;
+ const mountLogic = (props: object = {}) => {
+ mount(props, { query: 'foo-query' });
+ };
+
+ const { http } = mockHttpValues;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('has expected default values', () => {
+ mountLogic();
+ expect(CurationSuggestionLogic.values).toEqual(DEFAULT_VALUES);
+ });
+
+ describe('actions', () => {
+ describe('onSuggestionLoaded', () => {
+ it('should save the loaded suggestion and promoted documents associated with that suggestion and set dataLoading to false', () => {
+ mountLogic();
+ CurationSuggestionLogic.actions.onSuggestionLoaded({
+ suggestion,
+ suggestedPromotedDocuments,
+ });
+ expect(CurationSuggestionLogic.values).toEqual({
+ ...DEFAULT_VALUES,
+ suggestion,
+ suggestedPromotedDocuments,
+ dataLoading: false,
+ });
+ });
+ });
+ });
+
+ describe('listeners', () => {
+ describe('loadSuggestion', () => {
+ it('should set dataLoading state', () => {
+ mountLogic({ dataLoading: false });
+
+ CurationSuggestionLogic.actions.loadSuggestion();
+
+ expect(CurationSuggestionLogic.values).toEqual({
+ ...DEFAULT_VALUES,
+ dataLoading: true,
+ });
+ });
+
+ it('should make an API call and trigger onSuggestionLoaded', async () => {
+ http.post.mockReturnValueOnce(Promise.resolve(MOCK_RESPONSE));
+ http.post.mockReturnValueOnce(Promise.resolve(MOCK_DOCUMENTS_RESPONSE));
+ mountLogic();
+ jest.spyOn(CurationSuggestionLogic.actions, 'onSuggestionLoaded');
+
+ CurationSuggestionLogic.actions.loadSuggestion();
+ await nextTick();
+
+ expect(http.post).toHaveBeenCalledWith(
+ '/internal/app_search/engines/some-engine/search_relevance_suggestions/foo-query',
+ {
+ body: JSON.stringify({
+ page: {
+ current: 1,
+ size: 1,
+ },
+ filters: {
+ status: ['pending'],
+ type: 'curation',
+ },
+ }),
+ }
+ );
+
+ expect(http.post).toHaveBeenCalledWith('/internal/app_search/engines/some-engine/search', {
+ query: { query: '' },
+ body: JSON.stringify({
+ page: {
+ size: 100,
+ },
+ filters: {
+ // The results of the first API call are used to make the second http call for document details
+ id: MOCK_RESPONSE.results[0].promoted,
+ },
+ }),
+ });
+
+ expect(CurationSuggestionLogic.actions.onSuggestionLoaded).toHaveBeenCalledWith({
+ suggestion: {
+ query: 'foo',
+ updated_at: '2021-07-08T14:35:50Z',
+ promoted: ['1', '2', '3'],
+ status: 'applied',
+ },
+ // Note that these were re-ordered to match the 'promoted' list above, and since document
+ // 3 was not found it is not included in this list
+ suggestedPromotedDocuments: [
+ {
+ id: {
+ raw: '1',
+ },
+ _meta: {
+ id: '1',
+ engine: 'some-engine',
+ },
+ },
+ {
+ id: {
+ raw: '2',
+ },
+ _meta: {
+ id: '2',
+ engine: 'some-engine',
+ },
+ },
+ ],
+ });
+ });
+
+ it('handles errors', async () => {
+ http.post.mockReturnValueOnce(Promise.reject('error'));
+ mount();
+
+ CurationSuggestionLogic.actions.loadSuggestion();
+ await nextTick();
+
+ expect(flashAPIErrors).toHaveBeenCalledWith('error');
+ });
+ });
+ });
+});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion_logic.ts
new file mode 100644
index 00000000000000..d3f27be122060c
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion_logic.ts
@@ -0,0 +1,131 @@
+/*
+ * 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 { kea, MakeLogicType } from 'kea';
+
+import { flashAPIErrors } from '../../../../../shared/flash_messages';
+import { HttpLogic } from '../../../../../shared/http';
+import { EngineLogic } from '../../../engine';
+import { Result } from '../../../result/types';
+import { CurationSuggestion } from '../../types';
+
+interface CurationSuggestionValues {
+ dataLoading: boolean;
+ suggestion: CurationSuggestion | null;
+ suggestedPromotedDocuments: Result[];
+}
+
+interface CurationSuggestionActions {
+ loadSuggestion(): void;
+ onSuggestionLoaded({
+ suggestion,
+ suggestedPromotedDocuments,
+ }: {
+ suggestion: CurationSuggestion;
+ suggestedPromotedDocuments: Result[];
+ }): {
+ suggestion: CurationSuggestion;
+ suggestedPromotedDocuments: Result[];
+ };
+}
+
+interface CurationSuggestionProps {
+ query: CurationSuggestion['query'];
+}
+
+export const CurationSuggestionLogic = kea<
+ MakeLogicType
+>({
+ path: ['enterprise_search', 'app_search', 'curations', 'suggestion_logic'],
+ actions: () => ({
+ loadSuggestion: true,
+ onSuggestionLoaded: ({ suggestion, suggestedPromotedDocuments }) => ({
+ suggestion,
+ suggestedPromotedDocuments,
+ }),
+ }),
+ reducers: () => ({
+ dataLoading: [
+ true,
+ {
+ loadSuggestion: () => true,
+ onSuggestionLoaded: () => false,
+ },
+ ],
+ suggestion: [
+ null,
+ {
+ onSuggestionLoaded: (_, { suggestion }) => suggestion,
+ },
+ ],
+ suggestedPromotedDocuments: [
+ [],
+ {
+ onSuggestionLoaded: (_, { suggestedPromotedDocuments }) => suggestedPromotedDocuments,
+ },
+ ],
+ }),
+ listeners: ({ actions, props }) => ({
+ loadSuggestion: async () => {
+ const { http } = HttpLogic.values;
+ const { engineName } = EngineLogic.values;
+
+ try {
+ const response = await http.post(
+ `/internal/app_search/engines/${engineName}/search_relevance_suggestions/${props.query}`,
+ {
+ body: JSON.stringify({
+ page: {
+ current: 1,
+ size: 1,
+ },
+ filters: {
+ status: ['pending'],
+ type: 'curation',
+ },
+ }),
+ }
+ );
+
+ const suggestion = response.results[0];
+
+ const searchResponse = await http.post(
+ `/internal/app_search/engines/${engineName}/search`,
+ {
+ query: { query: '' },
+ body: JSON.stringify({
+ page: {
+ size: 100,
+ },
+ filters: {
+ id: suggestion.promoted,
+ },
+ }),
+ }
+ );
+
+ // Filter out docs that were not found and maintain promoted order
+ const promotedIds: string[] = suggestion.promoted;
+ const documentDetails = searchResponse.results;
+ const suggestedPromotedDocuments = promotedIds.reduce((acc: Result[], id: string) => {
+ const found = documentDetails.find(
+ (documentDetail: Result) => documentDetail.id.raw === id
+ );
+ if (!found) return acc;
+ return [...acc, found];
+ }, []);
+
+ actions.onSuggestionLoaded({
+ suggestion: suggestion as CurationSuggestion,
+ suggestedPromotedDocuments,
+ });
+ } catch (e) {
+ flashAPIErrors(e);
+ }
+ },
+ }),
+});
diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.test.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.test.ts
index 4fc62d18857362..2bdcfb9fe9d58d 100644
--- a/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.test.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.test.ts
@@ -115,4 +115,28 @@ describe('search relevance insights routes', () => {
});
});
});
+
+ describe('POST /internal/app_search/engines/{name}/search_relevance_suggestions/{query}', () => {
+ const mockRouter = new MockRouter({
+ method: 'post',
+ path: '/internal/app_search/engines/{engineName}/search_relevance_suggestions/{query}',
+ });
+
+ beforeEach(() => {
+ registerSearchRelevanceSuggestionsRoutes({
+ ...mockDependencies,
+ router: mockRouter.router,
+ });
+ });
+
+ it('creates a request to enterprise search', () => {
+ mockRouter.callRoute({
+ params: { engineName: 'some-engine', query: 'foo' },
+ });
+
+ expect(mockRequestHandler.createRequest).toHaveBeenCalledWith({
+ path: '/api/as/v0/engines/:engineName/search_relevance_suggestions/:query',
+ });
+ });
+ });
});
diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.ts
index 1ba9d9fa0ac53c..8b3b204c24d70c 100644
--- a/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/app_search/search_relevance_suggestions.ts
@@ -80,4 +80,29 @@ export function registerSearchRelevanceSuggestionsRoutes({
path: '/api/as/v0/engines/:engineName/search_relevance_suggestions/settings',
})
);
+
+ router.post(
+ {
+ path: '/internal/app_search/engines/{engineName}/search_relevance_suggestions/{query}',
+ validate: {
+ params: schema.object({
+ engineName: schema.string(),
+ query: schema.string(),
+ }),
+ body: schema.object({
+ page: schema.object({
+ current: schema.number(),
+ size: schema.number(),
+ }),
+ filters: schema.object({
+ status: schema.arrayOf(schema.string()),
+ type: schema.string(),
+ }),
+ }),
+ },
+ },
+ enterpriseSearchRequestHandler.createRequest({
+ path: '/api/as/v0/engines/:engineName/search_relevance_suggestions/:query',
+ })
+ );
}