update searchData calls with searchQuery

This commit is contained in:
Pranita 2025-09-09 20:16:41 +05:30
parent 638e1daa8e
commit c491ac8297
24 changed files with 517 additions and 394 deletions

View File

@ -16,7 +16,7 @@ import { isEmpty } from 'lodash';
import tippy, { Instance, Props } from 'tippy.js';
import { EntityType } from '../../../../enums/entity.enum';
import { SearchIndex } from '../../../../enums/search.enum';
import { searchData } from '../../../../rest/miscAPI';
import { searchQuery } from '../../../../rest/searchAPI';
import { getEntityBreadcrumbs } from '../../../../utils/EntityUtils';
import { buildMentionLink } from '../../../../utils/FeedUtils';
import { ExtensionRef } from '../../BlockEditor.interface';
@ -24,16 +24,13 @@ import HashList from './HashList';
export const hashtagSuggestion = () => ({
items: async ({ query }: { query: string }) => {
const data = await searchData(
query ?? '',
1,
5,
'',
'',
'',
SearchIndex.DATA_ASSET
);
const hits = data.data.hits.hits;
const data = await searchQuery({
query: query ?? '',
pageNumber: 1,
pageSize: 5,
searchIndex: SearchIndex.DATA_ASSET,
});
const hits = data.hits.hits;
return hits.map((hit) => ({
id: hit._id,

View File

@ -44,7 +44,7 @@ import { Operation } from '../../../generated/entity/policies/policy';
import { Style } from '../../../generated/type/tagLabel';
import { useFqn } from '../../../hooks/useFqn';
import { QueryFilterInterface } from '../../../pages/ExplorePage/ExplorePage.interface';
import { searchData } from '../../../rest/miscAPI';
import { searchQuery } from '../../../rest/searchAPI';
import { getEntityDeleteMessage } from '../../../utils/CommonUtils';
import { getQueryFilterToIncludeDomain } from '../../../utils/DomainUtils';
import { getEntityName } from '../../../utils/EntityUtils';
@ -191,17 +191,21 @@ const DataProductsDetailsPage = ({
const encodedFqn = getEncodedFqn(
escapeESReservedCharacters(dataProduct.fullyQualifiedName)
);
const res = await searchData(
'',
1,
0,
`(dataProducts.fullyQualifiedName:"${encodedFqn}")`,
'',
'',
SearchIndex.ALL
);
const res = await searchQuery({
query: '',
pageNumber: 1,
pageSize: 0,
queryFilter: {
query: {
term: {
'dataProducts.fullyQualifiedName': encodedFqn,
},
},
},
searchIndex: SearchIndex.ALL,
});
setAssetCount(res.data.hits.total.value ?? 0);
setAssetCount(res.hits.total.value ?? 0);
} catch (error) {
setAssetCount(0);
showErrorToast(

View File

@ -23,7 +23,7 @@ import {
import { QUERY_USED_BY_TABLE_VIEW_CAP } from '../../../../constants/Query.constant';
import { EntityType } from '../../../../enums/entity.enum';
import { SearchIndex } from '../../../../enums/search.enum';
import { searchData } from '../../../../rest/miscAPI';
import { searchQuery } from '../../../../rest/searchAPI';
import { getEntityLabel, getEntityName } from '../../../../utils/EntityUtils';
import { getEntityDetailsPath } from '../../../../utils/RouterUtils';
import { AsyncSelect } from '../../../common/AsyncSelect/AsyncSelect';
@ -124,17 +124,14 @@ const QueryUsedByOtherTable = ({
searchValue = ''
): Promise<DefaultOptionType[]> => {
try {
const { data } = await searchData(
searchValue,
INITIAL_PAGING_VALUE,
PAGE_SIZE_MEDIUM,
'',
'',
'',
SearchIndex.TABLE
);
const response = await searchQuery({
query: searchValue,
pageNumber: INITIAL_PAGING_VALUE,
pageSize: PAGE_SIZE_MEDIUM,
searchIndex: SearchIndex.TABLE,
});
return data.hits.hits.map((value) => ({
return response.hits.hits.map((value) => ({
label: getEntityLabel(value._source),
value: value._source.id,
labelName: getEntityName(value._source),

View File

@ -15,30 +15,30 @@ import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { Query } from '../../../../generated/entity/data/query';
import { MOCK_QUERIES } from '../../../../mocks/Queries.mock';
import { searchData } from '../../../../rest/miscAPI';
import { searchQuery } from '../../../../rest/searchAPI';
import { MOCK_EXPLORE_SEARCH_RESULTS } from '../../../Explore/Explore.mock';
import { QueryUsedByOtherTableProps } from '../TableQueries.interface';
import QueryUsedByOtherTable from './QueryUsedByOtherTable.component';
const mockProps: QueryUsedByOtherTableProps = {
query: MOCK_QUERIES[0] as Query,
isEditMode: false,
onChange: jest.fn(),
};
jest.mock('../../../common/AsyncSelect/AsyncSelect', () => ({
AsyncSelect: jest
.fn()
.mockImplementation(() => <div>AsyncSelect.component</div>),
}));
jest.mock('../../../../rest/miscAPI', () => ({
searchData: jest
.fn()
.mockReturnValue(() => Promise.resolve(MOCK_EXPLORE_SEARCH_RESULTS)),
}));
jest.mock('../../../../rest/searchAPI');
const mockProps: QueryUsedByOtherTableProps = {
query: MOCK_QUERIES[0] as Query,
isEditMode: false,
onChange: jest.fn(),
};
describe('QueryUsedByOtherTable test', () => {
beforeEach(() => {
(searchQuery as jest.Mock).mockResolvedValue(MOCK_EXPLORE_SEARCH_RESULTS);
});
it('Component should render', async () => {
render(<QueryUsedByOtherTable {...mockProps} />, {
wrapper: MemoryRouter,
@ -81,22 +81,19 @@ describe('QueryUsedByOtherTable test', () => {
});
it('Should fetch initial dropdown list in edit mode', async () => {
const mockSearchData = searchData as jest.Mock;
const mockSearchQuery = searchQuery as jest.Mock;
render(<QueryUsedByOtherTable {...mockProps} isEditMode />, {
wrapper: MemoryRouter,
});
const selectField = await screen.findByText('AsyncSelect.component');
expect(selectField).toBeInTheDocument();
expect(mockSearchData).toHaveBeenCalledWith(
'',
1,
25,
'',
'',
'',
'table_search_index'
);
expect(mockSearchQuery).toHaveBeenCalledWith({
query: '',
pageNumber: 1,
pageSize: 25,
searchIndex: 'table_search_index',
});
});
it('Loader should be visible while loading the initial options', async () => {

View File

@ -15,7 +15,7 @@ import { Col, Row, Typography } from 'antd';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { SearchIndex } from '../../../../enums/search.enum';
import { searchData } from '../../../../rest/miscAPI';
import { searchQuery } from '../../../../rest/searchAPI';
import SummaryPanelSkeleton from '../../../common/Skeleton/SummaryPanelSkeleton/SummaryPanelSkeleton.component';
import TableDataCardV2 from '../../../common/TableDataCardV2/TableDataCardV2';
import { SourceType } from '../../../SearchedData/SearchedData.interface';
@ -28,19 +28,30 @@ function TagsSummary({ entityDetails, isLoading }: TagsSummaryProps) {
const fetchTagAssetsDetails = useCallback(async () => {
try {
const query = `tags.tagFQN:"${entityDetails.fullyQualifiedName}"`;
const res = await searchData('', 1, 100, query, '', '', [
SearchIndex.TABLE,
SearchIndex.TOPIC,
SearchIndex.DASHBOARD,
SearchIndex.CONTAINER,
SearchIndex.GLOSSARY_TERM,
SearchIndex.MLMODEL,
SearchIndex.PIPELINE,
SearchIndex.STORED_PROCEDURE,
SearchIndex.DASHBOARD_DATA_MODEL,
]);
const sources = res.data.hits.hits.map((hit) => hit._source);
const res = await searchQuery({
query: '',
pageNumber: 1,
pageSize: 100,
queryFilter: {
query: {
term: {
'tags.tagFQN': entityDetails.fullyQualifiedName,
},
},
},
searchIndex: [
SearchIndex.TABLE,
SearchIndex.TOPIC,
SearchIndex.DASHBOARD,
SearchIndex.CONTAINER,
SearchIndex.GLOSSARY_TERM,
SearchIndex.MLMODEL,
SearchIndex.PIPELINE,
SearchIndex.STORED_PROCEDURE,
SearchIndex.DASHBOARD_DATA_MODEL,
],
});
const sources = res.hits.hits.map((hit) => hit._source);
setSelectedData(sources);
} catch (error) {
// Error

View File

@ -33,7 +33,7 @@ import { useCustomPages } from '../../../hooks/useCustomPages';
import { useFqn } from '../../../hooks/useFqn';
import { FeedCounts } from '../../../interface/feed.interface';
import { MOCK_GLOSSARY_NO_PERMISSIONS } from '../../../mocks/Glossary.mock';
import { searchData } from '../../../rest/miscAPI';
import { searchQuery } from '../../../rest/searchAPI';
import { getCountBadge, getFeedCounts } from '../../../utils/CommonUtils';
import {
checkIfExpandViewSupported,
@ -137,17 +137,21 @@ const GlossaryTermsV1 = ({
const encodedFqn = getEncodedFqn(
escapeESReservedCharacters(glossaryTerm.fullyQualifiedName)
);
const res = await searchData(
'',
1,
0,
`(tags.tagFQN:"${encodedFqn}")`,
'',
'',
SearchIndex.ALL
);
const res = await searchQuery({
query: '',
pageNumber: 1,
pageSize: 0,
queryFilter: {
query: {
term: {
'tags.tagFQN': encodedFqn,
},
},
},
searchIndex: SearchIndex.ALL,
});
setAssetCount(res.data.hits.total.value ?? 0);
setAssetCount(res.hits.total.value ?? 0);
} catch {
setAssetCount(0);
}

View File

@ -49,10 +49,13 @@ jest.mock(
})
);
jest.mock('../../../rest/miscAPI', () => ({
searchData: jest
.fn()
.mockImplementation(() => Promise.resolve(MOCK_ASSETS_DATA)),
jest.mock('../../../rest/searchAPI', () => ({
searchQuery: jest.fn().mockResolvedValue({
hits: {
hits: MOCK_ASSETS_DATA.data?.hits?.hits || [],
total: { value: MOCK_ASSETS_DATA.data?.hits?.total?.value || 0 },
},
}),
}));
jest.mock('./tabs/AssetsTabs.component', () =>

View File

@ -40,9 +40,8 @@ import { User } from '../../../../../generated/entity/teams/user';
import { EntityReference } from '../../../../../generated/entity/type';
import { Paging } from '../../../../../generated/type/paging';
import { usePaging } from '../../../../../hooks/paging/usePaging';
import { SearchResponse } from '../../../../../interface/search.interface';
import { ImportType } from '../../../../../pages/TeamsPage/ImportTeamsPage/ImportTeamsPage.interface';
import { searchData } from '../../../../../rest/miscAPI';
import { searchQuery } from '../../../../../rest/searchAPI';
import { exportUserOfTeam } from '../../../../../rest/teamsAPI';
import { getUsers } from '../../../../../rest/userAPI';
import { formatUsersResponse } from '../../../../../utils/APIUtils';
@ -135,22 +134,30 @@ export const UserTab = ({
const searchUsers = (text: string, currentPage: number) => {
setIsLoading(true);
searchData(
text,
currentPage,
searchQuery({
query: text ? `*${text}*` : '*',
pageNumber: currentPage,
pageSize,
`(teams.id:${currentTeam?.id})`,
'',
'',
SearchIndex.USER
)
queryFilter: {
query: {
bool: {
must: [
{
term: {
'teams.id': currentTeam?.id,
},
},
],
},
},
},
searchIndex: SearchIndex.USER,
})
.then((res) => {
const data = formatUsersResponse(
(res.data as SearchResponse<SearchIndex.USER>).hits.hits
);
const data = formatUsersResponse(res.hits.hits);
setUsers(data);
handlePagingChange({
total: res.data.hits.total.value,
total: res.hits.total.value,
});
})
.catch(() => {

View File

@ -22,7 +22,7 @@ import { NO_PERMISSION_FOR_ACTION } from '../../../constants/HelperTextUtil';
import { EntityType } from '../../../enums/entity.enum';
import { SearchIndex } from '../../../enums/search.enum';
import { EntityReference } from '../../../generated/entity/data/table';
import { searchData } from '../../../rest/miscAPI';
import { searchQuery } from '../../../rest/searchAPI';
import { getUsers } from '../../../rest/userAPI';
import { formatUsersResponse } from '../../../utils/APIUtils';
import { getEntityReferenceListFromEntities } from '../../../utils/EntityUtils';
@ -48,18 +48,22 @@ export const UserSelectableList = ({
const fetchOptions = async (searchText: string, after?: string) => {
if (searchText) {
try {
const res = await searchData(
searchText,
1,
PAGE_SIZE_MEDIUM,
'isBot:false',
'',
'',
SearchIndex.USER
);
const res = await searchQuery({
query: searchText,
pageNumber: 1,
pageSize: PAGE_SIZE_MEDIUM,
queryFilter: {
query: {
term: {
isBot: false,
},
},
},
searchIndex: SearchIndex.USER,
});
const data = getEntityReferenceListFromEntities(
formatUsersResponse(res.data.hits.hits),
formatUsersResponse(res.hits.hits),
EntityType.USER
);
@ -70,7 +74,7 @@ export const UserSelectableList = ({
}
}
return { data, paging: { total: res.data.hits.total.value } };
return { data, paging: { total: res.hits.total.value } };
} catch (error) {
return { data: [], paging: { total: 0 } };
}

View File

@ -19,8 +19,13 @@ jest.mock('../../../rest/userAPI', () => ({
getUsers: jest.fn().mockResolvedValue({ data: [], paging: { total: 5 } }),
}));
jest.mock('../../../rest/miscAPI', () => ({
searchData: jest.fn().mockResolvedValue({ data: [], paging: { total: 5 } }),
jest.mock('../../../rest/searchAPI', () => ({
searchQuery: jest.fn().mockResolvedValue({
hits: {
hits: [],
total: { value: 5 },
},
}),
}));
jest.mock('../SelectableList/SelectableList.component', () => ({

View File

@ -24,7 +24,7 @@ import {
import { EntityType } from '../../../enums/entity.enum';
import { SearchIndex } from '../../../enums/search.enum';
import { EntityReference } from '../../../generated/entity/data/table';
import { searchData } from '../../../rest/miscAPI';
import { searchQuery } from '../../../rest/searchAPI';
import {
formatTeamsResponse,
formatUsersResponse,
@ -88,22 +88,28 @@ export const UserTeamSelect = ({
const fetchUserOptions = async (searchTerm: string, page = 1) => {
setLoading(true);
try {
const res = await searchData(
searchTerm,
page,
PAGE_SIZE_MEDIUM,
'isBot:false',
'displayName.keyword',
'asc',
SearchIndex.USER
);
const res = await searchQuery({
query: searchTerm,
pageNumber: page,
pageSize: PAGE_SIZE_MEDIUM,
queryFilter: {
query: {
term: {
isBot: false,
},
},
},
sortField: 'displayName.keyword',
sortOrder: 'asc',
searchIndex: SearchIndex.USER,
});
const data = getEntityReferenceListFromEntities(
formatUsersResponse(res.data.hits.hits),
formatUsersResponse(res.hits.hits),
EntityType.USER
);
setCount((pre) => ({ ...pre, user: res.data.hits.total.value }));
setCount((pre) => ({ ...pre, user: res.hits.total.value }));
setHasMoreUsers(data.length === PAGE_SIZE_MEDIUM);
if (page === 1) {
@ -123,22 +129,28 @@ export const UserTeamSelect = ({
const fetchTeamOptions = async (searchTerm: string, page = 1) => {
setLoading(true);
try {
const res = await searchData(
searchTerm || '',
page,
PAGE_SIZE_MEDIUM,
'teamType:Group',
'displayName.keyword',
'asc',
SearchIndex.TEAM
);
const res = await searchQuery({
query: searchTerm || '',
pageNumber: page,
pageSize: PAGE_SIZE_MEDIUM,
queryFilter: {
query: {
match: {
teamType: 'Group',
},
},
},
sortField: 'displayName.keyword',
sortOrder: 'asc',
searchIndex: SearchIndex.TEAM,
});
const data = getEntityReferenceListFromEntities(
formatTeamsResponse(res.data.hits.hits),
formatTeamsResponse(res.hits.hits),
EntityType.TEAM
);
setCount((pre) => ({ ...pre, team: res.data.hits.total.value }));
setCount((pre) => ({ ...pre, team: res.hits.total.value }));
setHasMoreTeams(data.length === PAGE_SIZE_MEDIUM);
if (page === 1) {

View File

@ -26,7 +26,7 @@ import {
import { EntityType } from '../../../enums/entity.enum';
import { SearchIndex } from '../../../enums/search.enum';
import { EntityReference } from '../../../generated/entity/data/table';
import { searchData } from '../../../rest/miscAPI';
import { searchQuery } from '../../../rest/searchAPI';
import {
formatTeamsResponse,
formatUsersResponse,
@ -97,26 +97,32 @@ export const UserTeamSelectableList = ({
const fetchUserOptions = async (searchText: string, after?: string) => {
const afterPage = isNaN(Number(after)) ? 1 : Number(after);
try {
const res = await searchData(
searchText,
afterPage,
PAGE_SIZE_MEDIUM,
'isBot:false',
'displayName.keyword',
'asc',
SearchIndex.USER
);
const res = await searchQuery({
query: searchText,
pageNumber: afterPage,
pageSize: PAGE_SIZE_MEDIUM,
queryFilter: {
query: {
term: {
isBot: false,
},
},
},
sortField: 'displayName.keyword',
sortOrder: 'asc',
searchIndex: SearchIndex.USER,
});
const data = getEntityReferenceListFromEntities(
formatUsersResponse(res.data.hits.hits),
formatUsersResponse(res.hits.hits),
EntityType.USER
);
setCount((pre) => ({ ...pre, user: res.data.hits.total.value }));
setCount((pre) => ({ ...pre, user: res.hits.total.value }));
return {
data,
paging: {
total: res.data.hits.total.value,
total: res.hits.total.value,
after: toString(afterPage + 1),
},
};
@ -129,27 +135,33 @@ export const UserTeamSelectableList = ({
const afterPage = isNaN(Number(after)) ? 1 : Number(after);
try {
const res = await searchData(
searchText || '',
afterPage,
PAGE_SIZE_MEDIUM,
'teamType:Group',
'displayName.keyword',
'asc',
SearchIndex.TEAM
);
const res = await searchQuery({
query: searchText || '',
pageNumber: afterPage,
pageSize: PAGE_SIZE_MEDIUM,
queryFilter: {
query: {
match: {
teamType: 'Group',
},
},
},
sortField: 'displayName.keyword',
sortOrder: 'asc',
searchIndex: SearchIndex.TEAM,
});
const data = getEntityReferenceListFromEntities(
formatTeamsResponse(res.data.hits.hits),
formatTeamsResponse(res.hits.hits),
EntityType.TEAM
);
setCount((pre) => ({ ...pre, team: res.data.hits.total.value }));
setCount((pre) => ({ ...pre, team: res.hits.total.value }));
return {
data,
paging: {
total: res.data.hits.total.value,
total: res.hits.total.value,
after: toString(afterPage + 1),
},
};
@ -173,30 +185,38 @@ export const UserTeamSelectableList = ({
// Fetch and store count for Users tab
const getUserCount = async () => {
const res = await searchData(
'',
1,
0,
'isBot:false',
'',
'',
SearchIndex.USER
);
const res = await searchQuery({
query: '',
pageNumber: 1,
pageSize: 0,
queryFilter: {
query: {
term: {
isBot: false,
},
},
},
searchIndex: SearchIndex.USER,
});
setCount((pre) => ({ ...pre, user: res.data.hits.total.value }));
setCount((pre) => ({ ...pre, user: res.hits.total.value }));
};
const getTeamCount = async () => {
const res = await searchData(
'',
1,
0,
'teamType:Group',
'',
'',
SearchIndex.TEAM
);
const res = await searchQuery({
query: '',
pageNumber: 1,
pageSize: 0,
queryFilter: {
query: {
match: {
teamType: 'Group',
},
},
},
searchIndex: SearchIndex.TEAM,
});
setCount((pre) => ({ ...pre, team: res.data.hits.total.value }));
setCount((pre) => ({ ...pre, team: res.hits.total.value }));
};
const init = async () => {

View File

@ -33,7 +33,7 @@ import { SearchIndex } from '../../enums/search.enum';
import { User } from '../../generated/entity/teams/user';
import { useAuth } from '../../hooks/authHooks';
import { usePaging } from '../../hooks/paging/usePaging';
import { searchData } from '../../rest/miscAPI';
import { searchQuery } from '../../rest/searchAPI';
import { getOnlineUsers, OnlineUsersQueryParams } from '../../rest/userAPI';
import { formatDateTime } from '../../utils/date-time/DateTimeUtils';
import { getSettingPageEntityBreadCrumb } from '../../utils/GlobalSettingsUtils';
@ -116,19 +116,22 @@ const OnlineUsersPage = () => {
async (value: string) => {
setIsDataLoading(true);
try {
// For search, we still need to use searchData API and filter client-side
// For search, we still need to use searchQuery API and filter client-side
// as the online users endpoint doesn't support search yet
const res = await searchData(
value,
currentPage,
const res = await searchQuery({
query: value,
pageNumber: currentPage,
pageSize,
'isBot:false',
'',
'',
SearchIndex.USER,
false
);
const data = res.data.hits.hits.map(({ _source }) => _source);
queryFilter: {
query: {
term: {
isBot: false,
},
},
},
searchIndex: SearchIndex.USER,
});
const data = res.hits.hits.map(({ _source }) => _source);
// Filter users based on lastLoginTime
const onlineUsers = data.filter((user: User) => {

View File

@ -13,7 +13,7 @@
import { render, waitFor } from '@testing-library/react';
import { useFqn } from '../../hooks/useFqn';
import { searchData } from '../../rest/miscAPI';
import { searchQuery } from '../../rest/searchAPI';
import { getTagByFqn } from '../../rest/tagAPI';
import TagPage from './TagPage';
@ -24,12 +24,10 @@ jest.mock('../../rest/tagAPI', () => ({
}),
}));
jest.mock('../../rest/miscAPI', () => ({
searchData: jest.fn().mockResolvedValue({
data: {
hits: {
total: { value: 0 },
},
jest.mock('../../rest/searchAPI', () => ({
searchQuery: jest.fn().mockResolvedValue({
hits: {
total: { value: 0 },
},
}),
}));
@ -161,7 +159,7 @@ describe('TagPage', () => {
expect(getTagByFqn).toHaveBeenCalledWith('PII.NonSensitive', {
fields: ['domains', 'owners'],
});
expect(searchData).toHaveBeenCalled();
expect(searchQuery).toHaveBeenCalled();
});
jest.clearAllMocks();
@ -180,7 +178,7 @@ describe('TagPage', () => {
expect(getTagByFqn).toHaveBeenCalledWith('Certification.Gold', {
fields: ['domains', 'owners'],
});
expect(searchData).toHaveBeenCalled();
expect(searchQuery).toHaveBeenCalled();
});
});
});

View File

@ -76,7 +76,7 @@ import { SearchIndex } from '../../enums/search.enum';
import { ProviderType, Tag } from '../../generated/entity/classification/tag';
import { Style } from '../../generated/type/tagLabel';
import { useFqn } from '../../hooks/useFqn';
import { searchData } from '../../rest/miscAPI';
import { searchQuery } from '../../rest/searchAPI';
import { deleteTag, getTagByFqn, patchTag } from '../../rest/tagAPI';
import { getEntityDeleteMessage } from '../../utils/CommonUtils';
import { getEntityName } from '../../utils/EntityUtils';
@ -337,18 +337,16 @@ const TagPage = () => {
const fetchClassificationTagAssets = async () => {
try {
const encodedFqn = getEncodedFqn(escapeESReservedCharacters(tagFqn));
const res = await searchData(
'',
1,
0,
getTagAssetsQueryFilter(encodedFqn),
'',
'',
SearchIndex.ALL
);
const res = await searchQuery({
query: '',
pageNumber: 1,
pageSize: 0,
queryFilter: getTagAssetsQueryFilter(encodedFqn),
searchIndex: SearchIndex.ALL,
});
setAssetCount(res.data.hits.total.value ?? 0);
if (res.data.hits.total.value === 0) {
setAssetCount(res.hits.total.value ?? 0);
if (res.hits.total.value === 0) {
setPreviewAsset(undefined);
}
} catch (error) {

View File

@ -18,7 +18,7 @@ import { ERROR_PLACEHOLDER_TYPE } from '../../enums/common.enum';
import { TeamType } from '../../generated/entity/teams/team';
import { mockUserData } from '../../mocks/MyDataPage.mock';
import { MOCK_CURRENT_TEAM } from '../../mocks/Teams.mock';
import { searchData } from '../../rest/miscAPI';
import { searchQuery } from '../../rest/searchAPI';
import { getTeamByName } from '../../rest/teamsAPI';
import { DEFAULT_ENTITY_PERMISSION } from '../../utils/PermissionsUtils';
import TeamsPage from './TeamsPage';
@ -92,8 +92,8 @@ jest.mock('../../rest/teamsAPI', () => ({
patchTeamDetail: jest.fn().mockImplementation(() => Promise.resolve()),
}));
jest.mock('../../rest/miscAPI', () => ({
searchData: jest.fn().mockResolvedValue({ data: [], paging: { total: 0 } }),
jest.mock('../../rest/searchAPI', () => ({
searchQuery: jest.fn().mockResolvedValue({ hits: { total: { value: 0 } } }),
}));
jest.mock('../../hooks/useFqn', () => ({
@ -224,15 +224,25 @@ describe('Test Teams Page', () => {
render(<TeamsPage />);
});
expect(searchData).toHaveBeenCalledWith(
'',
0,
0,
'owners.id:f9578f16-363a-4788-80fb-d05816c9e169',
'',
'',
'all'
);
expect(searchQuery).toHaveBeenCalledWith({
query: '',
pageNumber: 0,
pageSize: 0,
queryFilter: {
query: {
bool: {
must: [
{
term: {
'owners.id': 'f9578f16-363a-4788-80fb-d05816c9e169',
},
},
],
},
},
},
searchIndex: 'all',
});
});
it('should not fetchAssetCount on page load if TeamType is not Group', async () => {
@ -250,7 +260,7 @@ describe('Test Teams Page', () => {
render(<TeamsPage />);
});
expect(searchData).not.toHaveBeenCalled();
expect(searchQuery).not.toHaveBeenCalled();
(getTeamByName as jest.Mock).mockReset();
});

View File

@ -36,7 +36,7 @@ import { Team } from '../../generated/entity/teams/team';
import { Include } from '../../generated/type/include';
import { useApplicationStore } from '../../hooks/useApplicationStore';
import { useFqn } from '../../hooks/useFqn';
import { searchData } from '../../rest/miscAPI';
import { searchQuery } from '../../rest/searchAPI';
import {
createTeam,
deleteUserFromTeam,
@ -190,16 +190,26 @@ const TeamsPage = () => {
const fetchAssets = async (selectedTeam: Team) => {
if (selectedTeam.id && selectedTeam.teamType === TeamType.Group) {
try {
const res = await searchData(
``,
0,
0,
`owners.id:${selectedTeam.id}`,
'',
'',
SearchIndex.ALL
);
const total = res?.data?.hits?.total.value ?? 0;
const res = await searchQuery({
query: '',
pageNumber: 0,
pageSize: 0,
queryFilter: {
query: {
bool: {
must: [
{
term: {
'owners.id': selectedTeam.id,
},
},
],
},
},
},
searchIndex: SearchIndex.ALL,
});
const total = res?.hits?.total.value ?? 0;
setAssets(total);
} catch {
// Error

View File

@ -61,10 +61,13 @@ jest.mock('../../rest/userAPI', () => ({
updateUser: jest.fn(),
}));
jest.mock('../../rest/miscAPI', () => ({
searchData: jest.fn().mockImplementation(() =>
jest.mock('../../rest/searchAPI', () => ({
searchQuery: jest.fn().mockImplementation(() =>
Promise.resolve({
data: MOCK_USER_DATA,
hits: {
hits: MOCK_USER_DATA.data.map((user) => ({ _source: user })),
total: { value: MOCK_USER_DATA.data.length },
},
})
),
}));

View File

@ -48,7 +48,7 @@ import { useAuth } from '../../hooks/authHooks';
import { useCurrentUserPreferences } from '../../hooks/currentUserStore/useCurrentUserStore';
import { usePaging } from '../../hooks/paging/usePaging';
import { useTableFilters } from '../../hooks/useTableFilters';
import { searchData } from '../../rest/miscAPI';
import { searchQuery } from '../../rest/searchAPI';
import { getUsers, restoreUser, UsersQueryParams } from '../../rest/userAPI';
import { Transi18next } from '../../utils/CommonUtils';
import { getEntityName } from '../../utils/EntityUtils';
@ -137,26 +137,40 @@ const UserListPageV1 = () => {
isAdmin = false,
isDeleted = false
) => {
let filters = 'isAdmin:false isBot:false';
if (isAdmin) {
filters = 'isAdmin:true isBot:false';
}
return new Promise<Array<User>>((resolve) => {
searchData(
text,
currentPage,
const searchText = text === WILD_CARD_CHAR ? text : `*${text}*`;
const queryFilter = {
query: {
bool: {
must: [
{
term: {
isAdmin: isAdmin,
},
},
{
term: {
isBot: false,
},
},
],
},
},
};
searchQuery({
query: searchText,
pageNumber: currentPage,
pageSize,
filters,
'',
'',
SearchIndex.USER,
isDeleted
)
queryFilter,
searchIndex: SearchIndex.USER,
includeDeleted: isDeleted,
})
.then((res) => {
const data = res.data.hits.hits.map(({ _source }) => _source);
const data = res.hits.hits.map(({ _source }) => _source);
handlePagingChange({
total: res.data.hits.total.value,
total: res.hits.total.value,
});
resolve(data);
})

View File

@ -36,7 +36,7 @@ import {
mockTypedEvent3,
mockTypedEvent4,
} from '../../mocks/AlertUtil.mock';
import { searchData } from '../../rest/miscAPI';
import { searchQuery } from '../../rest/searchAPI';
import {
getAlertActionTypeDisplayName,
getAlertEventsFilterLabels,
@ -74,8 +74,8 @@ jest.mock('../../components/common/AsyncSelect/AsyncSelect', () => ({
)),
}));
jest.mock('../../rest/miscAPI', () => ({
searchData: jest.fn(),
jest.mock('../../rest/searchAPI', () => ({
searchQuery: jest.fn(),
}));
describe('AlertsUtil tests', () => {
@ -275,15 +275,13 @@ describe('getFieldByArgumentType tests', () => {
fireEvent.click(selectDiv);
expect(searchData).toHaveBeenCalledWith(
undefined,
1,
50,
'',
'',
'',
'table_search_index'
);
expect(searchQuery).toHaveBeenCalledWith({
query: undefined,
pageNumber: 1,
pageSize: 50,
queryFilter: undefined,
searchIndex: 'table_search_index',
});
});
it('should return correct fields for argumentType domainList', async () => {
@ -295,15 +293,13 @@ describe('getFieldByArgumentType tests', () => {
fireEvent.click(selectDiv);
expect(searchData).toHaveBeenCalledWith(
undefined,
1,
50,
'',
'',
'',
'domain_search_index'
);
expect(searchQuery).toHaveBeenCalledWith({
query: undefined,
pageNumber: 1,
pageSize: 50,
queryFilter: undefined,
searchIndex: 'domain_search_index',
});
});
it('should return correct fields for argumentType tableNameList', async () => {
@ -320,15 +316,13 @@ describe('getFieldByArgumentType tests', () => {
fireEvent.click(selectDiv);
expect(searchData).toHaveBeenCalledWith(
undefined,
1,
50,
'',
'',
'',
'table_search_index'
);
expect(searchQuery).toHaveBeenCalledWith({
query: undefined,
pageNumber: 1,
pageSize: 50,
queryFilter: undefined,
searchIndex: 'table_search_index',
});
});
it('should return correct fields for argumentType ownerNameList', async () => {
@ -345,15 +339,19 @@ describe('getFieldByArgumentType tests', () => {
fireEvent.click(selectDiv);
expect(searchData).toHaveBeenCalledWith(
undefined,
1,
50,
'isBot:false',
'',
'',
['team_search_index', 'user_search_index']
);
expect(searchQuery).toHaveBeenCalledWith({
query: undefined,
pageNumber: 1,
pageSize: 50,
queryFilter: {
query: {
term: {
isBot: false,
},
},
},
searchIndex: ['team_search_index', 'user_search_index'],
});
});
it('should return correct fields for argumentType updateByUserList', async () => {
@ -370,15 +368,13 @@ describe('getFieldByArgumentType tests', () => {
fireEvent.click(selectDiv);
expect(searchData).toHaveBeenCalledWith(
undefined,
1,
50,
'',
'',
'',
'user_search_index'
);
expect(searchQuery).toHaveBeenCalledWith({
query: undefined,
pageNumber: 1,
pageSize: 50,
queryFilter: undefined,
searchIndex: 'user_search_index',
});
});
it('should return correct fields for argumentType userList', async () => {
@ -390,15 +386,19 @@ describe('getFieldByArgumentType tests', () => {
fireEvent.click(selectDiv);
expect(searchData).toHaveBeenCalledWith(
undefined,
1,
50,
'isBot:false',
'',
'',
'user_search_index'
);
expect(searchQuery).toHaveBeenCalledWith({
query: undefined,
pageNumber: 1,
pageSize: 50,
queryFilter: {
query: {
term: {
isBot: false,
},
},
},
searchIndex: 'user_search_index',
});
});
it('should return correct fields for argumentType eventTypeList', async () => {
@ -505,15 +505,13 @@ describe('getFieldByArgumentType tests', () => {
fireEvent.click(selectDiv);
expect(searchData).toHaveBeenCalledWith(
undefined,
1,
50,
'',
'',
'',
'test_suite_search_index'
);
expect(searchQuery).toHaveBeenCalledWith({
query: undefined,
pageNumber: 1,
pageSize: 50,
queryFilter: undefined,
searchIndex: 'test_suite_search_index',
});
});
it('should not return select component for random argumentType', () => {

View File

@ -103,7 +103,7 @@ import {
ModifiedDestination,
ModifiedEventSubscription,
} from '../../pages/AddObservabilityPage/AddObservabilityPage.interface';
import { searchData } from '../../rest/miscAPI';
import { searchQuery } from '../../rest/searchAPI';
import { ExtraInfoLabel } from '../DataAssetsHeader.utils';
import { getEntityName, getEntityNameLabel } from '../EntityUtils';
import { handleEntityCreationError } from '../formUtils';
@ -218,31 +218,51 @@ export const EDIT_LINK_PATH = `/settings/notifications/edit-alert`;
export const searchEntity = async ({
searchText,
searchIndex,
filters,
queryFilter,
showDisplayNameAsLabel = true,
setSourceAsValue = false,
}: {
searchText: string;
searchIndex: SearchIndex | SearchIndex[];
filters?: string;
queryFilter?: {
query: {
term?: Record<string, string | number | boolean>;
match?: Record<string, string | number>;
bool?: {
must?: Array<
| { term: Record<string, string | number | boolean> }
| { match: Record<string, string | number> }
>;
should?: Array<
| { term: Record<string, string | number | boolean> }
| { match: Record<string, string | number> }
>;
must_not?: Array<
| { term: Record<string, string | number | boolean> }
| { match: Record<string, string | number> }
>;
};
query_string?: {
query: string;
};
};
};
showDisplayNameAsLabel?: boolean;
setSourceAsValue?: boolean;
}) => {
try {
const response = await searchData(
searchText,
1,
PAGE_SIZE_LARGE,
filters ?? '',
'',
'',
searchIndex
);
const response = await searchQuery({
query: searchText,
pageNumber: 1,
pageSize: PAGE_SIZE_LARGE,
queryFilter,
searchIndex,
});
const searchIndexEntityTypeMapping =
searchClassBase.getSearchIndexEntityTypeMapping();
return uniqBy(
response.data.hits.hits.map((d) => {
response.hits.hits.map((d) => {
// Providing an option to hide display names, for inputs like 'fqnList',
// where users can input text alongside selection options.
// This helps avoid displaying the same option twice
@ -297,7 +317,13 @@ const getOwnerOptions = async (searchText: string) => {
return searchEntity({
searchText,
searchIndex: [SearchIndex.TEAM, SearchIndex.USER],
filters: 'isBot:false',
queryFilter: {
query: {
term: {
isBot: false,
},
},
},
});
};
@ -305,7 +331,13 @@ const getUserOptions = async (searchText: string) => {
return searchEntity({
searchText,
searchIndex: SearchIndex.USER,
filters: 'isBot:false',
queryFilter: {
query: {
term: {
isBot: false,
},
},
},
});
};

View File

@ -25,38 +25,21 @@ import {
suggestions,
} from './FeedUtils';
jest.mock('../rest/miscAPI', () => ({
getSearchedUsers: jest.fn().mockResolvedValue({
data: {
hits: {
hits: [
{
_source: {
entityType: 'User',
name: 'John Doe',
deleted: false,
},
_id: '1',
jest.mock('../rest/searchAPI', () => ({
searchQuery: jest.fn().mockResolvedValue({
hits: {
hits: [
{
_source: {
entityType: 'Table',
name: 'Table1',
displayName: 'Table 1',
fullyQualifiedName: 'db.schema.Table1',
},
],
},
},
}),
searchData: jest.fn().mockResolvedValue({
data: {
hits: {
hits: [
{
_source: {
entityType: 'Table',
name: 'Table1',
displayName: 'Table 1',
fullyQualifiedName: 'db.schema.Table1',
},
_id: '1',
},
],
},
_id: '1',
_index: 'team_search_index',
},
],
},
}),
}));

View File

@ -56,7 +56,7 @@ import {
updatePost,
updateThread,
} from '../rest/feedsAPI';
import { searchData } from '../rest/miscAPI';
import { searchQuery } from '../rest/searchAPI';
import {
getEntityPlaceHolder,
getPartialNameFromFQN,
@ -163,16 +163,22 @@ export async function suggestions(
if (mentionChar === '@') {
let atValues = [];
const data = await searchData(
searchTerm ?? '',
1,
5,
'isBot:false',
'displayName.keyword',
'asc',
[SearchIndex.USER, SearchIndex.TEAM]
);
const hits = data.data.hits.hits;
const data = await searchQuery({
query: searchTerm ?? '',
pageNumber: 1,
pageSize: 5,
queryFilter: {
query: {
term: {
isBot: false,
},
},
},
sortField: 'displayName.keyword',
sortOrder: 'asc',
searchIndex: [SearchIndex.USER, SearchIndex.TEAM],
});
const hits = data.hits.hits;
atValues = await Promise.all(
hits.map(async (hit) => {
@ -200,16 +206,15 @@ export async function suggestions(
return atValues as MentionSuggestionsItem[];
} else {
let hashValues = [];
const data = await searchData(
searchTerm ?? '',
1,
5,
'',
'displayName.keyword',
'asc',
SearchIndex.DATA_ASSET
);
const hits = data.data.hits.hits;
const data = await searchQuery({
query: searchTerm ?? '',
pageNumber: 1,
pageSize: 5,
sortField: 'displayName.keyword',
sortOrder: 'asc',
searchIndex: SearchIndex.DATA_ASSET,
});
const hits = data.hits.hits;
hashValues = hits.map((hit) => {
const entityType = hit._source.entityType;

View File

@ -587,13 +587,21 @@ export const getExcludedIndexesBasedOnEntityTypeEditTagPermission = (
};
export const getTagAssetsQueryFilter = (fqn: string) => {
let fieldName = 'tags.tagFQN';
if (fqn.includes('Tier.')) {
return `(tier.tagFQN:"${fqn}")`;
fieldName = 'tier.tagFQN';
} else if (fqn.includes('Certification.')) {
return `(certification.tagLabel.tagFQN:"${fqn}")`;
} else {
return `(tags.tagFQN:"${fqn}")`;
fieldName = 'certification.tagLabel.tagFQN';
}
return {
query: {
term: {
[fieldName]: fqn,
},
},
};
};
export const getTagImageSrc = (iconURL: string) => {