-
Notifications
You must be signed in to change notification settings - Fork 100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add autocomplete enhancements #507
Merged
eugenesk24
merged 11 commits into
opensearch-project:main
from
eugenesk24:more-autocomplete-enhancements
Feb 28, 2022
Merged
Changes from 5 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
0250453
Support strings, numbers, booleans in autocomplete data type
eugenesk24 10f0523
Only suggest number type fields after stats
eugenesk24 f6b028d
Facilitates multiple indices
eugenesk24 ccc9f60
Suggest span in progress
eugenesk24 05b15b8
Suggest span in autocomplete
eugenesk24 bc282b0
Only update if in edit mode
eugenesk24 76abbe0
Hide duplicate and addSample for now
eugenesk24 8041aaa
Change metrics to panel again
eugenesk24 859cd0e
Change button to add
eugenesk24 7964f17
Disable edit visualizations button
eugenesk24 c0008c1
Remove comment
eugenesk24 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,15 +51,19 @@ import { | |
PIPE_COMMA_AFTER_SORT_FIELD, | ||
PLUS_MINUS_FIELD_IN_FIELDS_LOOP, | ||
FIELD_AFTER_COMMAND, | ||
FIELD_AFTER_STATS_GROUP_BY, | ||
FIELD_AFTER_AGGREGATION, | ||
FIELD_SPAN_AFTER_GROUP_BY, | ||
NUM_FIELD_AFTER_AGGREGATION, | ||
CLOSE_AFTER_FIELD, | ||
PIPE_COMMA_BY_AFTER_AGGREGATION, | ||
PIPE_AFTER_STATS_GROUP_BY, | ||
AGGREGATION_FOR_STATS, | ||
FIELD_AFTER_SPAN, | ||
CLOSE_AFTER_SPAN, | ||
PIPE_AFTER_SPAN, | ||
} from '../../../../common/constants/autocomplete'; | ||
|
||
let currIndex: string = ''; | ||
// let currIndex: string = ''; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we remove this line if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes! Good catch. |
||
let currIndices: string[] = []; | ||
let currField: string = ''; | ||
let currFieldType: string = ''; | ||
|
||
|
@@ -89,65 +93,74 @@ const getIndices = async (dslService: DSLService): Promise<void> => { | |
}; | ||
|
||
const getFields = async (dslService: DSLService): Promise<void> => { | ||
if (currIndex !== '') { | ||
const res = await dslService.fetchFields(currIndex); | ||
if (!isEmpty(currIndices)) { | ||
fieldsFromBackend.length = 0; | ||
if (!res) { | ||
return; | ||
} | ||
const resFieldList = Object.keys(res?.[currIndex].mappings.properties); | ||
for (let i = 0; i < resFieldList.length; i++) { | ||
const element = resFieldList[i]; | ||
if ( | ||
res?.[currIndex].mappings.properties[element].properties || | ||
res?.[currIndex].mappings.properties[element].fields | ||
) { | ||
fieldsFromBackend.push({ label: element, type: 'string' }); | ||
} else if (res?.[currIndex].mappings.properties[element].type === 'keyword') { | ||
fieldsFromBackend.push({ label: element, type: 'string' }); | ||
} else { | ||
fieldsFromBackend.push({ | ||
label: element, | ||
type: res?.[currIndex].mappings.properties[element].type, | ||
}); | ||
for (let i = 0; i < currIndices.length; i++) { | ||
const index = currIndices[i]; | ||
const res = await dslService.fetchFields(index); | ||
if (!res) { | ||
return; | ||
} | ||
const resFieldList = Object.keys(res?.[index].mappings.properties); | ||
for (let j = 0; j < resFieldList.length; j++) { | ||
const element = resFieldList[j]; | ||
if ( | ||
res?.[index].mappings.properties[element].properties || | ||
res?.[index].mappings.properties[element].fields | ||
) { | ||
fieldsFromBackend.push({ label: element, type: 'string' }); | ||
} else if (res?.[index].mappings.properties[element].type === 'keyword') { | ||
fieldsFromBackend.push({ label: element, type: 'string' }); | ||
} else { | ||
fieldsFromBackend.push({ | ||
label: element, | ||
type: res?.[index].mappings.properties[element].type, | ||
}); | ||
} | ||
fieldList.push(element); | ||
} | ||
fieldList.push(element); | ||
} | ||
} | ||
}; | ||
|
||
const getDataValues = async ( | ||
index: string, | ||
indices: string[], | ||
field: string, | ||
fieldType: string, | ||
dslService: DSLService | ||
): Promise<DataItem[]> => { | ||
const res = | ||
(await dslService.fetch(getDataValueQuery(index, field)))?.aggregations?.top_tags?.buckets || | ||
[]; | ||
dataValuesFromBackend.length = 0; | ||
res.forEach((e: any) => { | ||
if (fieldType === 'string') { | ||
dataValuesFromBackend.push({ label: '"' + e.key + '"', doc_count: e.doc_count }); | ||
} else if (fieldType === 'boolean') { | ||
if (e.key === 1) { | ||
dataValuesFromBackend.push({ label: 'True', doc_count: e.doc_count }); | ||
} else { | ||
dataValuesFromBackend.push({ label: 'False', doc_count: e.doc_count }); | ||
} | ||
} else if (fieldType !== 'geo_point') { | ||
dataValuesFromBackend.push({ label: String(e.key), doc_count: e.doc_count }); | ||
for (let i = 0; i < indices.length; i++) { | ||
const index = indices[i]; | ||
const res = (await dslService.fetch(getDataValueQuery(index, field)))?.aggregations?.top_tags | ||
?.buckets; | ||
if (isEmpty(res)) { | ||
continue; | ||
} | ||
}); | ||
return dataValuesFromBackend; | ||
dataValuesFromBackend.length = 0; | ||
res.forEach((e: any) => { | ||
if (fieldType === 'string') { | ||
dataValuesFromBackend.push({ label: '"' + e.key + '"', doc_count: e.doc_count }); | ||
} else if (fieldType === 'boolean') { | ||
if (e.key === 1) { | ||
dataValuesFromBackend.push({ label: 'True', doc_count: e.doc_count }); | ||
} else { | ||
dataValuesFromBackend.push({ label: 'False', doc_count: e.doc_count }); | ||
} | ||
} else if (fieldType !== 'geo_point') { | ||
dataValuesFromBackend.push({ label: String(e.key), doc_count: e.doc_count }); | ||
} | ||
}); | ||
return dataValuesFromBackend; | ||
} | ||
return []; | ||
}; | ||
|
||
export const onItemSelect = async ( | ||
{ setQuery, item }: { setQuery: any; item: any }, | ||
dslService: DSLService | ||
) => { | ||
if (fieldsFromBackend.length === 0 && indexList.includes(item.itemName)) { | ||
currIndex = item.itemName; | ||
currIndices = [item.itemName]; | ||
getFields(dslService); | ||
} | ||
setQuery(item.label + ' '); | ||
|
@@ -199,7 +212,7 @@ export const getFullSuggestions = async ( | |
// Check the last full word in the query, then suggest inputs based off that | ||
if (splittedModel.length === 1) { | ||
currField = ''; | ||
currIndex = ''; | ||
currIndices = []; | ||
return getFirstPipe(str, dslService); | ||
} else if (splittedModel.length > 1) { | ||
// Suggest commands after pipe | ||
|
@@ -233,7 +246,7 @@ export const getFullSuggestions = async ( | |
return fillSuggestions(str, prefix, indicesFromBackend); | ||
// Suggest pipe after setting source | ||
} else if (indexList.includes(splittedModel[splittedModel.length - 2])) { | ||
currIndex = splittedModel[splittedModel.length - 2]; | ||
currIndices = [splittedModel[splittedModel.length - 2]]; | ||
getFields(dslService); | ||
return filterSuggestions( | ||
[{ label: str + '|', input: str, suggestion: '|', itemName: '|' }], | ||
|
@@ -336,13 +349,13 @@ export const getFullSuggestions = async ( | |
fieldsFromBackend.find( | ||
(field: { label: string; type: string }) => field.label === currField | ||
)?.type || ''; | ||
await getDataValues(currIndex, currField, currFieldType, dslService); | ||
await getDataValues(currIndices, currField, currFieldType, dslService); | ||
return filterSuggestions(fullSuggestions, lowerPrefix); | ||
// Suggest , after match([field] | ||
} else if (inMatch && fieldList.includes(splittedModel[splittedModel.length - 2])) { | ||
currField = splittedModel[splittedModel.length - 2]; | ||
currFieldType = fieldsFromBackend.find((field) => field.label === currField)?.type || ''; | ||
await getDataValues(currIndex, currField, currFieldType, dslService); | ||
await getDataValues(currIndices, currField, currFieldType, dslService); | ||
return filterSuggestions( | ||
[{ label: str + ',', input: str, suggestion: ',', itemName: ',' }], | ||
lowerPrefix | ||
|
@@ -387,14 +400,17 @@ export const getFullSuggestions = async ( | |
return []; | ||
}; | ||
|
||
const parseForIndex = (query: string) => { | ||
const parseForIndices = (query: string) => { | ||
for (let i = 0; i < regexForIndex.length; i++) { | ||
const groupArray = regexForIndex[i].exec(query); | ||
if (groupArray) { | ||
return groupArray[1]; | ||
const afterEqual = query.substring(query.indexOf('=') + 1); | ||
const beforePipe = afterEqual.substring(0, afterEqual.indexOf('|')) || afterEqual; | ||
const noSpaces = beforePipe.replaceAll(/\s/g, ''); | ||
return noSpaces.split(','); | ||
} | ||
} | ||
return ''; | ||
return []; | ||
}; | ||
|
||
const parseForNextSuggestion = (command: string) => { | ||
|
@@ -418,8 +434,8 @@ export const getSuggestionsAfterSource = async ( | |
const lastWord = splitSpaceQuery[splitSpaceQuery.length - 1]; | ||
const lastCommand = splitPipeQuery[splitPipeQuery.length - 1]; | ||
|
||
if (isEmpty(currQuery)) { | ||
currIndex = parseForIndex(base); | ||
if (isEmpty(currQuery) || isEmpty(currIndices)) { | ||
currIndices = parseForIndices(base); | ||
getFields(dslService); | ||
currField = ''; | ||
currFieldType = ''; | ||
|
@@ -475,12 +491,24 @@ export const getSuggestionsAfterSource = async ( | |
]); | ||
case CLOSE_AFTER_DATA: | ||
case CLOSE_AFTER_FIELD: | ||
case CLOSE_AFTER_SPAN: | ||
return fillSuggestions(currQuery, lastWord, [{ label: ')' }]); | ||
case COMMA_AFTER_FIELD: | ||
currField = COMMA_AFTER_FIELD.exec(lastCommand)![1]; | ||
currFieldType = fieldsFromBackend.find((field) => field.label === currField)?.type || ''; | ||
await getDataValues(currIndex, currField, currFieldType, dslService); | ||
await getDataValues(currIndices, currField, currFieldType, dslService); | ||
return fillSuggestions(currQuery, lastWord, [{ label: ',' }]); | ||
case FIELD_AFTER_SPAN: | ||
const matchArray = FIELD_AFTER_SPAN.exec(lastCommand); | ||
const tempField = matchArray![matchArray!.length - 1]; | ||
if (fieldList.includes(tempField)) { | ||
currField = tempField; | ||
currFieldType = fieldsFromBackend.find((field) => field.label === currField)?.type || ''; | ||
await getDataValues(currIndices, currField, currFieldType, dslService); | ||
return fillSuggestions(currQuery, lastWord, [{ label: ',' }]); | ||
} else { | ||
return fillSuggestions(currQuery, lastWord, fieldsFromBackend); | ||
} | ||
case FIELD_AFTER_COMMAND: | ||
case FIELD_IN_FIELD_LOOP: | ||
case FIELD_AFTER_EVAL_EQUAL: | ||
|
@@ -490,16 +518,22 @@ export const getSuggestionsAfterSource = async ( | |
case FIELD_AFTER_BY: | ||
case FIELD_AFTER_COMMA: | ||
case FIELD_AFTER_PLUS_MINUS_SORT: | ||
case FIELD_AFTER_STATS_GROUP_BY: | ||
case FIELD_AFTER_AGGREGATION: | ||
return fillSuggestions(currQuery, lastWord, fieldsFromBackend); | ||
case FIELD_SPAN_AFTER_GROUP_BY: | ||
return fillSuggestions(currQuery, lastWord, [{ label: 'span(' }, ...fieldsFromBackend]); | ||
case NUM_FIELD_AFTER_AGGREGATION: | ||
const numberFields = fieldsFromBackend.filter((field: { type: string }) => | ||
numberTypes.includes(field.type) | ||
); | ||
return fillSuggestions(currQuery, lastWord, numberFields); | ||
case PIPE_AFTER_WHERE: | ||
case PIPE_AFTER_MATCH: | ||
case PIPE_AFTER_KEEP_EMPTY: | ||
case PIPE_AFTER_CONSECUTIVE: | ||
case PIPE_AFTER_GROUP_BY: | ||
case PIPE_AFTER_HEAD: | ||
case PIPE_AFTER_STATS_GROUP_BY: | ||
case PIPE_AFTER_SPAN: | ||
return fillSuggestions(currQuery, lastWord, [{ label: '|' }]); | ||
case DATA_AFTER_WHERE_EQUAL: | ||
case DATA_AFTER_COMMA: | ||
|
@@ -508,7 +542,7 @@ export const getSuggestionsAfterSource = async ( | |
case EQUAL_AFTER_EVAL_FIELD: | ||
currField = next.exec(lastCommand)![1]; | ||
currFieldType = fieldsFromBackend.find((field) => field.label === currField)?.type || ''; | ||
await getDataValues(currIndex, currField, currFieldType, dslService); | ||
await getDataValues(currIndices, currField, currFieldType, dslService); | ||
return fillSuggestions(currQuery, lastWord, [{ label: '=' }]); | ||
case MATCH_FIELD_AFTER_WHERE: | ||
return fillSuggestions(currQuery, lastWord, [{ label: 'match(' }, ...fieldsFromBackend]); | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the firstnvm it's not.. ignore this comment i need to read it again\s*
is redundant?