Skip to content

Commit

Permalink
query builder refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
SKarolFolio committed Oct 23, 2024
1 parent cd21f40 commit b8e3d8a
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 47 deletions.
6 changes: 6 additions & 0 deletions src/common/constants/complexLookup.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ export enum SearchableIndex {
Genre = 'genre',
}

export enum SearchableIndexQuerySelector {
Query = 'query',
Prev = 'prev',
Next = 'next',
}

export const COMPLEX_LOOKUPS_LINKED_FIELDS_MAPPING = {
subclass: {
PERSON: {
Expand Down
1 change: 1 addition & 0 deletions src/common/helpers/search/formatters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export const SEARCH_RESULTS_FORMATTER: Record<
string,
(data: any, sourceData?: SourceDataDTO) => SearchResultsTableRow[]
> = {
default: formatAuthorityItem,
authorities: formatAuthorityItem,
};
15 changes: 15 additions & 0 deletions src/common/helpers/search/queryBuilder/authorities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { SearchableIndexQuerySelector } from '@common/constants/complexLookup.constants';
import { SEARCH_QUERY_VALUE_PARAM } from '@common/constants/search.constants';

export const buildSearchQuery = ({
map,
selector = SearchableIndexQuerySelector.Query,
searchBy,
value,
}: BuildSearchQueryParams) => {
const searchableIndex = map?.[searchBy];

return searchableIndex?.[selector]?.replaceAll(SEARCH_QUERY_VALUE_PARAM, value);
};

export const buildBrowseQuery = () => {};
10 changes: 9 additions & 1 deletion src/common/helpers/search/queryBuilder/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
export { buildSearchQuery } from './queryBuilder';
import { buildSearchQuery } from './authorities';

export const SEARCH_QUERY_BUILDER: Record<
string,
({ map, selector, searchBy, value }: BuildSearchQueryParams) => string | undefined
> = {
default: buildSearchQuery,
authorities: buildSearchQuery,
};
7 changes: 0 additions & 7 deletions src/common/helpers/search/queryBuilder/queryBuilder.ts

This file was deleted.

9 changes: 2 additions & 7 deletions src/common/hooks/useLoadSearchResults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,8 @@ export const useLoadSearchResults = (fetchData: ({ query, searchBy, offset }: Fe
async function onLoad() {
setIsLoading(true);

if (getSearchSourceData) {
await getSearchSourceData();
}

if (getSearchFacetsData) {
await getSearchFacetsData();
}
await getSearchSourceData?.();
await getSearchFacetsData?.();

if (defaultSearchBy && defaultQuery) {
await fetchData({ query: defaultQuery as string, searchBy: defaultSearchBy, offset: 0 });
Expand Down
27 changes: 18 additions & 9 deletions src/common/hooks/useSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { SearchIdentifiers } from '@common/constants/search.constants';
import { StatusType } from '@common/constants/status.constants';
import { generateSearchParamsState, normalizeQuery } from '@common/helpers/search.helper';
import { normalizeLccn } from '@common/helpers/validations.helper';
import { buildSearchQuery } from '@common/helpers/search/queryBuilder';
import { UserNotificationFactory } from '@common/services/userNotification';
import { usePagination } from '@common/hooks/usePagination';
import state from '@state';
import { useSearchContext } from './useSearchContext';
import { SearchableIndexQuerySelector } from '@common/constants/complexLookup.constants';

export const useSearch = () => {
const {
Expand All @@ -30,6 +30,7 @@ export const useSearch = () => {
searchByControlOptions,
searchableIndicesMap,
getSearchSourceData,
buildSearchQuery,
} = useSearchContext();
const setIsLoading = useSetRecoilState(state.loadingState.isLoading);
const [searchBy, setSearchBy] = useRecoilState(state.search.index);
Expand Down Expand Up @@ -94,7 +95,13 @@ export const useSearch = () => {
);

const fetchData = useCallback(
async ({ query, searchBy, offset, selectedSegment }: FetchDataParams) => {
async ({
query,
searchBy,
offset,
selectedSegment,
baseQuerySelector = SearchableIndexQuerySelector.Query,
}: FetchDataParams) => {
setMessage('');
const selectedNavigationSegment = selectedSegment ?? navigationSegment?.value;

Expand All @@ -114,13 +121,15 @@ export const useSearch = () => {
isVisibleSegments && selectedNavigationSegment
? searchableIndicesMap?.[selectedNavigationSegment as SearchSegmentValue]
: searchableIndicesMap;
const generatedQuery = fetchSearchResults
? (buildSearchQuery(
selectedSearchableIndices as SearchableIndexEntries,
searchBy as unknown as SearchableIndexType,
updatedQuery,
) as string)
: (updatedQuery as string);
const generatedQuery =
fetchSearchResults && buildSearchQuery
? (buildSearchQuery({
map: selectedSearchableIndices as SearchableIndexEntries,
selector: baseQuerySelector,
searchBy: searchBy as unknown as SearchableIndexType,
value: updatedQuery,
}) as string)
: (updatedQuery as string);

const result = fetchSearchResults
? await fetchSearchResults({
Expand Down
3 changes: 3 additions & 0 deletions src/components/ComplexLookupField/ModalComplexLookup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { ComplexLookupSearchResults } from './ComplexLookupSearchResults';
import { MarсPreviewComplexLookup } from './MarсPreviewComplexLookup';
import { SEARCH_RESULTS_TABLE_CONFIG } from './configs';
import './ModalComplexLookup.scss';
import { SEARCH_QUERY_BUILDER } from '@common/helpers/search/queryBuilder';

interface ModalComplexLookupProps {
isOpen: boolean;
Expand Down Expand Up @@ -47,6 +48,7 @@ export const ModalComplexLookup: FC<ModalComplexLookupProps> = memo(
} = COMPLEX_LOOKUPS_CONFIG[assignEntityName];
const tableConfig = SEARCH_RESULTS_TABLE_CONFIG[assignEntityName] || SEARCH_RESULTS_TABLE_CONFIG.default;
const searchResultsFormatter = SEARCH_RESULTS_FORMATTER[assignEntityName] || SEARCH_RESULTS_FORMATTER.default;
const buildSearchQuery = SEARCH_QUERY_BUILDER[assignEntityName] || SEARCH_QUERY_BUILDER.default;

const setIsMarcPreviewOpen = useSetRecoilState(state.ui.isMarcPreviewOpen);
const setSearchQuery = useSetRecoilState(state.search.query);
Expand Down Expand Up @@ -166,6 +168,7 @@ export const ModalComplexLookup: FC<ModalComplexLookupProps> = memo(
getSearchSourceData={getSourceData}
getSearchFacetsData={getFacetsData}
fetchSearchResults={getSearchResults}
buildSearchQuery={buildSearchQuery}
searchResultsLimit={api.searchQuery.limit}
searchResultsContainer={api.results.containers}
onAssignRecord={onAssign}
Expand Down
53 changes: 33 additions & 20 deletions src/configs/complexLookup/complexLookupSeachableIndicesMap.ts
Original file line number Diff line number Diff line change
@@ -1,64 +1,77 @@
import { SearchableIndex } from '@common/constants/complexLookup.constants';
import { SearchableIndex, SearchableIndexQuerySelector } from '@common/constants/complexLookup.constants';
import { SEARCH_QUERY_VALUE_PARAM, SearchSegment } from '@common/constants/search.constants';

export const COMPLEX_LOOKUP_SEARCHABLE_INDICES_MAP: SearchableIndicesMap = {
[SearchSegment.Search]: {
[SearchableIndex.Keyword]: {
query: `(keyword=="${SEARCH_QUERY_VALUE_PARAM}" or naturalId="${SEARCH_QUERY_VALUE_PARAM}")`,
[SearchableIndexQuerySelector.Query]: `(keyword=="${SEARCH_QUERY_VALUE_PARAM}" or naturalId="${SEARCH_QUERY_VALUE_PARAM}")`,
},
[SearchableIndex.Identifier]: {
query: `((identifiers.value=="${SEARCH_QUERY_VALUE_PARAM}" or naturalId="${SEARCH_QUERY_VALUE_PARAM}") and authRefType=="Authorized")`,
[SearchableIndexQuerySelector.Query]: `((identifiers.value=="${SEARCH_QUERY_VALUE_PARAM}" or naturalId="${SEARCH_QUERY_VALUE_PARAM}") and authRefType=="Authorized")`,
},
[SearchableIndex.LCCN]: {
query: `lccn=="${SEARCH_QUERY_VALUE_PARAM}"`,
[SearchableIndexQuerySelector.Query]: `lccn=="${SEARCH_QUERY_VALUE_PARAM}"`,
},
[SearchableIndex.PersonalName]: {
query: `(personalName all "${SEARCH_QUERY_VALUE_PARAM}" or sftPersonalName all "${SEARCH_QUERY_VALUE_PARAM}" or saftPersonalName all "${SEARCH_QUERY_VALUE_PARAM}")`,
[SearchableIndexQuerySelector.Query]: `(personalName all "${SEARCH_QUERY_VALUE_PARAM}" or sftPersonalName all "${SEARCH_QUERY_VALUE_PARAM}" or saftPersonalName all "${SEARCH_QUERY_VALUE_PARAM}")`,
},
[SearchableIndex.CorporateConferenceName]: {
query: `(corporateName all "${SEARCH_QUERY_VALUE_PARAM}" or sftCorporateName all "${SEARCH_QUERY_VALUE_PARAM}" or saftCorporateName all "${SEARCH_QUERY_VALUE_PARAM}" or meetingName all "${SEARCH_QUERY_VALUE_PARAM}" or sftMeetingName all "${SEARCH_QUERY_VALUE_PARAM}" or saftMeetingName all "${SEARCH_QUERY_VALUE_PARAM}")`,
[SearchableIndexQuerySelector.Query]: `(corporateName all "${SEARCH_QUERY_VALUE_PARAM}" or sftCorporateName all "${SEARCH_QUERY_VALUE_PARAM}" or saftCorporateName all "${SEARCH_QUERY_VALUE_PARAM}" or meetingName all "${SEARCH_QUERY_VALUE_PARAM}" or sftMeetingName all "${SEARCH_QUERY_VALUE_PARAM}" or saftMeetingName all "${SEARCH_QUERY_VALUE_PARAM}")`,
},
[SearchableIndex.GeographicName]: {
query: `(geographicName all "${SEARCH_QUERY_VALUE_PARAM}" or sftGeographicName all "${SEARCH_QUERY_VALUE_PARAM}" or saftGeographicName all "${SEARCH_QUERY_VALUE_PARAM}")`,
[SearchableIndexQuerySelector.Query]: `(geographicName all "${SEARCH_QUERY_VALUE_PARAM}" or sftGeographicName all "${SEARCH_QUERY_VALUE_PARAM}" or saftGeographicName all "${SEARCH_QUERY_VALUE_PARAM}")`,
},
[SearchableIndex.NameTitle]: {
query: `(personalNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or sftPersonalNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or saftPersonalNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or corporateNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or sftCorporateNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or saftCorporateNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or meetingNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or sftMeetingNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or saftMeetingNameTitle all "${SEARCH_QUERY_VALUE_PARAM}")`,
[SearchableIndexQuerySelector.Query]: `(personalNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or sftPersonalNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or saftPersonalNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or corporateNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or sftCorporateNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or saftCorporateNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or meetingNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or sftMeetingNameTitle all "${SEARCH_QUERY_VALUE_PARAM}" or saftMeetingNameTitle all "${SEARCH_QUERY_VALUE_PARAM}")`,
},
[SearchableIndex.UniformTitle]: {
query: `(uniformTitle all "${SEARCH_QUERY_VALUE_PARAM}" or sftUniformTitle all "${SEARCH_QUERY_VALUE_PARAM}" or saftUniformTitle all "${SEARCH_QUERY_VALUE_PARAM}")`,
[SearchableIndexQuerySelector.Query]: `(uniformTitle all "${SEARCH_QUERY_VALUE_PARAM}" or sftUniformTitle all "${SEARCH_QUERY_VALUE_PARAM}" or saftUniformTitle all "${SEARCH_QUERY_VALUE_PARAM}")`,
},
[SearchableIndex.Subject]: {
query: `(topicalTerm all "${SEARCH_QUERY_VALUE_PARAM}" or sftTopicalTerm all "${SEARCH_QUERY_VALUE_PARAM}" or saftTopicalTerm all "${SEARCH_QUERY_VALUE_PARAM}")`,
[SearchableIndexQuerySelector.Query]: `(topicalTerm all "${SEARCH_QUERY_VALUE_PARAM}" or sftTopicalTerm all "${SEARCH_QUERY_VALUE_PARAM}" or saftTopicalTerm all "${SEARCH_QUERY_VALUE_PARAM}")`,
},
[SearchableIndex.ChildrenSubjectHeading]: {
query: `((keyword all "${SEARCH_QUERY_VALUE_PARAM}" or naturalId="${SEARCH_QUERY_VALUE_PARAM}") and subjectHeadings=="b")`,
[SearchableIndexQuerySelector.Query]: `((keyword all "${SEARCH_QUERY_VALUE_PARAM}" or naturalId="${SEARCH_QUERY_VALUE_PARAM}") and subjectHeadings=="b")`,
},
[SearchableIndex.Genre]: {
query: `(genreTerm all "${SEARCH_QUERY_VALUE_PARAM}" or sftGenreTerm all "${SEARCH_QUERY_VALUE_PARAM}" or saftGenreTerm all "${SEARCH_QUERY_VALUE_PARAM}")`,
[SearchableIndexQuerySelector.Query]: `(genreTerm all "${SEARCH_QUERY_VALUE_PARAM}" or sftGenreTerm all "${SEARCH_QUERY_VALUE_PARAM}" or saftGenreTerm all "${SEARCH_QUERY_VALUE_PARAM}")`,
},
},
// TODO: dynamically generate browse queries
[SearchSegment.Browse]: {
[SearchableIndex.PersonalName]: {
query: `(headingRef>="${SEARCH_QUERY_VALUE_PARAM}" or headingRef<"${SEARCH_QUERY_VALUE_PARAM}") and isTitleHeadingRef==false and headingType==("Personal Name")`,
[SearchableIndexQuerySelector.Query]: `(headingRef>="${SEARCH_QUERY_VALUE_PARAM}" or headingRef<"${SEARCH_QUERY_VALUE_PARAM}") and isTitleHeadingRef==false and headingType==("Personal Name")`,
[SearchableIndexQuerySelector.Prev]: `headingRef<"${SEARCH_QUERY_VALUE_PARAM}" and isTitleHeadingRef==false and headingType==("Personal Name")`,
[SearchableIndexQuerySelector.Next]: `headingRef>"${SEARCH_QUERY_VALUE_PARAM}" and isTitleHeadingRef==false and headingType==("Personal Name")`,
},
[SearchableIndex.CorporateConferenceName]: {
query: `(headingRef>="${SEARCH_QUERY_VALUE_PARAM}" or headingRef<"${SEARCH_QUERY_VALUE_PARAM}") and isTitleHeadingRef==false and headingType==("Conference Name" or "Corporate Name")`,
[SearchableIndexQuerySelector.Query]: `(headingRef>="${SEARCH_QUERY_VALUE_PARAM}" or headingRef<"${SEARCH_QUERY_VALUE_PARAM}") and isTitleHeadingRef==false and headingType==("Conference Name" or "Corporate Name")`,
[SearchableIndexQuerySelector.Prev]: `headingRef<"${SEARCH_QUERY_VALUE_PARAM}" and isTitleHeadingRef==false and headingType==("Conference Name" or "Corporate Name")`,
[SearchableIndexQuerySelector.Next]: `headingRef>"${SEARCH_QUERY_VALUE_PARAM}" and isTitleHeadingRef==false and headingType==("Conference Name" or "Corporate Name")`,
},
[SearchableIndex.GeographicName]: {
query: `(headingRef>="${SEARCH_QUERY_VALUE_PARAM}" or headingRef<"${SEARCH_QUERY_VALUE_PARAM}") and isTitleHeadingRef==false and headingType==("Geographic Name")`,
[SearchableIndexQuerySelector.Query]: `(headingRef>="${SEARCH_QUERY_VALUE_PARAM}" or headingRef<"${SEARCH_QUERY_VALUE_PARAM}") and isTitleHeadingRef==false and headingType==("Geographic Name")`,
[SearchableIndexQuerySelector.Prev]: `headingRef<"${SEARCH_QUERY_VALUE_PARAM}" and isTitleHeadingRef==false and headingType==("Geographic Name")`,
[SearchableIndexQuerySelector.Next]: `headingRef>"${SEARCH_QUERY_VALUE_PARAM}" and isTitleHeadingRef==false and headingType==("Geographic Name")`,
},
[SearchableIndex.NameTitle]: {
query: `(headingRef>="${SEARCH_QUERY_VALUE_PARAM}" or headingRef<"${SEARCH_QUERY_VALUE_PARAM}") and isTitleHeadingRef==true and headingType==("Conference Name" or "Corporate Name" or "Personal Name")`,
[SearchableIndexQuerySelector.Query]: `(headingRef>="${SEARCH_QUERY_VALUE_PARAM}" or headingRef<"${SEARCH_QUERY_VALUE_PARAM}") and isTitleHeadingRef==true and headingType==("Conference Name" or "Corporate Name" or "Personal Name")`,
[SearchableIndexQuerySelector.Prev]: `headingRef<"${SEARCH_QUERY_VALUE_PARAM}" and isTitleHeadingRef==true and headingType==("Conference Name" or "Corporate Name" or "Personal Name")`,
[SearchableIndexQuerySelector.Next]: `headingRef>"${SEARCH_QUERY_VALUE_PARAM}" and isTitleHeadingRef==true and headingType==("Conference Name" or "Corporate Name" or "Personal Name")`,
},
[SearchableIndex.UniformTitle]: {
query: `(headingRef>="${SEARCH_QUERY_VALUE_PARAM}" or headingRef<"${SEARCH_QUERY_VALUE_PARAM}") and isTitleHeadingRef==false and headingType==("Uniform Title")`,
[SearchableIndexQuerySelector.Query]: `(headingRef>="${SEARCH_QUERY_VALUE_PARAM}" or headingRef<"${SEARCH_QUERY_VALUE_PARAM}") and isTitleHeadingRef==false and headingType==("Uniform Title")`,
[SearchableIndexQuerySelector.Prev]: `headingRef<"${SEARCH_QUERY_VALUE_PARAM}" and isTitleHeadingRef==false and headingType==("Uniform Title")`,
[SearchableIndexQuerySelector.Next]: `headingRef>"${SEARCH_QUERY_VALUE_PARAM}" and isTitleHeadingRef==false and headingType==("Uniform Title")`,
},
[SearchableIndex.Subject]: {
query: `(headingRef>="${SEARCH_QUERY_VALUE_PARAM}" or headingRef<"${SEARCH_QUERY_VALUE_PARAM}") and isTitleHeadingRef==false and headingType==("Topical")`,
[SearchableIndexQuerySelector.Query]: `(headingRef>="${SEARCH_QUERY_VALUE_PARAM}" or headingRef<"${SEARCH_QUERY_VALUE_PARAM}") and isTitleHeadingRef==false and headingType==("Topical")`,
[SearchableIndexQuerySelector.Prev]: `headingRef<"${SEARCH_QUERY_VALUE_PARAM}" and isTitleHeadingRef==false and headingType==("Topical")`,
[SearchableIndexQuerySelector.Next]: `headingRef>"${SEARCH_QUERY_VALUE_PARAM}" and isTitleHeadingRef==false and headingType==("Topical")`,
},
[SearchableIndex.Genre]: {
query: `(headingRef>="${SEARCH_QUERY_VALUE_PARAM}" or headingRef<"${SEARCH_QUERY_VALUE_PARAM}") and isTitleHeadingRef==false and headingType==("Genre")`,
[SearchableIndexQuerySelector.Query]: `(headingRef>="${SEARCH_QUERY_VALUE_PARAM}" or headingRef<"${SEARCH_QUERY_VALUE_PARAM}") and isTitleHeadingRef==false and headingType==("Genre")`,
[SearchableIndexQuerySelector.Prev]: `headingRef<"${SEARCH_QUERY_VALUE_PARAM}" and isTitleHeadingRef==false and headingType==("Genre")`,
[SearchableIndexQuerySelector.Next]: `headingRef>"${SEARCH_QUERY_VALUE_PARAM}" and isTitleHeadingRef==false and headingType==("Genre")`,
},
},
};
17 changes: 14 additions & 3 deletions src/types/complexLookup.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
type SearchableIndexType = import('@common/constants/complexLookup.constants').SearchableIndex;
type SearchableIndexQuerySelectorType =
import('@common/constants/complexLookup.constants').SearchableIndexQuerySelector;

type ComplexLookupLabels = {
button: {
Expand Down Expand Up @@ -50,10 +52,12 @@ type ComplexLookupApiEntryConfig = {
};
};

type SearchableIndexEntry = {
[key in SearchableIndexQuerySelectorType]?: string;
};

type SearchableIndexEntries = {
[key in SearchableIndexType]?: {
query: string;
};
[key in SearchableIndexType]?: SearchableIndexEntry;
};

type SearchableIndicesMap = {
Expand Down Expand Up @@ -83,3 +87,10 @@ type ComplexLookupAssignRecordDTO = {
title: string;
linkedFieldValue?: string;
};

type BuildSearchQueryParams = {
map: SearchableIndexEntries;
selector?: SearchableIndexQuerySelectorType;
searchBy: SearchableIndexType;
value: string;
}
2 changes: 2 additions & 0 deletions src/types/search.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type SearchParams = {
getSearchFacetsData?: (facet?: string, isOpen?: boolean) => Promise<void>;
searchResultsLimit?: number;
fetchSearchResults?: (params: any) => Promise<SearchResults>;
buildSearchQuery?: (params: BuildSearchQueryParams) => string | undefined;
searchResultsContainer?: {
[key in SearchSegment]: string;
};
Expand Down Expand Up @@ -100,4 +101,5 @@ type FetchDataParams = {
searchBy: SearchIdentifiers;
offset?: number;
selectedSegment?: string;
baseQuerySelector?: SearchableIndexQuerySelectorType;
};

0 comments on commit b8e3d8a

Please sign in to comment.