diff --git a/kubernetes/loculus/templates/_siloDatabaseConfig.tpl b/kubernetes/loculus/templates/_siloDatabaseConfig.tpl index 7a7c00951..053422be9 100644 --- a/kubernetes/loculus/templates/_siloDatabaseConfig.tpl +++ b/kubernetes/loculus/templates/_siloDatabaseConfig.tpl @@ -4,8 +4,8 @@ {{- if .generateIndex }} generateIndex: {{ .generateIndex }} {{- end }} - {{- if .lapisAllowsRegexSearch }} - lapisAllowsRegexSearch: {{ .lapisAllowsRegexSearch }} + {{- if eq .type "authors" }} + lapisAllowsRegexSearch: true {{- end }} {{- end }} diff --git a/kubernetes/loculus/values.yaml b/kubernetes/loculus/values.yaml index 6f5707733..1ffbd62d1 100644 --- a/kubernetes/loculus/values.yaml +++ b/kubernetes/loculus/values.yaml @@ -419,7 +419,6 @@ defaultOrganismConfig: &defaultOrganismConfig header: Authors truncateColumnDisplayTo: 15 ingest: ncbi_submitter_names - lapisAllowsRegexSearch: true - name: author_affiliations displayName: Author affiliations generateIndex: true diff --git a/website/src/components/SearchPage/SearchFullUI.tsx b/website/src/components/SearchPage/SearchFullUI.tsx index 6944504e2..d13318e7e 100644 --- a/website/src/components/SearchPage/SearchFullUI.tsx +++ b/website/src/components/SearchPage/SearchFullUI.tsx @@ -175,8 +175,8 @@ export const InnerSearchFullUI = ({ const detailsHook = hooks.useDetails({}, {}); const lapisSearchParameters = useMemo(() => { - return getLapisSearchParameters(fieldValues, referenceGenomesSequenceNames); - }, [fieldValues, referenceGenomesSequenceNames]); + return getLapisSearchParameters(fieldValues, referenceGenomesSequenceNames, schema); + }, [fieldValues, referenceGenomesSequenceNames, schema]); useEffect(() => { aggregatedHook.mutate({ diff --git a/website/src/utils/search.ts b/website/src/utils/search.ts index 56340b0bc..235470718 100644 --- a/website/src/utils/search.ts +++ b/website/src/utils/search.ts @@ -146,13 +146,29 @@ const textAccessionsToList = (text: string): string[] => { return accessions; }; +const makeCaseInsensitiveLiteralSubstringRegex = (s: string): string => { + // takes raw string and escapes all special characters and prefixes (?i) for case insensitivity + return `(?i)${s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`; +}; + export const getLapisSearchParameters = ( fieldValues: Record, referenceGenomesSequenceNames: ReferenceGenomesSequenceNames, + schema: Schema, ): Record => { + const expandedSchema = getMetadataSchemaWithExpandedRanges(schema.metadata); + const sequenceFilters = Object.fromEntries( Object.entries(fieldValues).filter(([, value]) => value !== undefined && value !== ''), ); + for (const field of expandedSchema) { + if (field.type === 'authors' && sequenceFilters[field.name] !== undefined) { + sequenceFilters[field.name.concat('$regex')] = makeCaseInsensitiveLiteralSubstringRegex( + sequenceFilters[field.name], + ); + delete sequenceFilters[field.name]; + } + } if (sequenceFilters.accession !== '' && sequenceFilters.accession !== undefined) { sequenceFilters.accession = textAccessionsToList(sequenceFilters.accession); diff --git a/website/src/utils/serversideSearch.ts b/website/src/utils/serversideSearch.ts index 198daf70b..6c5c12e26 100644 --- a/website/src/utils/serversideSearch.ts +++ b/website/src/utils/serversideSearch.ts @@ -21,7 +21,7 @@ export const performLapisSearchQueries = async ( organism: string, ): Promise => { const fieldValues = getFieldValuesFromQuery(state, hiddenFieldValues, schema); - const lapisSearchParameters = getLapisSearchParameters(fieldValues, referenceGenomesSequenceNames); + const lapisSearchParameters = getLapisSearchParameters(fieldValues, referenceGenomesSequenceNames, schema); const orderByField = ORDER_KEY in state ? state[ORDER_KEY] : schema.defaultOrderBy; const orderDirection = state[ORDER_DIRECTION_KEY] ?? schema.defaultOrder;