[ML] Show analysis not available for vector fields in Index Data Visualizer (#209945)

## Summary

In 9.0, vector fields like vector embeddings or offsets are no longer
exposed in Elasticsearch API, which makes it not possible to sample the
count and show examples This PR makes it so that the expanded rows for
these fields indicate analysis is not available for these fields.

<img width="1295" alt="image"
src="https://github.com/user-attachments/assets/60a95883-2918-4af5-821a-8f8a006d8441"
/>


### Checklist

Check the PR satisfies following conditions. 

Reviewers should verify this PR satisfies this list as well.

- [ ] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md)
- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [ ] [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
- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)
- [ ] This was checked for breaking HTTP API changes, and any breaking
changes have been approved by the breaking-change committee. The
`release_note:breaking` label should be applied in these situations.
- [ ] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [ ] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

### Identify risks

Does this PR introduce any risks? For example, consider risks like hard
to test bugs, performance regression, potential of data loss.

Describe the risk, its severity, and mitigation for each identified
risk. Invite stakeholders and evaluate how to proceed before merging.

- [ ] [See some risk
examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx)
- [ ] ...

---------

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Quynh Nguyen (Quinn) 2025-02-07 13:39:59 -06:00 committed by GitHub
parent 8efc247688
commit 14eefced0f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 56 additions and 2 deletions

View file

@ -24,6 +24,7 @@ import type { FieldVisConfig } from '../stats_table/types';
import type { CombinedQuery } from '../../../index_data_visualizer/types/combined_query';
import { LoadingIndicator } from '../loading_indicator';
import { ErrorMessageContent } from '../stats_table/components/field_data_expanded_row/error_message';
import { NotSupportedContent } from '../not_in_docs_content/not_supported_content';
export const IndexBasedDataVisualizerExpandedRow = ({
item,
@ -55,6 +56,10 @@ export const IndexBasedDataVisualizerExpandedRow = ({
const dvExpandedRow = useExpandedRowCss();
function getCardContent() {
if (type === 'unknown' || type.includes('vector') || item.secondaryType?.includes('vector')) {
return <NotSupportedContent />;
}
if (existsInDocs === false) {
return <NotInDocsContent />;
}

View file

@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { Fragment } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiIcon, EuiText } from '@elastic/eui';
import type { FC } from 'react';
export const NotSupportedContent: FC = () => (
<Fragment>
<EuiText textAlign="center">
<EuiIcon type="warning" />
</EuiText>
<EuiText textAlign="center" size={'xs'}>
<FormattedMessage
id="xpack.dataVisualizer.dataGrid.field.analysisNotSupportedLabel"
defaultMessage="Analysis is not available for this field."
/>
</EuiText>
</Fragment>
);

View file

@ -44,10 +44,13 @@ const EmbeddableFieldStatsTableWrapper = (
searchString,
extendedColumns,
progress,
overallStats,
overallStatsProgress,
setLastRefresh,
} = useDataVisualizerGridData(props, dataVisualizerListState);
const totalCount = overallStats?.totalCount;
useEffect(() => {
setLastRefresh(Date.now());
}, [props?.lastReloadRequestTime, setLastRefresh]);
@ -93,6 +96,7 @@ const EmbeddableFieldStatsTableWrapper = (
onChange={onTableUpdate}
loading={progress < 100}
overallStatsRunning={overallStatsProgress.isRunning}
totalCount={totalCount}
renderFieldName={props.renderFieldName}
/>
);

View file

@ -31,6 +31,7 @@ import {
isAggregatableFieldOverallStats,
isNonAggregatableFieldOverallStats,
isNonAggregatableSampledDocs,
isUnsupportedVectorField,
processAggregatableFieldsExistResponse,
processNonAggregatableFieldsExistResponse,
} from '../search_strategy/requests/overall_stats';
@ -214,6 +215,9 @@ export function useOverallStats<TParams extends OverallStatsSearchStrategyParams
const nonAggregatableFields = hasPopulatedFieldsInfo
? originalNonAggregatableFields.filter((fieldName) => populatedFieldsInIndex.has(fieldName))
: originalNonAggregatableFields;
const supportedNonAggregatableFields = nonAggregatableFields.filter((fieldName) => {
return !isUnsupportedVectorField(fieldName);
});
const documentCountStats = await getDocumentCountStats(
data.search,
@ -227,7 +231,7 @@ export function useOverallStats<TParams extends OverallStatsSearchStrategyParams
.search<IKibanaSearchRequest, IKibanaSearchResponse>(
{
params: getSampleOfDocumentsForNonAggregatableFields(
nonAggregatableFields,
supportedNonAggregatableFields,
index,
searchQuery,
timeFieldName,
@ -244,7 +248,7 @@ export function useOverallStats<TParams extends OverallStatsSearchStrategyParams
})
);
const nonAggregatableFieldsObs = nonAggregatableFields.map((fieldName: string) =>
const nonAggregatableFieldsObs = supportedNonAggregatableFields.map((fieldName: string) =>
data.search
.search<IKibanaSearchRequest, IKibanaSearchResponse>(
{

View file

@ -252,6 +252,10 @@ export const checkNonAggregatableFieldExistsRequest = (
const DEFAULT_DOCS_SAMPLE_OF_TEXT_FIELDS_SIZE = 1000;
export const isUnsupportedVectorField = (fieldName: string) => {
return fieldName.endsWith('.chunks.embeddings') || fieldName.endsWith('.chunks.offset');
};
export const getSampleOfDocumentsForNonAggregatableFields = (
nonAggregatableFields: string[],
dataViewTitle: string,
@ -305,6 +309,19 @@ export const processNonAggregatableFieldsExistResponse = (
});
return;
}
if (isUnsupportedVectorField(fieldName)) {
stats.nonAggregatableExistsFields.push({
fieldName,
existsInDocs: true,
stats: {
count: undefined,
cardinality: undefined,
sampleCount: undefined,
},
});
return;
}
const foundField = results.find((r) => r.rawResponse.fieldName === fieldName);
const existsInDocs = foundField !== undefined && foundField.rawResponse.hits.total > 0;