Skip to content

Commit

Permalink
Improve presets for use cases (#322)
Browse files Browse the repository at this point in the history
Signed-off-by: Tyler Ohlsen <[email protected]>
(cherry picked from commit ee56015)
  • Loading branch information
ohltyler authored and github-actions[bot] committed Aug 28, 2024
1 parent b3edc41 commit 2c05046
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 26 deletions.
99 changes: 91 additions & 8 deletions common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export const SHARED_OPTIONAL_FIELDS = ['max_chunk_limit', 'description', 'tag'];
*/
export const VECTOR_FIELD_PATTERN = `{{vector_field}}`;
export const TEXT_FIELD_PATTERN = `{{text_field}}`;
export const IMAGE_FIELD_PATTERN = `{{image_field}}`;
export const QUERY_TEXT_PATTERN = `{{query_text}}`;
export const QUERY_IMAGE_PATTERN = `{{query_image}}`;
export const MODEL_ID_PATTERN = `{{model_id}}`;
Expand All @@ -163,7 +164,30 @@ export const FETCH_ALL_QUERY = {
},
size: 1000,
};
export const SEMANTIC_SEARCH_QUERY = {
export const TERM_QUERY = {
query: {
term: {
[TEXT_FIELD_PATTERN]: {
value: QUERY_TEXT_PATTERN,
},
},
},
};
export const KNN_QUERY = {
_source: {
excludes: [VECTOR_FIELD_PATTERN],
},
query: {
knn: {
[VECTOR_FIELD_PATTERN]: {
vector: `{{vector}}`,
},
k: 10,
model_id: MODEL_ID_PATTERN,
},
},
};
export const SEMANTIC_SEARCH_QUERY_NEURAL = {
_source: {
excludes: [VECTOR_FIELD_PATTERN],
},
Expand All @@ -177,7 +201,7 @@ export const SEMANTIC_SEARCH_QUERY = {
},
},
};
export const MULTIMODAL_SEARCH_QUERY = {
export const MULTIMODAL_SEARCH_QUERY_NEURAL = {
_source: {
excludes: [VECTOR_FIELD_PATTERN],
},
Expand All @@ -192,7 +216,25 @@ export const MULTIMODAL_SEARCH_QUERY = {
},
},
};
export const HYBRID_SEARCH_QUERY = {
export const MULTIMODAL_SEARCH_QUERY_BOOL = {
query: {
bool: {
must: [
{
match: {
[TEXT_FIELD_PATTERN]: QUERY_TEXT_PATTERN,
},
},
{
match: {
[IMAGE_FIELD_PATTERN]: QUERY_IMAGE_PATTERN,
},
},
],
},
},
};
export const HYBRID_SEARCH_QUERY_MATCH_NEURAL = {
_source: {
excludes: [VECTOR_FIELD_PATTERN],
},
Expand All @@ -219,23 +261,64 @@ export const HYBRID_SEARCH_QUERY = {
},
},
};
export const HYBRID_SEARCH_QUERY_MATCH_TERM = {
_source: {
excludes: [VECTOR_FIELD_PATTERN],
},
query: {
hybrid: {
queries: [
{
match: {
[TEXT_FIELD_PATTERN]: {
query: QUERY_TEXT_PATTERN,
},
},
},
{
term: {
[TEXT_FIELD_PATTERN]: {
value: QUERY_TEXT_PATTERN,
},
},
},
],
},
},
};

export const QUERY_PRESETS = [
{
name: 'Fetch all',
query: customStringify(FETCH_ALL_QUERY),
},
{
name: WORKFLOW_TYPE.SEMANTIC_SEARCH,
query: customStringify(SEMANTIC_SEARCH_QUERY),
name: 'Term',
query: customStringify(TERM_QUERY),
},
{
name: 'Basic k-NN',
query: customStringify(KNN_QUERY),
},
{
name: `${WORKFLOW_TYPE.SEMANTIC_SEARCH} (neural)`,
query: customStringify(SEMANTIC_SEARCH_QUERY_NEURAL),
},
{
name: WORKFLOW_TYPE.MULTIMODAL_SEARCH,
query: customStringify(MULTIMODAL_SEARCH_QUERY),
query: customStringify(MULTIMODAL_SEARCH_QUERY_BOOL),
},
{
name: `${WORKFLOW_TYPE.MULTIMODAL_SEARCH} (neural)`,
query: customStringify(MULTIMODAL_SEARCH_QUERY_NEURAL),
},
{
name: `Hybrid search (match & term queries)`,
query: customStringify(HYBRID_SEARCH_QUERY_MATCH_TERM),
},
{
name: WORKFLOW_TYPE.HYBRID_SEARCH,
query: customStringify(HYBRID_SEARCH_QUERY),
name: `Hybrid search (match & neural queries)`,
query: customStringify(HYBRID_SEARCH_QUERY_MATCH_NEURAL),
},
] as QueryPreset[];

Expand Down
1 change: 1 addition & 0 deletions common/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ export type QuickConfigureFields = {
embeddingModelId?: string;
vectorField?: string;
textField?: string;
imageField?: string;
embeddingLength?: number;
};

Expand Down
20 changes: 20 additions & 0 deletions public/pages/workflows/new_workflow/quick_configure_inputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,26 @@ export function QuickConfigureInputs(props: QuickConfigureInputsProps) {
/>
</EuiCompressedFormRow>
<EuiSpacer size="s" />
{props.workflowType === WORKFLOW_TYPE.MULTIMODAL_SEARCH && (
<>
<EuiCompressedFormRow
label={'Image field'}
isInvalid={false}
helpText="The name of the document field containing the image binary"
>
<EuiCompressedFieldText
value={fieldValues?.imageField || ''}
onChange={(e) => {
setFieldValues({
...fieldValues,
imageField: e.target.value,
});
}}
/>
</EuiCompressedFormRow>
<EuiSpacer size="s" />
</>
)}
<EuiCompressedFormRow
label={'Vector field'}
isInvalid={false}
Expand Down
70 changes: 64 additions & 6 deletions public/pages/workflows/new_workflow/quick_configure_modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ import {
EuiCompressedFormRow,
} from '@elastic/eui';
import {
EMPTY_MAP_ENTRY,
IMAGE_FIELD_PATTERN,
MODEL_ID_PATTERN,
MapArrayFormValue,
MapFormValue,
QuickConfigureFields,
TEXT_FIELD_PATTERN,
VECTOR_FIELD_PATTERN,
Expand Down Expand Up @@ -158,7 +161,8 @@ function injectQuickConfigureFields(
// Semantic search / hybrid search: set defaults in the ingest processor, the index mappings,
// and the preset query
case WORKFLOW_TYPE.SEMANTIC_SEARCH:
case WORKFLOW_TYPE.HYBRID_SEARCH: {
case WORKFLOW_TYPE.HYBRID_SEARCH:
case WORKFLOW_TYPE.MULTIMODAL_SEARCH: {
if (!isEmpty(quickConfigureFields) && workflow.ui_metadata?.config) {
workflow.ui_metadata.config = updateIngestProcessorConfig(
workflow.ui_metadata.config,
Expand All @@ -172,7 +176,12 @@ function injectQuickConfigureFields(
workflow.ui_metadata.config,
quickConfigureFields
);
workflow.ui_metadata.config = updateSearchRequestProcessorConfig(
workflow.ui_metadata.config,
quickConfigureFields
);
}
break;
}
case WORKFLOW_TYPE.CUSTOM:
case undefined:
Expand All @@ -183,7 +192,7 @@ function injectQuickConfigureFields(
return workflow;
}

// prefill ML ingest pipeline processor config, if applicable
// prefill ML ingest processor config, if applicable
function updateIngestProcessorConfig(
config: WorkflowConfig,
fields: QuickConfigureFields
Expand All @@ -192,10 +201,21 @@ function updateIngestProcessorConfig(
if (field.id === 'model' && fields.embeddingModelId) {
field.value = { id: fields.embeddingModelId };
}
if (field.id === 'input_map' && fields.textField) {
field.value = [
[{ key: '', value: fields.textField }],
] as MapArrayFormValue;
if (field.id === 'input_map' && (fields.textField || fields.imageField)) {
const inputMap = [] as MapFormValue;
if (fields.textField) {
inputMap.push({
key: '',
value: fields.textField,
});
}
if (fields.imageField) {
inputMap.push({
key: '',
value: fields.imageField,
});
}
field.value = [inputMap] as MapArrayFormValue;
}
if (field.id === 'output_map' && fields.vectorField) {
field.value = [
Expand All @@ -207,6 +227,23 @@ function updateIngestProcessorConfig(
return config;
}

// prefill ML search request processor config, if applicable
function updateSearchRequestProcessorConfig(
config: WorkflowConfig,
fields: QuickConfigureFields
): WorkflowConfig {
config.search.enrichRequest.processors[0].fields.forEach((field) => {
if (field.id === 'model' && fields.embeddingModelId) {
field.value = { id: fields.embeddingModelId };
}
if (field.id === 'input_map' || field.id === 'output_map') {
field.value = [[EMPTY_MAP_ENTRY]] as MapArrayFormValue;
}
});

return config;
}

// prefill index mappings/settings, if applicable
function updateIndexConfig(
config: WorkflowConfig,
Expand All @@ -226,6 +263,20 @@ function updateIndexConfig(
},
});
}
if (fields.imageField) {
const existingMappings = JSON.parse(
config.ingest.index.mappings.value as string
);
config.ingest.index.mappings.value = customStringify({
...existingMappings,
properties: {
...(existingMappings.properties || {}),
[fields.imageField]: {
type: 'binary',
},
},
});
}
if (fields.vectorField) {
const existingMappings = JSON.parse(
config.ingest.index.mappings.value as string
Expand Down Expand Up @@ -270,6 +321,13 @@ function updateSearchRequestConfig(
fields.vectorField
);
}
if (fields.imageField) {
config.search.request.value = ((config.search.request.value ||
'') as string).replace(
new RegExp(IMAGE_FIELD_PATTERN, 'g'),
fields.imageField
);
}

return config;
}
31 changes: 22 additions & 9 deletions public/pages/workflows/new_workflow/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
*/

import { snakeCase } from 'lodash';
import { MLIngestProcessor } from '../../../configs';
import {
MLIngestProcessor,
MLSearchRequestProcessor,
NormalizationProcessor,
} from '../../../configs';
import {
WorkflowTemplate,
START_FROM_SCRATCH_WORKFLOW_NAME,
Expand All @@ -13,9 +17,8 @@ import {
WORKFLOW_TYPE,
FETCH_ALL_QUERY,
customStringify,
SEMANTIC_SEARCH_QUERY,
MULTIMODAL_SEARCH_QUERY,
HYBRID_SEARCH_QUERY,
TERM_QUERY,
MULTIMODAL_SEARCH_QUERY_BOOL,
} from '../../../../common';
import { generateId } from '../../../utils';

Expand Down Expand Up @@ -125,9 +128,10 @@ function fetchSemanticSearchMetadata(): UIState {
baseState.config.ingest.index.settings.value = customStringify({
[`index.knn`]: true,
});
baseState.config.search.request.value = customStringify(
SEMANTIC_SEARCH_QUERY
);
baseState.config.search.request.value = customStringify(TERM_QUERY);
baseState.config.search.enrichRequest.processors = [
new MLSearchRequestProcessor().toObj(),
];
return baseState;
}

Expand All @@ -140,8 +144,11 @@ function fetchMultimodalSearchMetadata(): UIState {
[`index.knn`]: true,
});
baseState.config.search.request.value = customStringify(
MULTIMODAL_SEARCH_QUERY
MULTIMODAL_SEARCH_QUERY_BOOL
);
baseState.config.search.enrichRequest.processors = [
new MLSearchRequestProcessor().toObj(),
];
return baseState;
}

Expand All @@ -153,7 +160,13 @@ function fetchHybridSearchMetadata(): UIState {
baseState.config.ingest.index.settings.value = customStringify({
[`index.knn`]: true,
});
baseState.config.search.request.value = customStringify(HYBRID_SEARCH_QUERY);
baseState.config.search.request.value = customStringify(TERM_QUERY);
baseState.config.search.enrichResponse.processors = [
new NormalizationProcessor().toObj(),
];
baseState.config.search.enrichRequest.processors = [
new MLSearchRequestProcessor().toObj(),
];
return baseState;
}

Expand Down
2 changes: 1 addition & 1 deletion server/resources/templates/hybrid_search.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Hybrid Search",
"description": "A basic workflow containing the ingest pipeline and index configurations for performing hybrid search",
"description": "A basic workflow containing the ingest pipeline, search pipeline, and index configurations for performing hybrid search",
"version": {
"template": "1.0.0",
"compatibility": [
Expand Down
2 changes: 1 addition & 1 deletion server/resources/templates/multimodal_search.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Multimodal Search",
"description": "A basic workflow containing the ingest pipeline and index configurations for performing multimodal search",
"description": "A basic workflow containing the ingest pipeline, search pipeline, and index configurations for performing multimodal search",
"version": {
"template": "1.0.0",
"compatibility": [
Expand Down
Loading

0 comments on commit 2c05046

Please sign in to comment.