Vector search for NoSQL accounts (#1843)
* Add container vector policy and indexing policy support * Add vector search capability * hide vector settings for shared throughput DB * update package-lock * fix pipeline * remove comments * Address comments * Address comments
This commit is contained in:
parent
4da3363cf7
commit
ceeead8458
|
@ -10,7 +10,7 @@
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/arm-cosmosdb": "9.1.0",
|
"@azure/arm-cosmosdb": "9.1.0",
|
||||||
"@azure/cosmos": "4.0.1-beta.2",
|
"@azure/cosmos": "4.0.1-beta.3",
|
||||||
"@azure/cosmos-language-service": "0.0.5",
|
"@azure/cosmos-language-service": "0.0.5",
|
||||||
"@azure/identity": "1.5.2",
|
"@azure/identity": "1.5.2",
|
||||||
"@azure/ms-rest-nodeauth": "3.1.1",
|
"@azure/ms-rest-nodeauth": "3.1.1",
|
||||||
|
@ -362,9 +362,9 @@
|
||||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||||
},
|
},
|
||||||
"node_modules/@azure/cosmos": {
|
"node_modules/@azure/cosmos": {
|
||||||
"version": "4.0.1-beta.2",
|
"version": "4.0.1-beta.3",
|
||||||
"resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-4.0.1-beta.2.tgz",
|
"resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-4.0.1-beta.3.tgz",
|
||||||
"integrity": "sha512-iuqg/QwLQlxgRi4pnXU8JUYv+f24wkRvJ9ZZI4/sYk+DxSgkuQ194Cc2IpckpeO8z7ZpcBkVQFa82wcZVVZ8Zg==",
|
"integrity": "sha512-CpRGt+S5jnvtGUi4TmlS79YvxpbNc8/5/QHgIvvQ9D2ZFUqO0MjbMCU3lVZV2NAJT02BsbLfRAFe+FPn8nMRQw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/abort-controller": "^1.0.0",
|
"@azure/abort-controller": "^1.0.0",
|
||||||
"@azure/core-auth": "^1.3.0",
|
"@azure/core-auth": "^1.3.0",
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@azure/arm-cosmosdb": "9.1.0",
|
"@azure/arm-cosmosdb": "9.1.0",
|
||||||
"@azure/cosmos": "4.0.1-beta.2",
|
"@azure/cosmos": "4.0.1-beta.3",
|
||||||
"@azure/cosmos-language-service": "0.0.5",
|
"@azure/cosmos-language-service": "0.0.5",
|
||||||
"@azure/identity": "1.5.2",
|
"@azure/identity": "1.5.2",
|
||||||
"@azure/ms-rest-nodeauth": "3.1.1",
|
"@azure/ms-rest-nodeauth": "3.1.1",
|
||||||
|
|
|
@ -88,6 +88,7 @@ export class CapabilityNames {
|
||||||
public static readonly EnableStorageAnalytics: string = "EnableStorageAnalytics";
|
public static readonly EnableStorageAnalytics: string = "EnableStorageAnalytics";
|
||||||
public static readonly EnableMongo: string = "EnableMongo";
|
public static readonly EnableMongo: string = "EnableMongo";
|
||||||
public static readonly EnableServerless: string = "EnableServerless";
|
public static readonly EnableServerless: string = "EnableServerless";
|
||||||
|
public static readonly EnableNoSQLVectorSearch: string = "EnableNoSQLVectorSearch";
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum CapacityMode {
|
export enum CapacityMode {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
exports[`getCommonQueryOptions builds the correct default options objects 1`] = `
|
exports[`getCommonQueryOptions builds the correct default options objects 1`] = `
|
||||||
Object {
|
Object {
|
||||||
|
"disableNonStreamingOrderByQuery": true,
|
||||||
"enableScanInQuery": true,
|
"enableScanInQuery": true,
|
||||||
"forceQueryPlan": true,
|
"forceQueryPlan": true,
|
||||||
"maxDegreeOfParallelism": 0,
|
"maxDegreeOfParallelism": 0,
|
||||||
|
@ -12,6 +13,7 @@ Object {
|
||||||
|
|
||||||
exports[`getCommonQueryOptions reads from localStorage 1`] = `
|
exports[`getCommonQueryOptions reads from localStorage 1`] = `
|
||||||
Object {
|
Object {
|
||||||
|
"disableNonStreamingOrderByQuery": true,
|
||||||
"enableScanInQuery": true,
|
"enableScanInQuery": true,
|
||||||
"forceQueryPlan": true,
|
"forceQueryPlan": true,
|
||||||
"maxDegreeOfParallelism": 17,
|
"maxDegreeOfParallelism": 17,
|
||||||
|
|
|
@ -6,13 +6,13 @@ import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstan
|
||||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||||
import { userContext } from "../../UserContext";
|
import { userContext } from "../../UserContext";
|
||||||
import { getCollectionName } from "../../Utils/APITypeUtils";
|
import { getCollectionName } from "../../Utils/APITypeUtils";
|
||||||
|
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
|
||||||
import { createUpdateCassandraTable } from "../../Utils/arm/generatedClients/cosmos/cassandraResources";
|
import { createUpdateCassandraTable } from "../../Utils/arm/generatedClients/cosmos/cassandraResources";
|
||||||
import { createUpdateGremlinGraph } from "../../Utils/arm/generatedClients/cosmos/gremlinResources";
|
import { createUpdateGremlinGraph } from "../../Utils/arm/generatedClients/cosmos/gremlinResources";
|
||||||
import { createUpdateMongoDBCollection } from "../../Utils/arm/generatedClients/cosmos/mongoDBResources";
|
import { createUpdateMongoDBCollection } from "../../Utils/arm/generatedClients/cosmos/mongoDBResources";
|
||||||
import { createUpdateSqlContainer } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
|
import { createUpdateSqlContainer } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
|
||||||
import { createUpdateTable } from "../../Utils/arm/generatedClients/cosmos/tableResources";
|
import { createUpdateTable } from "../../Utils/arm/generatedClients/cosmos/tableResources";
|
||||||
import * as ARMTypes from "../../Utils/arm/generatedClients/cosmos/types";
|
import * as ARMTypes from "../../Utils/arm/generatedClients/cosmos/types";
|
||||||
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
|
|
||||||
import { client } from "../CosmosClient";
|
import { client } from "../CosmosClient";
|
||||||
import { handleError } from "../ErrorHandlingUtils";
|
import { handleError } from "../ErrorHandlingUtils";
|
||||||
import { createMongoCollectionWithProxy } from "../MongoProxyClient";
|
import { createMongoCollectionWithProxy } from "../MongoProxyClient";
|
||||||
|
@ -96,6 +96,9 @@ const createSqlContainer = async (params: DataModels.CreateCollectionParams): Pr
|
||||||
if (params.uniqueKeyPolicy) {
|
if (params.uniqueKeyPolicy) {
|
||||||
resource.uniqueKeyPolicy = params.uniqueKeyPolicy;
|
resource.uniqueKeyPolicy = params.uniqueKeyPolicy;
|
||||||
}
|
}
|
||||||
|
if (params.vectorEmbeddingPolicy) {
|
||||||
|
resource.vectorEmbeddingPolicy = params.vectorEmbeddingPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
const rpPayload: ARMTypes.SqlDatabaseCreateUpdateParameters = {
|
const rpPayload: ARMTypes.SqlDatabaseCreateUpdateParameters = {
|
||||||
properties: {
|
properties: {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { FeedOptions, ItemDefinition, QueryIterator, Resource } from "@azure/cosmos";
|
import { FeedOptions, ItemDefinition, QueryIterator, Resource } from "@azure/cosmos";
|
||||||
|
import { isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
||||||
import { LocalStorageUtility, StorageKey } from "../../Shared/StorageUtility";
|
import { LocalStorageUtility, StorageKey } from "../../Shared/StorageUtility";
|
||||||
import { Queries } from "../Constants";
|
import { Queries } from "../Constants";
|
||||||
import { client } from "../CosmosClient";
|
import { client } from "../CosmosClient";
|
||||||
|
@ -26,5 +27,6 @@ export const getCommonQueryOptions = (options: FeedOptions): FeedOptions => {
|
||||||
(storedItemPerPageSetting !== undefined && storedItemPerPageSetting) ||
|
(storedItemPerPageSetting !== undefined && storedItemPerPageSetting) ||
|
||||||
Queries.itemsPerPage;
|
Queries.itemsPerPage;
|
||||||
options.maxDegreeOfParallelism = LocalStorageUtility.getEntryNumber(StorageKey.MaxDegreeOfParellism);
|
options.maxDegreeOfParallelism = LocalStorageUtility.getEntryNumber(StorageKey.MaxDegreeOfParellism);
|
||||||
|
options.disableNonStreamingOrderByQuery = !isVectorSearchEnabled();
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
|
|
@ -158,6 +158,7 @@ export interface Collection extends Resource {
|
||||||
changeFeedPolicy?: ChangeFeedPolicy;
|
changeFeedPolicy?: ChangeFeedPolicy;
|
||||||
analyticalStorageTtl?: number;
|
analyticalStorageTtl?: number;
|
||||||
geospatialConfig?: GeospatialConfig;
|
geospatialConfig?: GeospatialConfig;
|
||||||
|
vectorEmbeddingPolicy?: VectorEmbeddingPolicy;
|
||||||
schema?: ISchema;
|
schema?: ISchema;
|
||||||
requestSchema?: () => void;
|
requestSchema?: () => void;
|
||||||
computedProperties?: ComputedProperties;
|
computedProperties?: ComputedProperties;
|
||||||
|
@ -195,8 +196,14 @@ export interface IndexingPolicy {
|
||||||
indexingMode: "consistent" | "lazy" | "none";
|
indexingMode: "consistent" | "lazy" | "none";
|
||||||
includedPaths: any;
|
includedPaths: any;
|
||||||
excludedPaths: any;
|
excludedPaths: any;
|
||||||
compositeIndexes?: any;
|
compositeIndexes?: any[];
|
||||||
spatialIndexes?: any;
|
spatialIndexes?: any[];
|
||||||
|
vectorIndexes?: VectorIndex[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VectorIndex {
|
||||||
|
path: string;
|
||||||
|
type: "flat" | "diskANN" | "quantizedFlat";
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ComputedProperty {
|
export interface ComputedProperty {
|
||||||
|
@ -334,6 +341,18 @@ export interface CreateCollectionParams {
|
||||||
partitionKey?: PartitionKey;
|
partitionKey?: PartitionKey;
|
||||||
uniqueKeyPolicy?: UniqueKeyPolicy;
|
uniqueKeyPolicy?: UniqueKeyPolicy;
|
||||||
createMongoWildcardIndex?: boolean;
|
createMongoWildcardIndex?: boolean;
|
||||||
|
vectorEmbeddingPolicy?: VectorEmbeddingPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VectorEmbeddingPolicy {
|
||||||
|
vectorEmbeddings: VectorEmbedding[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VectorEmbedding {
|
||||||
|
dataType: "float16" | "float32" | "uint8" | "int8";
|
||||||
|
dimensions: number;
|
||||||
|
distanceFunction: "euclidean" | "cosine" | "dotproduct";
|
||||||
|
path: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ReadDatabaseOfferParams {
|
export interface ReadDatabaseOfferParams {
|
||||||
|
|
|
@ -26,8 +26,8 @@ export class CollapsibleSectionComponent extends React.Component<CollapsibleSect
|
||||||
this.setState({ isExpanded: !this.state.isExpanded });
|
this.setState({ isExpanded: !this.state.isExpanded });
|
||||||
};
|
};
|
||||||
|
|
||||||
public componentDidUpdate(): void {
|
public componentDidUpdate(_prevProps: CollapsibleSectionProps, prevState: CollapsibleSectionState): void {
|
||||||
if (this.state.isExpanded && this.props.onExpand) {
|
if (!prevState.isExpanded && this.state.isExpanded && this.props.onExpand) {
|
||||||
this.props.onExpand();
|
this.props.onExpand();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ export class CollapsibleSectionComponent extends React.Component<CollapsibleSect
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Stack
|
<Stack
|
||||||
className="collapsibleSection"
|
className={"collapsibleSection"}
|
||||||
horizontal
|
horizontal
|
||||||
verticalAlign="center"
|
verticalAlign="center"
|
||||||
tokens={accordionStackTokens}
|
tokens={accordionStackTokens}
|
||||||
|
|
|
@ -20,7 +20,10 @@ export interface EditorReactProps {
|
||||||
lineDecorationsWidth?: monaco.editor.IEditorOptions["lineDecorationsWidth"];
|
lineDecorationsWidth?: monaco.editor.IEditorOptions["lineDecorationsWidth"];
|
||||||
minimap?: monaco.editor.IEditorOptions["minimap"];
|
minimap?: monaco.editor.IEditorOptions["minimap"];
|
||||||
scrollBeyondLastLine?: monaco.editor.IEditorOptions["scrollBeyondLastLine"];
|
scrollBeyondLastLine?: monaco.editor.IEditorOptions["scrollBeyondLastLine"];
|
||||||
|
fontSize?: monaco.editor.IEditorOptions["fontSize"];
|
||||||
monacoContainerStyles?: React.CSSProperties;
|
monacoContainerStyles?: React.CSSProperties;
|
||||||
|
className?: string;
|
||||||
|
spinnerClassName?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EditorReact extends React.Component<EditorReactProps, EditorReactStates> {
|
export class EditorReact extends React.Component<EditorReactProps, EditorReactStates> {
|
||||||
|
@ -75,9 +78,11 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{!this.state.showEditor && <Spinner size={SpinnerSize.large} className="spinner" />}
|
{!this.state.showEditor && (
|
||||||
|
<Spinner size={SpinnerSize.large} className={this.props.spinnerClassName || "spinner"} />
|
||||||
|
)}
|
||||||
<div
|
<div
|
||||||
className="jsonEditor"
|
className={this.props.className || "jsonEditor"}
|
||||||
style={this.props.monacoContainerStyles}
|
style={this.props.monacoContainerStyles}
|
||||||
ref={(elt: HTMLElement) => this.setRef(elt)}
|
ref={(elt: HTMLElement) => this.setRef(elt)}
|
||||||
/>
|
/>
|
||||||
|
@ -119,7 +124,7 @@ export class EditorReact extends React.Component<EditorReactProps, EditorReactSt
|
||||||
value: this.props.content,
|
value: this.props.content,
|
||||||
readOnly: this.props.isReadOnly,
|
readOnly: this.props.isReadOnly,
|
||||||
ariaLabel: this.props.ariaLabel,
|
ariaLabel: this.props.ariaLabel,
|
||||||
fontSize: 12,
|
fontSize: this.props.fontSize || 12,
|
||||||
automaticLayout: true,
|
automaticLayout: true,
|
||||||
theme: this.props.theme,
|
theme: this.props.theme,
|
||||||
wordWrap: this.props.wordWrap || "off",
|
wordWrap: this.props.wordWrap || "off",
|
||||||
|
|
|
@ -7,14 +7,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.settingsV2ToolTip {
|
.settingsV2ToolTip {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
font: 12px @DataExplorerFont;
|
font: 12px @DataExplorerFont;
|
||||||
max-width: 300px;
|
max-width: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.autoPilotSelector span {
|
.autoPilotSelector span {
|
||||||
height: 25px;
|
height: 25px;
|
||||||
font: 14px @DataExplorerFont;
|
font: 14px @DataExplorerFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settingsV2TabsContainer {
|
.settingsV2TabsContainer {
|
||||||
|
@ -25,7 +25,14 @@
|
||||||
font-family: @DataExplorerFont;
|
font-family: @DataExplorerFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settingsV2IndexingPolicyEditor {
|
.settingsV2Editor {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 60vh;
|
height: 60vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.settingsV2EditorSpinner {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,12 @@ import {
|
||||||
ComputedPropertiesComponent,
|
ComputedPropertiesComponent,
|
||||||
ComputedPropertiesComponentProps,
|
ComputedPropertiesComponentProps,
|
||||||
} from "Explorer/Controls/Settings/SettingsSubComponents/ComputedPropertiesComponent";
|
} from "Explorer/Controls/Settings/SettingsSubComponents/ComputedPropertiesComponent";
|
||||||
|
import {
|
||||||
|
ContainerVectorPolicyComponent,
|
||||||
|
ContainerVectorPolicyComponentProps,
|
||||||
|
} from "Explorer/Controls/Settings/SettingsSubComponents/ContainerVectorPolicyComponent";
|
||||||
import { useDatabases } from "Explorer/useDatabases";
|
import { useDatabases } from "Explorer/useDatabases";
|
||||||
|
import { isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
||||||
import { isRunningOnPublicCloud } from "Utils/CloudUtils";
|
import { isRunningOnPublicCloud } from "Utils/CloudUtils";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import DiscardIcon from "../../../../images/discard.svg";
|
import DiscardIcon from "../../../../images/discard.svg";
|
||||||
|
@ -144,6 +149,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||||
private shouldShowComputedPropertiesEditor: boolean;
|
private shouldShowComputedPropertiesEditor: boolean;
|
||||||
private shouldShowIndexingPolicyEditor: boolean;
|
private shouldShowIndexingPolicyEditor: boolean;
|
||||||
private shouldShowPartitionKeyEditor: boolean;
|
private shouldShowPartitionKeyEditor: boolean;
|
||||||
|
private isVectorSearchEnabled: boolean;
|
||||||
private totalThroughputUsed: number;
|
private totalThroughputUsed: number;
|
||||||
public mongoDBCollectionResource: MongoDBCollectionResource;
|
public mongoDBCollectionResource: MongoDBCollectionResource;
|
||||||
|
|
||||||
|
@ -158,6 +164,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||||
this.shouldShowComputedPropertiesEditor = userContext.apiType === "SQL";
|
this.shouldShowComputedPropertiesEditor = userContext.apiType === "SQL";
|
||||||
this.shouldShowIndexingPolicyEditor = userContext.apiType !== "Cassandra" && userContext.apiType !== "Mongo";
|
this.shouldShowIndexingPolicyEditor = userContext.apiType !== "Cassandra" && userContext.apiType !== "Mongo";
|
||||||
this.shouldShowPartitionKeyEditor = userContext.apiType === "SQL" && isRunningOnPublicCloud();
|
this.shouldShowPartitionKeyEditor = userContext.apiType === "SQL" && isRunningOnPublicCloud();
|
||||||
|
this.isVectorSearchEnabled = isVectorSearchEnabled() && !hasDatabaseSharedThroughput(this.collection);
|
||||||
|
|
||||||
this.changeFeedPolicyVisible = userContext.features.enableChangeFeedPolicy;
|
this.changeFeedPolicyVisible = userContext.features.enableChangeFeedPolicy;
|
||||||
|
|
||||||
|
@ -1097,6 +1104,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||||
indexTransformationProgress: this.state.indexTransformationProgress,
|
indexTransformationProgress: this.state.indexTransformationProgress,
|
||||||
refreshIndexTransformationProgress: this.refreshIndexTransformationProgress,
|
refreshIndexTransformationProgress: this.refreshIndexTransformationProgress,
|
||||||
onIndexingPolicyDirtyChange: this.onIndexingPolicyDirtyChange,
|
onIndexingPolicyDirtyChange: this.onIndexingPolicyDirtyChange,
|
||||||
|
isVectorSearchEnabled: this.isVectorSearchEnabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mongoIndexingPolicyComponentProps: MongoIndexingPolicyComponentProps = {
|
const mongoIndexingPolicyComponentProps: MongoIndexingPolicyComponentProps = {
|
||||||
|
@ -1143,6 +1151,10 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||||
explorer: this.props.settingsTab.getContainer(),
|
explorer: this.props.settingsTab.getContainer(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const containerVectorPolicyProps: ContainerVectorPolicyComponentProps = {
|
||||||
|
vectorEmbeddingPolicy: this.collection.rawDataModel?.vectorEmbeddingPolicy,
|
||||||
|
};
|
||||||
|
|
||||||
const tabs: SettingsV2TabInfo[] = [];
|
const tabs: SettingsV2TabInfo[] = [];
|
||||||
if (!hasDatabaseSharedThroughput(this.collection) && this.offer) {
|
if (!hasDatabaseSharedThroughput(this.collection) && this.offer) {
|
||||||
tabs.push({
|
tabs.push({
|
||||||
|
@ -1156,6 +1168,13 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
|
||||||
content: <SubSettingsComponent {...subSettingsComponentProps} />,
|
content: <SubSettingsComponent {...subSettingsComponentProps} />,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (this.isVectorSearchEnabled) {
|
||||||
|
tabs.push({
|
||||||
|
tab: SettingsV2TabTypes.ContainerVectorPolicyTab,
|
||||||
|
content: <ContainerVectorPolicyComponent {...containerVectorPolicyProps} />,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (this.shouldShowIndexingPolicyEditor) {
|
if (this.shouldShowIndexingPolicyEditor) {
|
||||||
tabs.push({
|
tabs.push({
|
||||||
tab: SettingsV2TabTypes.IndexingPolicyTab,
|
tab: SettingsV2TabTypes.IndexingPolicyTab,
|
||||||
|
|
|
@ -121,7 +121,7 @@ export class ComputedPropertiesComponent extends React.Component<
|
||||||
</Link>
|
</Link>
|
||||||
  about how to define computed properties and how to use them.
|
  about how to define computed properties and how to use them.
|
||||||
</Text>
|
</Text>
|
||||||
<div className="settingsV2IndexingPolicyEditor" tabIndex={0} ref={this.computedPropertiesDiv}></div>
|
<div className="settingsV2Editor" tabIndex={0} ref={this.computedPropertiesDiv}></div>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { Stack } from "@fluentui/react";
|
||||||
|
import { VectorEmbeddingPolicy } from "Contracts/DataModels";
|
||||||
|
import { EditorReact } from "Explorer/Controls/Editor/EditorReact";
|
||||||
|
import { titleAndInputStackProps } from "Explorer/Controls/Settings/SettingsRenderUtils";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export interface ContainerVectorPolicyComponentProps {
|
||||||
|
vectorEmbeddingPolicy: VectorEmbeddingPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ContainerVectorPolicyComponent: React.FC<ContainerVectorPolicyComponentProps> = ({
|
||||||
|
vectorEmbeddingPolicy,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<Stack {...titleAndInputStackProps} styles={{ root: { position: "relative" } }}>
|
||||||
|
<EditorReact
|
||||||
|
language={"json"}
|
||||||
|
content={JSON.stringify(vectorEmbeddingPolicy, null, 4)}
|
||||||
|
isReadOnly={true}
|
||||||
|
wordWrap={"on"}
|
||||||
|
ariaLabel={"Container vector policy"}
|
||||||
|
lineNumbers={"on"}
|
||||||
|
scrollBeyondLastLine={false}
|
||||||
|
className={"settingsV2Editor"}
|
||||||
|
spinnerClassName={"settingsV2EditorSpinner"}
|
||||||
|
fontSize={14}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
};
|
|
@ -16,6 +16,7 @@ export interface IndexingPolicyComponentProps {
|
||||||
logIndexingPolicySuccessMessage: () => void;
|
logIndexingPolicySuccessMessage: () => void;
|
||||||
indexTransformationProgress: number;
|
indexTransformationProgress: number;
|
||||||
refreshIndexTransformationProgress: () => Promise<void>;
|
refreshIndexTransformationProgress: () => Promise<void>;
|
||||||
|
isVectorSearchEnabled?: boolean;
|
||||||
onIndexingPolicyDirtyChange: (isIndexingPolicyDirty: boolean) => void;
|
onIndexingPolicyDirtyChange: (isIndexingPolicyDirty: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,10 +120,15 @@ export class IndexingPolicyComponent extends React.Component<
|
||||||
indexTransformationProgress={this.props.indexTransformationProgress}
|
indexTransformationProgress={this.props.indexTransformationProgress}
|
||||||
refreshIndexTransformationProgress={this.props.refreshIndexTransformationProgress}
|
refreshIndexTransformationProgress={this.props.refreshIndexTransformationProgress}
|
||||||
/>
|
/>
|
||||||
|
{this.props.isVectorSearchEnabled && (
|
||||||
|
<MessageBar messageBarType={MessageBarType.severeWarning}>
|
||||||
|
Container vector policies and vector indexes are not modifiable after container creation
|
||||||
|
</MessageBar>
|
||||||
|
)}
|
||||||
{isDirty(this.props.indexingPolicyContent, this.props.indexingPolicyContentBaseline) && (
|
{isDirty(this.props.indexingPolicyContent, this.props.indexingPolicyContentBaseline) && (
|
||||||
<MessageBar messageBarType={MessageBarType.warning}>{unsavedEditorWarningMessage("indexPolicy")}</MessageBar>
|
<MessageBar messageBarType={MessageBarType.warning}>{unsavedEditorWarningMessage("indexPolicy")}</MessageBar>
|
||||||
)}
|
)}
|
||||||
<div className="settingsV2IndexingPolicyEditor" tabIndex={0} ref={this.indexingPolicyDiv}></div>
|
<div className="settingsV2Editor" tabIndex={0} ref={this.indexingPolicyDiv}></div>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ exports[`ComputedPropertiesComponent renders 1`] = `
|
||||||
about how to define computed properties and how to use them.
|
about how to define computed properties and how to use them.
|
||||||
</Text>
|
</Text>
|
||||||
<div
|
<div
|
||||||
className="settingsV2IndexingPolicyEditor"
|
className="settingsV2Editor"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
|
@ -12,7 +12,7 @@ exports[`IndexingPolicyComponent renders 1`] = `
|
||||||
refreshIndexTransformationProgress={[Function]}
|
refreshIndexTransformationProgress={[Function]}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className="settingsV2IndexingPolicyEditor"
|
className="settingsV2Editor"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
|
@ -47,6 +47,7 @@ export enum SettingsV2TabTypes {
|
||||||
IndexingPolicyTab,
|
IndexingPolicyTab,
|
||||||
PartitionKeyTab,
|
PartitionKeyTab,
|
||||||
ComputedPropertiesTab,
|
ComputedPropertiesTab,
|
||||||
|
ContainerVectorPolicyTab,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IsComponentDirtyResult {
|
export interface IsComponentDirtyResult {
|
||||||
|
@ -152,6 +153,8 @@ export const getTabTitle = (tab: SettingsV2TabTypes): string => {
|
||||||
return "Partition Keys (preview)";
|
return "Partition Keys (preview)";
|
||||||
case SettingsV2TabTypes.ComputedPropertiesTab:
|
case SettingsV2TabTypes.ComputedPropertiesTab:
|
||||||
return "Computed Properties";
|
return "Computed Properties";
|
||||||
|
case SettingsV2TabTypes.ContainerVectorPolicyTab:
|
||||||
|
return "Container Vector Policy (preview)";
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown tab ${tab}`);
|
throw new Error(`Unknown tab ${tab}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,6 +196,7 @@ exports[`SettingsComponent renders 1`] = `
|
||||||
"indexingMode": "consistent",
|
"indexingMode": "consistent",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
isVectorSearchEnabled={false}
|
||||||
logIndexingPolicySuccessMessage={[Function]}
|
logIndexingPolicySuccessMessage={[Function]}
|
||||||
onIndexingPolicyContentChange={[Function]}
|
onIndexingPolicyContentChange={[Function]}
|
||||||
onIndexingPolicyDirtyChange={[Function]}
|
onIndexingPolicyDirtyChange={[Function]}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import { getErrorMessage, getErrorStack } from "Common/ErrorHandlingUtils";
|
||||||
import { configContext, Platform } from "ConfigContext";
|
import { configContext, Platform } from "ConfigContext";
|
||||||
import * as DataModels from "Contracts/DataModels";
|
import * as DataModels from "Contracts/DataModels";
|
||||||
import { SubscriptionType } from "Contracts/SubscriptionType";
|
import { SubscriptionType } from "Contracts/SubscriptionType";
|
||||||
|
import { EditorReact } from "Explorer/Controls/Editor/EditorReact";
|
||||||
import { useSidePanel } from "hooks/useSidePanel";
|
import { useSidePanel } from "hooks/useSidePanel";
|
||||||
import { useTeachingBubble } from "hooks/useTeachingBubble";
|
import { useTeachingBubble } from "hooks/useTeachingBubble";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
@ -29,7 +30,7 @@ import { Action } from "Shared/Telemetry/TelemetryConstants";
|
||||||
import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
|
import * as TelemetryProcessor from "Shared/Telemetry/TelemetryProcessor";
|
||||||
import { userContext } from "UserContext";
|
import { userContext } from "UserContext";
|
||||||
import { getCollectionName } from "Utils/APITypeUtils";
|
import { getCollectionName } from "Utils/APITypeUtils";
|
||||||
import { isCapabilityEnabled, isServerlessAccount } from "Utils/CapabilityUtils";
|
import { isCapabilityEnabled, isServerlessAccount, isVectorSearchEnabled } from "Utils/CapabilityUtils";
|
||||||
import { getUpsellMessage } from "Utils/PricingUtils";
|
import { getUpsellMessage } from "Utils/PricingUtils";
|
||||||
import { CollapsibleSectionComponent } from "../Controls/CollapsiblePanel/CollapsibleSectionComponent";
|
import { CollapsibleSectionComponent } from "../Controls/CollapsiblePanel/CollapsibleSectionComponent";
|
||||||
import { ThroughputInput } from "../Controls/ThroughputInput/ThroughputInput";
|
import { ThroughputInput } from "../Controls/ThroughputInput/ThroughputInput";
|
||||||
|
@ -81,6 +82,26 @@ export const AllPropertiesIndexed: DataModels.IndexingPolicy = {
|
||||||
excludedPaths: [],
|
excludedPaths: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DefaultDatabaseVectorIndex: DataModels.IndexingPolicy = {
|
||||||
|
indexingMode: "consistent",
|
||||||
|
automatic: true,
|
||||||
|
includedPaths: [
|
||||||
|
{
|
||||||
|
path: "/*",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
excludedPaths: [
|
||||||
|
{
|
||||||
|
path: '/"_etag"/?',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
vectorIndexes: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DefaultVectorEmbeddingPolicy: DataModels.VectorEmbeddingPolicy = {
|
||||||
|
vectorEmbeddings: [],
|
||||||
|
};
|
||||||
|
|
||||||
export interface AddCollectionPanelState {
|
export interface AddCollectionPanelState {
|
||||||
createNewDatabase: boolean;
|
createNewDatabase: boolean;
|
||||||
newDatabaseId: string;
|
newDatabaseId: string;
|
||||||
|
@ -101,6 +122,8 @@ export interface AddCollectionPanelState {
|
||||||
isExecuting: boolean;
|
isExecuting: boolean;
|
||||||
isThroughputCapExceeded: boolean;
|
isThroughputCapExceeded: boolean;
|
||||||
teachingBubbleStep: number;
|
teachingBubbleStep: number;
|
||||||
|
vectorIndexingPolicy: string;
|
||||||
|
vectorEmbeddingPolicy: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AddCollectionPanel extends React.Component<AddCollectionPanelProps, AddCollectionPanelState> {
|
export class AddCollectionPanel extends React.Component<AddCollectionPanelProps, AddCollectionPanelState> {
|
||||||
|
@ -136,6 +159,8 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||||
isExecuting: false,
|
isExecuting: false,
|
||||||
isThroughputCapExceeded: false,
|
isThroughputCapExceeded: false,
|
||||||
teachingBubbleStep: 0,
|
teachingBubbleStep: 0,
|
||||||
|
vectorIndexingPolicy: JSON.stringify(DefaultDatabaseVectorIndex, null, 2),
|
||||||
|
vectorEmbeddingPolicy: JSON.stringify(DefaultVectorEmbeddingPolicy, null, 2),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,11 +170,17 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(_prevProps: AddCollectionPanelProps, prevState: AddCollectionPanelState): void {
|
||||||
|
if (this.state.errorMessage && this.state.errorMessage !== prevState.errorMessage) {
|
||||||
|
this.scrollToSection("panelContainer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
const isFirstResourceCreated = useDatabases.getState().isFirstResourceCreated();
|
const isFirstResourceCreated = useDatabases.getState().isFirstResourceCreated();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="panelFormWrapper" onSubmit={this.submit.bind(this)}>
|
<form className="panelFormWrapper" onSubmit={this.submit.bind(this)} id="panelContainer">
|
||||||
{this.state.errorMessage && (
|
{this.state.errorMessage && (
|
||||||
<PanelInfoErrorComponent
|
<PanelInfoErrorComponent
|
||||||
message={this.state.errorMessage}
|
message={this.state.errorMessage}
|
||||||
|
@ -864,17 +895,76 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
|
{this.shouldShowVectorSearchParameters() && (
|
||||||
|
<Stack>
|
||||||
|
<CollapsibleSectionComponent
|
||||||
|
title="Indexing Policy"
|
||||||
|
isExpandedByDefault={false}
|
||||||
|
onExpand={() => {
|
||||||
|
this.scrollToSection("collapsibleVectorPolicySectionContent");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Stack id="collapsibleVectorPolicySectionContent" styles={{ root: { position: "relative" } }}>
|
||||||
|
<Link href="https://aka.ms/CosmosDBVectorSetup" target="_blank">
|
||||||
|
Learn more
|
||||||
|
</Link>
|
||||||
|
<EditorReact
|
||||||
|
language={"json"}
|
||||||
|
content={this.state.vectorIndexingPolicy}
|
||||||
|
isReadOnly={false}
|
||||||
|
wordWrap={"on"}
|
||||||
|
ariaLabel={"Editing indexing policy"}
|
||||||
|
lineNumbers={"on"}
|
||||||
|
scrollBeyondLastLine={false}
|
||||||
|
spinnerClassName="panelSectionSpinner"
|
||||||
|
monacoContainerStyles={{
|
||||||
|
minHeight: 200,
|
||||||
|
}}
|
||||||
|
onContentChanged={(newIndexingPolicy: string) => this.setVectorIndexingPolicy(newIndexingPolicy)}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</CollapsibleSectionComponent>
|
||||||
|
<CollapsibleSectionComponent
|
||||||
|
title="Container Vector Policy"
|
||||||
|
isExpandedByDefault={false}
|
||||||
|
onExpand={() => {
|
||||||
|
this.scrollToSection("collapsibleVectorPolicySectionContent");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Stack id="collapsibleVectorPolicySectionContent" styles={{ root: { position: "relative" } }}>
|
||||||
|
<Link href="https://aka.ms/CosmosDBVectorSetup" target="_blank">
|
||||||
|
Learn more
|
||||||
|
</Link>
|
||||||
|
<EditorReact
|
||||||
|
language={"json"}
|
||||||
|
content={this.state.vectorEmbeddingPolicy}
|
||||||
|
isReadOnly={false}
|
||||||
|
wordWrap={"on"}
|
||||||
|
ariaLabel={"Editing container vector policy"}
|
||||||
|
lineNumbers={"on"}
|
||||||
|
scrollBeyondLastLine={false}
|
||||||
|
spinnerClassName="panelSectionSpinner"
|
||||||
|
monacoContainerStyles={{
|
||||||
|
minHeight: 200,
|
||||||
|
}}
|
||||||
|
onContentChanged={(newVectorEmbeddingPolicy: string) =>
|
||||||
|
this.setVectorEmbeddingPolicy(newVectorEmbeddingPolicy)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</CollapsibleSectionComponent>
|
||||||
|
</Stack>
|
||||||
|
)}
|
||||||
{userContext.apiType !== "Tables" && (
|
{userContext.apiType !== "Tables" && (
|
||||||
<CollapsibleSectionComponent
|
<CollapsibleSectionComponent
|
||||||
title="Advanced"
|
title="Advanced"
|
||||||
isExpandedByDefault={false}
|
isExpandedByDefault={false}
|
||||||
onExpand={() => {
|
onExpand={() => {
|
||||||
TelemetryProcessor.traceOpen(Action.ExpandAddCollectionPaneAdvancedSection);
|
TelemetryProcessor.traceOpen(Action.ExpandAddCollectionPaneAdvancedSection);
|
||||||
this.scrollToAdvancedSection();
|
this.scrollToSection("collapsibleAdvancedSectionContent");
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stack className="panelGroupSpacing" id="collapsibleSectionContent">
|
<Stack className="panelGroupSpacing" id="collapsibleAdvancedSectionContent">
|
||||||
{isCapabilityEnabled("EnableMongo") && !isCapabilityEnabled("EnableMongo16MBDocumentSupport") && (
|
{isCapabilityEnabled("EnableMongo") && !isCapabilityEnabled("EnableMongo16MBDocumentSupport") && (
|
||||||
<Stack className="panelGroupSpacing">
|
<Stack className="panelGroupSpacing">
|
||||||
<Stack horizontal>
|
<Stack horizontal>
|
||||||
|
@ -1070,6 +1160,18 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setVectorEmbeddingPolicy(vectorEmbeddingPolicy: string): void {
|
||||||
|
this.setState({
|
||||||
|
vectorEmbeddingPolicy,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private setVectorIndexingPolicy(vectorIndexingPolicy: string): void {
|
||||||
|
this.setState({
|
||||||
|
vectorIndexingPolicy,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private isSelectedDatabaseSharedThroughput(): boolean {
|
private isSelectedDatabaseSharedThroughput(): boolean {
|
||||||
if (!this.state.selectedDatabaseId) {
|
if (!this.state.selectedDatabaseId) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1209,6 +1311,10 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private shouldShowVectorSearchParameters() {
|
||||||
|
return isVectorSearchEnabled() && this.shouldShowCollectionThroughputInput();
|
||||||
|
}
|
||||||
|
|
||||||
private parseUniqueKeys(): DataModels.UniqueKeyPolicy {
|
private parseUniqueKeys(): DataModels.UniqueKeyPolicy {
|
||||||
if (this.state.uniqueKeys?.length === 0) {
|
if (this.state.uniqueKeys?.length === 0) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -1265,6 +1371,22 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.shouldShowVectorSearchParameters()) {
|
||||||
|
try {
|
||||||
|
JSON.parse(this.state.vectorIndexingPolicy) as DataModels.IndexingPolicy;
|
||||||
|
} catch (e) {
|
||||||
|
this.setState({ errorMessage: "Invalid JSON format for indexingPolicy" });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSON.parse(this.state.vectorEmbeddingPolicy) as DataModels.VectorEmbeddingPolicy;
|
||||||
|
} catch (e) {
|
||||||
|
this.setState({ errorMessage: "Invalid JSON format for vectorEmbeddingPolicy" });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1287,8 +1409,8 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||||
return Constants.AnalyticalStorageTtl.Disabled;
|
return Constants.AnalyticalStorageTtl.Disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
private scrollToAdvancedSection(): void {
|
private scrollToSection(id: string): void {
|
||||||
document.getElementById("collapsibleSectionContent")?.scrollIntoView();
|
document.getElementById(id)?.scrollIntoView();
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSampleDBName(): string {
|
private getSampleDBName(): string {
|
||||||
|
@ -1340,10 +1462,17 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||||
}
|
}
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const indexingPolicy: DataModels.IndexingPolicy = this.state.enableIndexing
|
let indexingPolicy: DataModels.IndexingPolicy = this.state.enableIndexing
|
||||||
? AllPropertiesIndexed
|
? AllPropertiesIndexed
|
||||||
: SharedDatabaseDefault;
|
: SharedDatabaseDefault;
|
||||||
|
|
||||||
|
let vectorEmbeddingPolicy: DataModels.VectorEmbeddingPolicy;
|
||||||
|
|
||||||
|
if (this.shouldShowVectorSearchParameters()) {
|
||||||
|
indexingPolicy = JSON.parse(this.state.vectorIndexingPolicy);
|
||||||
|
vectorEmbeddingPolicy = JSON.parse(this.state.vectorEmbeddingPolicy);
|
||||||
|
}
|
||||||
|
|
||||||
const telemetryData = {
|
const telemetryData = {
|
||||||
database: {
|
database: {
|
||||||
id: databaseId,
|
id: databaseId,
|
||||||
|
@ -1402,6 +1531,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
|
||||||
partitionKey,
|
partitionKey,
|
||||||
uniqueKeyPolicy,
|
uniqueKeyPolicy,
|
||||||
createMongoWildcardIndex: this.state.createMongoWildCardIndex,
|
createMongoWildcardIndex: this.state.createMongoWildCardIndex,
|
||||||
|
vectorEmbeddingPolicy,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setState({ isExecuting: true });
|
this.setState({ isExecuting: true });
|
||||||
|
|
|
@ -48,6 +48,13 @@
|
||||||
font-size: @mediumFontSize;
|
font-size: @mediumFontSize;
|
||||||
padding: 0 @LargeSpace 0 @SmallSpace;
|
padding: 0 @LargeSpace 0 @SmallSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.panelSectionSpinner {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
exports[`AddCollectionPanel should render Default properly 1`] = `
|
exports[`AddCollectionPanel should render Default properly 1`] = `
|
||||||
<form
|
<form
|
||||||
className="panelFormWrapper"
|
className="panelFormWrapper"
|
||||||
|
id="panelContainer"
|
||||||
onSubmit={[Function]}
|
onSubmit={[Function]}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
@ -433,7 +434,7 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
|
||||||
>
|
>
|
||||||
<Stack
|
<Stack
|
||||||
className="panelGroupSpacing"
|
className="panelGroupSpacing"
|
||||||
id="collapsibleSectionContent"
|
id="collapsibleAdvancedSectionContent"
|
||||||
>
|
>
|
||||||
<Stack
|
<Stack
|
||||||
className="panelGroupSpacing"
|
className="panelGroupSpacing"
|
||||||
|
@ -485,4 +486,4 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
|
||||||
isButtonDisabled={false}
|
isButtonDisabled={false}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -16,3 +16,7 @@ export const isServerlessAccount = (): boolean => {
|
||||||
isCapabilityEnabled(Constants.CapabilityNames.EnableServerless)
|
isCapabilityEnabled(Constants.CapabilityNames.EnableServerless)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isVectorSearchEnabled = (): boolean => {
|
||||||
|
return userContext.apiType === "SQL" && isCapabilityEnabled(Constants.CapabilityNames.EnableNoSQLVectorSearch);
|
||||||
|
};
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
import { configContext } from "../../../../ConfigContext";
|
import { configContext } from "../../../../ConfigContext";
|
||||||
import { armRequest } from "../../request";
|
import { armRequest } from "../../request";
|
||||||
import * as Types from "./types";
|
import * as Types from "./types";
|
||||||
const apiVersion = "2024-02-15-preview";
|
const apiVersion = "2024-05-15-preview";
|
||||||
|
|
||||||
/* Lists the SQL databases under an existing Azure Cosmos DB database account. */
|
/* Lists the SQL databases under an existing Azure Cosmos DB database account. */
|
||||||
export async function listSqlDatabases(
|
export async function listSqlDatabases(
|
||||||
|
|
|
@ -1235,6 +1235,9 @@ export interface SqlDatabaseResource {
|
||||||
export interface SqlContainerResource {
|
export interface SqlContainerResource {
|
||||||
/* Name of the Cosmos DB SQL container */
|
/* Name of the Cosmos DB SQL container */
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
|
vectorEmbeddingPolicy?: VectorEmbeddingPolicy;
|
||||||
|
|
||||||
/* The configuration of the indexing policy. By default, the indexing is automatic for all document paths within the container */
|
/* The configuration of the indexing policy. By default, the indexing is automatic for all document paths within the container */
|
||||||
indexingPolicy?: IndexingPolicy;
|
indexingPolicy?: IndexingPolicy;
|
||||||
|
|
||||||
|
@ -1267,6 +1270,17 @@ export interface SqlContainerResource {
|
||||||
computedProperties?: ComputedProperty[];
|
computedProperties?: ComputedProperty[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface VectorEmbeddingPolicy {
|
||||||
|
vectorEmbeddings: VectorEmbedding[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VectorEmbedding {
|
||||||
|
path?: string;
|
||||||
|
dataType?: string;
|
||||||
|
dimensions?: number;
|
||||||
|
distanceFunction?: string;
|
||||||
|
}
|
||||||
|
|
||||||
/* Cosmos DB indexing policy */
|
/* Cosmos DB indexing policy */
|
||||||
export interface IndexingPolicy {
|
export interface IndexingPolicy {
|
||||||
/* Indicates if the indexing policy is automatic */
|
/* Indicates if the indexing policy is automatic */
|
||||||
|
@ -1285,6 +1299,13 @@ export interface IndexingPolicy {
|
||||||
|
|
||||||
/* List of spatial specifics */
|
/* List of spatial specifics */
|
||||||
spatialIndexes?: SpatialSpec[];
|
spatialIndexes?: SpatialSpec[];
|
||||||
|
|
||||||
|
vectorIndexes?: VectorIndex[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface VectorIndex {
|
||||||
|
path?: string;
|
||||||
|
type?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* undocumented */
|
/* undocumented */
|
||||||
|
|
Loading…
Reference in New Issue