mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-05-09 09:53:26 +01:00
Add Vector Index Shard Key option on container creation (#2097)
* Add vector index shard key * npm run format * rename shard key to vector index shard key * add tooltip for quantization byte size * change text for GSI and container in VectorEmbedding Policy --------- Co-authored-by: Asier Isayas <aisayas@microsoft.com>
This commit is contained in:
parent
205355bf55
commit
10cda21401
@ -210,7 +210,7 @@ export interface IndexingPolicy {
|
|||||||
export interface VectorIndex {
|
export interface VectorIndex {
|
||||||
path: string;
|
path: string;
|
||||||
type: "flat" | "diskANN" | "quantizedFlat";
|
type: "flat" | "diskANN" | "quantizedFlat";
|
||||||
diskANNShardKey?: string;
|
vectorIndexShardKey?: string[];
|
||||||
indexingSearchListSize?: number;
|
indexingSearchListSize?: number;
|
||||||
quantizationByteSize?: number;
|
quantizationByteSize?: number;
|
||||||
}
|
}
|
||||||
|
@ -1215,6 +1215,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
|||||||
isFullTextSearchEnabled: this.isFullTextSearchEnabled,
|
isFullTextSearchEnabled: this.isFullTextSearchEnabled,
|
||||||
shouldDiscardContainerPolicies: this.state.shouldDiscardContainerPolicies,
|
shouldDiscardContainerPolicies: this.state.shouldDiscardContainerPolicies,
|
||||||
resetShouldDiscardContainerPolicyChange: this.resetShouldDiscardContainerPolicies,
|
resetShouldDiscardContainerPolicyChange: this.resetShouldDiscardContainerPolicies,
|
||||||
|
isGlobalSecondaryIndex: this.isGlobalSecondaryIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
const indexingPolicyComponentProps: IndexingPolicyComponentProps = {
|
const indexingPolicyComponentProps: IndexingPolicyComponentProps = {
|
||||||
|
@ -22,6 +22,7 @@ export interface ContainerPolicyComponentProps {
|
|||||||
isFullTextSearchEnabled: boolean;
|
isFullTextSearchEnabled: boolean;
|
||||||
shouldDiscardContainerPolicies: boolean;
|
shouldDiscardContainerPolicies: boolean;
|
||||||
resetShouldDiscardContainerPolicyChange: () => void;
|
resetShouldDiscardContainerPolicyChange: () => void;
|
||||||
|
isGlobalSecondaryIndex?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ContainerPolicyComponent: React.FC<ContainerPolicyComponentProps> = ({
|
export const ContainerPolicyComponent: React.FC<ContainerPolicyComponentProps> = ({
|
||||||
|
@ -9,6 +9,7 @@ import {
|
|||||||
Stack,
|
Stack,
|
||||||
TextField,
|
TextField,
|
||||||
} from "@fluentui/react";
|
} from "@fluentui/react";
|
||||||
|
import { InfoTooltip } from "Common/Tooltip/InfoTooltip";
|
||||||
import { VectorEmbedding, VectorIndex } from "Contracts/DataModels";
|
import { VectorEmbedding, VectorIndex } from "Contracts/DataModels";
|
||||||
import { CollapsibleSectionComponent } from "Explorer/Controls/CollapsiblePanel/CollapsibleSectionComponent";
|
import { CollapsibleSectionComponent } from "Explorer/Controls/CollapsiblePanel/CollapsibleSectionComponent";
|
||||||
import {
|
import {
|
||||||
@ -29,6 +30,7 @@ export interface IVectorEmbeddingPoliciesComponentProps {
|
|||||||
discardChanges?: boolean;
|
discardChanges?: boolean;
|
||||||
onChangesDiscarded?: () => void;
|
onChangesDiscarded?: () => void;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
isGlobalSecondaryIndex?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VectorEmbeddingPolicyData {
|
export interface VectorEmbeddingPolicyData {
|
||||||
@ -39,8 +41,7 @@ export interface VectorEmbeddingPolicyData {
|
|||||||
indexType: VectorIndex["type"] | "none";
|
indexType: VectorIndex["type"] | "none";
|
||||||
pathError: string;
|
pathError: string;
|
||||||
dimensionsError: string;
|
dimensionsError: string;
|
||||||
diskANNShardKey?: string;
|
vectorIndexShardKey?: string[];
|
||||||
diskANNShardKeyError?: string;
|
|
||||||
indexingSearchListSize?: number;
|
indexingSearchListSize?: number;
|
||||||
indexingSearchListSizeError?: string;
|
indexingSearchListSizeError?: string;
|
||||||
quantizationByteSize?: number;
|
quantizationByteSize?: number;
|
||||||
@ -87,6 +88,7 @@ export const VectorEmbeddingPoliciesComponent: FunctionComponent<IVectorEmbeddin
|
|||||||
discardChanges,
|
discardChanges,
|
||||||
onChangesDiscarded,
|
onChangesDiscarded,
|
||||||
disabled,
|
disabled,
|
||||||
|
isGlobalSecondaryIndex,
|
||||||
}): JSX.Element => {
|
}): JSX.Element => {
|
||||||
const onVectorEmbeddingPathError = (path: string, index?: number): string => {
|
const onVectorEmbeddingPathError = (path: string, index?: number): string => {
|
||||||
let error = "";
|
let error = "";
|
||||||
@ -132,12 +134,6 @@ export const VectorEmbeddingPoliciesComponent: FunctionComponent<IVectorEmbeddin
|
|||||||
return error;
|
return error;
|
||||||
};
|
};
|
||||||
|
|
||||||
//TODO: no restrictions yet due to this field being removed for now.
|
|
||||||
// Uncomment and replace with validation code when field is reinstated
|
|
||||||
// const onDiskANNShardKeyError = (shardKey: string): string => {
|
|
||||||
// return "";
|
|
||||||
// };
|
|
||||||
|
|
||||||
const initializeData = (vectorEmbeddings: VectorEmbedding[], vectorIndexes: VectorIndex[]) => {
|
const initializeData = (vectorEmbeddings: VectorEmbedding[], vectorIndexes: VectorIndex[]) => {
|
||||||
const mergedData: VectorEmbeddingPolicyData[] = [];
|
const mergedData: VectorEmbeddingPolicyData[] = [];
|
||||||
vectorEmbeddings.forEach((embedding) => {
|
vectorEmbeddings.forEach((embedding) => {
|
||||||
@ -147,6 +143,7 @@ export const VectorEmbeddingPoliciesComponent: FunctionComponent<IVectorEmbeddin
|
|||||||
indexType: matchingIndex?.type || "none",
|
indexType: matchingIndex?.type || "none",
|
||||||
indexingSearchListSize: matchingIndex?.indexingSearchListSize || undefined,
|
indexingSearchListSize: matchingIndex?.indexingSearchListSize || undefined,
|
||||||
quantizationByteSize: matchingIndex?.quantizationByteSize || undefined,
|
quantizationByteSize: matchingIndex?.quantizationByteSize || undefined,
|
||||||
|
vectorIndexShardKey: matchingIndex?.vectorIndexShardKey || undefined,
|
||||||
pathError: onVectorEmbeddingPathError(embedding.path),
|
pathError: onVectorEmbeddingPathError(embedding.path),
|
||||||
dimensionsError: onVectorEmbeddingDimensionError(embedding.dimensions, matchingIndex?.type || "none"),
|
dimensionsError: onVectorEmbeddingDimensionError(embedding.dimensions, matchingIndex?.type || "none"),
|
||||||
});
|
});
|
||||||
@ -186,6 +183,7 @@ export const VectorEmbeddingPoliciesComponent: FunctionComponent<IVectorEmbeddin
|
|||||||
type: policy.indexType,
|
type: policy.indexType,
|
||||||
indexingSearchListSize: policy.indexingSearchListSize,
|
indexingSearchListSize: policy.indexingSearchListSize,
|
||||||
quantizationByteSize: policy.quantizationByteSize,
|
quantizationByteSize: policy.quantizationByteSize,
|
||||||
|
vectorIndexShardKey: policy.vectorIndexShardKey,
|
||||||
}) as VectorIndex,
|
}) as VectorIndex,
|
||||||
);
|
);
|
||||||
const validationPassed = vectorEmbeddingPolicyData.every(
|
const validationPassed = vectorEmbeddingPolicyData.every(
|
||||||
@ -247,20 +245,16 @@ export const VectorEmbeddingPoliciesComponent: FunctionComponent<IVectorEmbeddin
|
|||||||
setVectorEmbeddingPolicyData(vectorEmbeddings);
|
setVectorEmbeddingPolicyData(vectorEmbeddings);
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: uncomment after Ignite
|
const onShardKeyChange = (index: number, event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
// DiskANNShardKey was removed for Ignite due to backend problems. Leaving this here as it will be reinstated immediately after Ignite
|
const value = event.target.value.trim();
|
||||||
// const onDiskANNShardKeyChange = (index: number, event: React.ChangeEvent<HTMLInputElement>) => {
|
const vectorEmbeddings = [...vectorEmbeddingPolicyData];
|
||||||
// const value = event.target.value.trim();
|
if (!vectorEmbeddings[index]?.vectorIndexShardKey?.[0] && !value.startsWith("/")) {
|
||||||
// const vectorEmbeddings = [...vectorEmbeddingPolicyData];
|
vectorEmbeddings[index].vectorIndexShardKey = ["/" + value];
|
||||||
// if (!vectorEmbeddings[index]?.diskANNShardKey && !value.startsWith("/")) {
|
} else {
|
||||||
// vectorEmbeddings[index].diskANNShardKey = "/" + value;
|
vectorEmbeddings[index].vectorIndexShardKey = [value];
|
||||||
// } else {
|
}
|
||||||
// vectorEmbeddings[index].diskANNShardKey = value;
|
setVectorEmbeddingPolicyData(vectorEmbeddings);
|
||||||
// }
|
};
|
||||||
// const error = onDiskANNShardKeyError(value);
|
|
||||||
// vectorEmbeddings[index].diskANNShardKeyError = error;
|
|
||||||
// setVectorEmbeddingPolicyData(vectorEmbeddings);
|
|
||||||
// }
|
|
||||||
|
|
||||||
const onVectorEmbeddingPolicyChange = (
|
const onVectorEmbeddingPolicyChange = (
|
||||||
index: number,
|
index: number,
|
||||||
@ -292,6 +286,11 @@ export const VectorEmbeddingPoliciesComponent: FunctionComponent<IVectorEmbeddin
|
|||||||
setVectorEmbeddingPolicyData(vectorEmbeddings);
|
setVectorEmbeddingPolicyData(vectorEmbeddings);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getQuantizationByteSizeTooltipContent = (): string => {
|
||||||
|
const containerName: string = isGlobalSecondaryIndex ? "global secondary index" : "container";
|
||||||
|
return `This is dynamically set by the ${containerName} if left blank, or it can be set to a fixed number`;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack tokens={{ childrenGap: 4 }}>
|
<Stack tokens={{ childrenGap: 4 }}>
|
||||||
{vectorEmbeddingPolicyData &&
|
{vectorEmbeddingPolicyData &&
|
||||||
@ -402,6 +401,7 @@ export const VectorEmbeddingPoliciesComponent: FunctionComponent<IVectorEmbeddin
|
|||||||
styles={labelStyles}
|
styles={labelStyles}
|
||||||
>
|
>
|
||||||
Quantization byte size
|
Quantization byte size
|
||||||
|
<InfoTooltip>{getQuantizationByteSizeTooltipContent()}</InfoTooltip>
|
||||||
</Label>
|
</Label>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={
|
disabled={
|
||||||
@ -431,26 +431,18 @@ export const VectorEmbeddingPoliciesComponent: FunctionComponent<IVectorEmbeddin
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
{/*TODO: uncomment after Ignite */}
|
<Stack style={{ marginLeft: "10px" }}>
|
||||||
{/* DiskANNShardKey was removed for Ignite due to backend problems. Leaving this here as it will be reinstated immediately after Ignite
|
<Label disabled={disabled || vectorEmbeddingPolicy.indexType !== "diskANN"} styles={labelStyles}>
|
||||||
<Stack
|
Vector index shard key
|
||||||
style={{ marginLeft: "10px" }}
|
</Label>
|
||||||
>
|
|
||||||
<Label
|
|
||||||
disabled={disabled || vectorEmbeddingPolicy.indexType !== "diskANN"}
|
|
||||||
styles={labelStyles}
|
|
||||||
>DiskANN shard key</Label>
|
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled || vectorEmbeddingPolicy.indexType !== "diskANN"}
|
disabled={disabled || vectorEmbeddingPolicy.indexType !== "diskANN"}
|
||||||
id={`vector-policy-diskANNShardKey-${index + 1}`}
|
id={`vector-policy-vectorIndexShardKey-${index + 1}`}
|
||||||
styles={textFieldStyles}
|
styles={textFieldStyles}
|
||||||
value={String(vectorEmbeddingPolicy.diskANNShardKey || "")}
|
value={String(vectorEmbeddingPolicy.vectorIndexShardKey?.[0] ?? "")}
|
||||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
|
onChange={(event: React.ChangeEvent<HTMLInputElement>) => onShardKeyChange(index, event)}
|
||||||
onDiskANNShardKeyChange(index, event)
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
*/}
|
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
@ -388,6 +388,7 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
|
|||||||
setVectorIndexingPolicy,
|
setVectorIndexingPolicy,
|
||||||
vectorPolicyValidated,
|
vectorPolicyValidated,
|
||||||
setVectorPolicyValidated,
|
setVectorPolicyValidated,
|
||||||
|
isGlobalSecondaryIndex: true,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -14,6 +14,7 @@ export interface VectorSearchComponentProps {
|
|||||||
vectorIndexingPolicy: VectorIndex[];
|
vectorIndexingPolicy: VectorIndex[];
|
||||||
setVectorIndexingPolicy: React.Dispatch<React.SetStateAction<VectorIndex[]>>;
|
setVectorIndexingPolicy: React.Dispatch<React.SetStateAction<VectorIndex[]>>;
|
||||||
setVectorPolicyValidated: React.Dispatch<React.SetStateAction<boolean>>;
|
setVectorPolicyValidated: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
isGlobalSecondaryIndex?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VectorSearchComponent = (props: VectorSearchComponentProps): JSX.Element => {
|
export const VectorSearchComponent = (props: VectorSearchComponentProps): JSX.Element => {
|
||||||
@ -23,6 +24,7 @@ export const VectorSearchComponent = (props: VectorSearchComponentProps): JSX.El
|
|||||||
vectorIndexingPolicy,
|
vectorIndexingPolicy,
|
||||||
setVectorIndexingPolicy,
|
setVectorIndexingPolicy,
|
||||||
setVectorPolicyValidated,
|
setVectorPolicyValidated,
|
||||||
|
isGlobalSecondaryIndex,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -49,6 +51,7 @@ export const VectorSearchComponent = (props: VectorSearchComponentProps): JSX.El
|
|||||||
setVectorIndexingPolicy(vectorIndexingPolicy);
|
setVectorIndexingPolicy(vectorIndexingPolicy);
|
||||||
setVectorPolicyValidated(vectorPolicyValidated);
|
setVectorPolicyValidated(vectorPolicyValidated);
|
||||||
}}
|
}}
|
||||||
|
isGlobalSecondaryIndex={isGlobalSecondaryIndex}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user