Skip to content

Commit

Permalink
[Search] [Onboarding] Update document count (#196674)
Browse files Browse the repository at this point in the history
## Summary

This uses the document list count within the quick stats. Before it used
the document count from es3 billing and takes a while to update.


https://github.com/user-attachments/assets/9c29c88a-628f-4c63-99e5-d892a835e973

### Checklist

Delete any items that are not applicable to this PR.

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed

---------

Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
joemcelroy and elasticmachine authored Oct 22, 2024
1 parent feb5b79 commit 5c51e78
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ describe('fetchSearchResults lib function', () => {
index: indexName,
q: query,
size: DEFAULT_DOCS_PER_PAGE,
track_total_hits: false,
});
});

Expand All @@ -109,6 +110,7 @@ describe('fetchSearchResults lib function', () => {
index: indexName,
q: '\\"yellow banana\\"',
size: DEFAULT_DOCS_PER_PAGE,
track_total_hits: false,
});
});

Expand All @@ -123,6 +125,7 @@ describe('fetchSearchResults lib function', () => {
from: DEFAULT_FROM_VALUE,
index: indexName,
size: DEFAULT_DOCS_PER_PAGE,
track_total_hits: false,
});
});

Expand Down Expand Up @@ -150,6 +153,42 @@ describe('fetchSearchResults lib function', () => {
index: indexName,
q: query,
size: DEFAULT_DOCS_PER_PAGE,
track_total_hits: false,
});
});

it('should send track_total_hits true when specified', async () => {
mockClient.search.mockImplementationOnce(() =>
Promise.resolve({
...mockSearchResponseWithHits,
hits: {
...mockSearchResponseWithHits.hits,
total: {
...mockSearchResponseWithHits.hits.total,
value: 0,
},
hits: [],
},
})
);

await expect(
fetchSearchResults(
mockClient as unknown as ElasticsearchClient,
indexName,
query,
0,
25,
true
)
).resolves.toEqual(emptySearchResultsResponse);

expect(mockClient.search).toHaveBeenCalledWith({
from: DEFAULT_FROM_VALUE,
index: indexName,
q: query,
size: DEFAULT_DOCS_PER_PAGE,
track_total_hits: true,
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export const fetchSearchResults = async (
indexName: string,
query?: string,
from: number = 0,
size: number = DEFAULT_DOCS_PER_PAGE
size: number = DEFAULT_DOCS_PER_PAGE,
trackTotalHits: boolean = false
): Promise<Paginate<SearchHit>> => {
const result = await fetchWithPagination(
async () =>
Expand All @@ -27,6 +28,7 @@ export const fetchSearchResults = async (
index: indexName,
size,
...(!!query ? { q: escapeLuceneChars(query) } : {}),
track_total_hits: trackTotalHits,
}),
from,
size
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ export const SearchIndexDetailsPage = () => {
}, [isShowingDeleteModal]);
const { euiTheme } = useEuiTheme();

if (isInitialLoading || isMappingsInitialLoading) {
if (isInitialLoading || isMappingsInitialLoading || indexDocumentsIsInitialLoading) {
return (
<SectionLoading>
{i18n.translate('xpack.searchIndices.loadingDescription', {
Expand All @@ -209,7 +209,7 @@ export const SearchIndexDetailsPage = () => {
panelled
bottomBorder
>
{isIndexError || isMappingsError || !index || !mappings ? (
{isIndexError || isMappingsError || !index || !mappings || !indexDocuments ? (
<IndexloadingError
error={indexError}
navigateToIndexListPage={navigateToIndexListPage}
Expand Down Expand Up @@ -297,7 +297,7 @@ export const SearchIndexDetailsPage = () => {
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexGroup>
<QuickStats index={index} mappings={mappings} />
<QuickStats indexDocuments={indexDocuments} index={index} mappings={mappings} />
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ import { Mappings } from '../../types';
import { countVectorBasedTypesFromMappings } from './mappings_convertor';
import { QuickStat } from './quick_stat';
import { useKibana } from '../../hooks/use_kibana';
import { IndexDocuments } from '../../hooks/api/use_document_search';

export interface QuickStatsProps {
index: Index;
mappings: Mappings;
indexDocuments: IndexDocuments;
}

export const SetupAISearchButton: React.FC = () => {
Expand Down Expand Up @@ -60,12 +62,13 @@ export const SetupAISearchButton: React.FC = () => {
);
};

export const QuickStats: React.FC<QuickStatsProps> = ({ index, mappings }) => {
export const QuickStats: React.FC<QuickStatsProps> = ({ index, mappings, indexDocuments }) => {
const [open, setOpen] = useState<boolean>(false);
const { euiTheme } = useEuiTheme();
const mappingStats = useMemo(() => countVectorBasedTypesFromMappings(mappings), [mappings]);
const vectorFieldCount =
mappingStats.sparse_vector + mappingStats.dense_vector + mappingStats.semantic_text;
const docCount = indexDocuments?.results._meta.page.total ?? 0;

return (
<EuiPanel
Expand All @@ -89,13 +92,13 @@ export const QuickStats: React.FC<QuickStatsProps> = ({ index, mappings }) => {
defaultMessage: 'Document count',
})}
data-test-subj="QuickStatsDocumentCount"
secondaryTitle={<EuiI18nNumber value={index.documents ?? 0} />}
secondaryTitle={<EuiI18nNumber value={docCount ?? 0} />}
stats={[
{
title: i18n.translate('xpack.searchIndices.quickStats.documents.totalTitle', {
defaultMessage: 'Total',
}),
description: <EuiI18nNumber value={index.documents ?? 0} />,
description: <EuiI18nNumber value={docCount ?? 0} />,
},
{
title: i18n.translate('xpack.searchIndices.quickStats.documents.indexSize', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,18 @@ export const useDeleteDocument = (indexName: string) => {
queryClient.setQueryData(
[QueryKeys.SearchDocuments, indexName],
(snapshot: IndexDocuments | undefined) => {
const oldData = snapshot ?? { results: { data: [] } };
const oldData = snapshot ?? { results: { data: [], _meta: { page: { total: 0 } } } };
return {
...oldData,
results: {
...oldData.results,
data: oldData.results.data.filter((doc: SearchHit) => doc._id !== id),
_meta: {
page: {
...oldData.results._meta.page,
total: oldData.results._meta.page.total - 1,
},
},
},
} as IndexDocuments;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const useIndexDocumentSearch = (indexName: string) => {
http.post<IndexDocuments>(`/internal/serverless_search/indices/${indexName}/search`, {
body: JSON.stringify({
searchQuery: '',
trackTotalHits: true,
}),
query: {
page: 0,
Expand Down
11 changes: 10 additions & 1 deletion x-pack/plugins/serverless_search/server/routes/indices_routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ export const registerIndicesRoutes = ({ logger, router }: RouteDependencies) =>
searchQuery: schema.string({
defaultValue: '',
}),
trackTotalHits: schema.boolean({ defaultValue: false }),
}),
params: schema.object({
index_name: schema.string(),
Expand All @@ -126,8 +127,16 @@ export const registerIndicesRoutes = ({ logger, router }: RouteDependencies) =>
const searchQuery = request.body.searchQuery;
const { page = 0, size = DEFAULT_DOCS_PER_PAGE } = request.query;
const from = page * size;
const trackTotalHits = request.body.trackTotalHits;

const searchResults = await fetchSearchResults(client, indexName, searchQuery, from, size);
const searchResults = await fetchSearchResults(
client,
indexName,
searchQuery,
from,
size,
trackTotalHits
);

return response.ok({
body: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ export function SvlSearchIndexDetailPageProvider({ getService }: FtrProviderCont
await quickStatsDocumentElem.click();
expect(await quickStatsDocumentElem.getVisibleText()).to.contain('Index Size\n0b');
},

async expectQuickStatsToHaveDocumentCount(count: number) {
const quickStatsElem = await testSubjects.find('quickStats');
const quickStatsDocumentElem = await quickStatsElem.findByTestSubject(
'QuickStatsDocumentCount'
);
expect(await quickStatsDocumentElem.getVisibleText()).to.contain(`Document count\n${count}`);
},

async expectQuickStatsAIMappings() {
await testSubjects.existOrFail('quickStats', { timeout: 2000 });
const quickStatsElem = await testSubjects.find('quickStats');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
it('should have index documents', async () => {
await pageObjects.svlSearchIndexDetailPage.expectHasIndexDocuments();
});
it('should have one document in quick stats', async () => {
await pageObjects.svlSearchIndexDetailPage.expectQuickStatsToHaveDocumentCount(1);
});
it('should have with data tabs', async () => {
await pageObjects.svlSearchIndexDetailPage.expectWithDataTabsExists();
await pageObjects.svlSearchIndexDetailPage.expectShouldDefaultToDataTab();
Expand All @@ -148,6 +151,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await pageObjects.svlSearchIndexDetailPage.withDataChangeTabs('dataTab');
await pageObjects.svlSearchIndexDetailPage.clickFirstDocumentDeleteAction();
await pageObjects.svlSearchIndexDetailPage.expectAddDocumentCodeExamples();
await pageObjects.svlSearchIndexDetailPage.expectQuickStatsToHaveDocumentCount(0);
});
});

Expand Down

0 comments on commit 5c51e78

Please sign in to comment.