Enable Full Text Search on all NoSQL accounts (#2157)

* Enable Full Text Search on all NoSQL accounts

* format

* fix tests

* run tests

---------

Co-authored-by: Asier Isayas <aisayas@microsoft.com>
This commit is contained in:
asier-isayas 2025-05-20 10:49:09 -04:00 committed by GitHub
parent 45513e5e1b
commit f14b574527
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 89 additions and 26 deletions

View File

@ -13,7 +13,7 @@ import {
} from "Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputBucketsComponent"; } from "Explorer/Controls/Settings/SettingsSubComponents/ThroughputInputComponents/ThroughputBucketsComponent";
import { useDatabases } from "Explorer/useDatabases"; import { useDatabases } from "Explorer/useDatabases";
import { isFabricNative } from "Platform/Fabric/FabricUtil"; import { isFabricNative } from "Platform/Fabric/FabricUtil";
import { isFullTextSearchEnabled, isVectorSearchEnabled } from "Utils/CapabilityUtils"; 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";
@ -188,7 +188,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
this.isGlobalSecondaryIndex = this.isGlobalSecondaryIndex =
!!this.collection?.materializedViewDefinition() || !!this.collection?.materializedViews(); !!this.collection?.materializedViewDefinition() || !!this.collection?.materializedViews();
this.isVectorSearchEnabled = isVectorSearchEnabled() && !hasDatabaseSharedThroughput(this.collection); this.isVectorSearchEnabled = isVectorSearchEnabled() && !hasDatabaseSharedThroughput(this.collection);
this.isFullTextSearchEnabled = isFullTextSearchEnabled() && !hasDatabaseSharedThroughput(this.collection); this.isFullTextSearchEnabled = userContext.apiType === "SQL";
this.changeFeedPolicyVisible = userContext.features.enableChangeFeedPolicy; this.changeFeedPolicyVisible = userContext.features.enableChangeFeedPolicy;
this.throughputBucketsEnabled = userContext.throughputBucketsEnabled; this.throughputBucketsEnabled = userContext.throughputBucketsEnabled;

View File

@ -198,6 +198,32 @@ exports[`SettingsComponent renders 1`] = `
timeToLiveSecondsBaseline={5} timeToLiveSecondsBaseline={5}
/> />
</PivotItem> </PivotItem>
<PivotItem
headerText="Container Policies"
itemKey="ContainerVectorPolicyTab"
key="ContainerVectorPolicyTab"
style={
{
"marginTop": 20,
}
}
>
<ContainerPolicyComponent
fullTextPolicy={{}}
fullTextPolicyBaseline={{}}
isFullTextSearchEnabled={true}
isGlobalSecondaryIndex={true}
isVectorSearchEnabled={false}
onFullTextPolicyChange={[Function]}
onFullTextPolicyDirtyChange={[Function]}
onVectorEmbeddingPolicyChange={[Function]}
onVectorEmbeddingPolicyDirtyChange={[Function]}
resetShouldDiscardContainerPolicyChange={[Function]}
shouldDiscardContainerPolicies={false}
vectorEmbeddingPolicy={{}}
vectorEmbeddingPolicyBaseline={{}}
/>
</PivotItem>
<PivotItem <PivotItem
headerText="Indexing Policy" headerText="Indexing Policy"
itemKey="IndexingPolicyTab" itemKey="IndexingPolicyTab"

View File

@ -49,12 +49,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 { import { isCapabilityEnabled, isServerlessAccount, isVectorSearchEnabled } from "Utils/CapabilityUtils";
isCapabilityEnabled,
isFullTextSearchEnabled,
isServerlessAccount,
isVectorSearchEnabled,
} from "Utils/CapabilityUtils";
import { getUpsellMessage } from "Utils/PricingUtils"; import { getUpsellMessage } from "Utils/PricingUtils";
import { ValidCosmosDbIdDescription, ValidCosmosDbIdInputPattern } from "Utils/ValidationUtils"; import { ValidCosmosDbIdDescription, ValidCosmosDbIdInputPattern } from "Utils/ValidationUtils";
import { CollapsibleSectionComponent } from "../../Controls/CollapsiblePanel/CollapsibleSectionComponent"; import { CollapsibleSectionComponent } from "../../Controls/CollapsiblePanel/CollapsibleSectionComponent";
@ -110,6 +105,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
private collectionThroughput: number; private collectionThroughput: number;
private isCollectionAutoscale: boolean; private isCollectionAutoscale: boolean;
private isCostAcknowledged: boolean; private isCostAcknowledged: boolean;
private showFullTextSearch: boolean;
constructor(props: AddCollectionPanelProps) { constructor(props: AddCollectionPanelProps) {
super(props); super(props);
@ -144,6 +140,8 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
fullTextIndexes: [], fullTextIndexes: [],
fullTextPolicyValidated: true, fullTextPolicyValidated: true,
}; };
this.showFullTextSearch = userContext.apiType === "SQL";
} }
componentDidMount(): void { componentDidMount(): void {
@ -869,7 +867,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
</CollapsibleSectionComponent> </CollapsibleSectionComponent>
</Stack> </Stack>
)} )}
{this.shouldShowFullTextSearchParameters() && ( {this.showFullTextSearch && (
<Stack> <Stack>
<CollapsibleSectionComponent <CollapsibleSectionComponent
title="Container Full Text Search Policy" title="Container Full Text Search Policy"
@ -1160,10 +1158,6 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
return isVectorSearchEnabled() && (isServerlessAccount() || this.shouldShowCollectionThroughputInput()); return isVectorSearchEnabled() && (isServerlessAccount() || this.shouldShowCollectionThroughputInput());
} }
private shouldShowFullTextSearchParameters() {
return isFullTextSearchEnabled() && (isServerlessAccount() || 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;
@ -1316,7 +1310,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
}; };
} }
if (this.shouldShowFullTextSearchParameters()) { if (this.showFullTextSearch) {
indexingPolicy.fullTextIndexes = this.state.fullTextIndexes; indexingPolicy.fullTextIndexes = this.state.fullTextIndexes;
} }

View File

@ -411,6 +411,44 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
/> />
</Stack> </Stack>
</Stack> </Stack>
<Stack>
<CollapsibleSectionComponent
isExpandedByDefault={false}
onExpand={[Function]}
title="Container Full Text Search Policy"
>
<Stack
id="collapsibleFullTextPolicySectionContent"
styles={
{
"root": {
"position": "relative",
},
}
}
>
<Stack
styles={
{
"root": {
"paddingLeft": 40,
},
}
}
>
<FullTextPoliciesComponent
fullTextPolicy={
{
"defaultLanguage": "en-US",
"fullTextPaths": [],
}
}
onFullTextPathChange={[Function]}
/>
</Stack>
</Stack>
</CollapsibleSectionComponent>
</Stack>
<CollapsibleSectionComponent <CollapsibleSectionComponent
isExpandedByDefault={false} isExpandedByDefault={false}
onExpand={[Function]} onExpand={[Function]}

View File

@ -40,12 +40,12 @@ import { PanelInfoErrorComponent } from "Explorer/Panes/PanelInfoErrorComponent"
import { PanelLoadingScreen } from "Explorer/Panes/PanelLoadingScreen"; import { PanelLoadingScreen } from "Explorer/Panes/PanelLoadingScreen";
import { useDatabases } from "Explorer/useDatabases"; import { useDatabases } from "Explorer/useDatabases";
import { useSidePanel } from "hooks/useSidePanel"; import { useSidePanel } from "hooks/useSidePanel";
import React, { useEffect, useState } from "react"; import React, { MutableRefObject, useEffect, useRef, useState } from "react";
import { CollectionCreation } from "Shared/Constants"; import { CollectionCreation } from "Shared/Constants";
import { Action } from "Shared/Telemetry/TelemetryConstants"; 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 { isFullTextSearchEnabled, isServerlessAccount, isVectorSearchEnabled } from "Utils/CapabilityUtils"; import { isServerlessAccount, isVectorSearchEnabled } from "Utils/CapabilityUtils";
import { ValidCosmosDbIdDescription, ValidCosmosDbIdInputPattern } from "Utils/ValidationUtils"; import { ValidCosmosDbIdDescription, ValidCosmosDbIdInputPattern } from "Utils/ValidationUtils";
export interface AddGlobalSecondaryIndexPanelProps { export interface AddGlobalSecondaryIndexPanelProps {
@ -75,6 +75,8 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
const [showErrorDetails, setShowErrorDetails] = useState<boolean>(); const [showErrorDetails, setShowErrorDetails] = useState<boolean>();
const [isExecuting, setIsExecuting] = useState<boolean>(); const [isExecuting, setIsExecuting] = useState<boolean>();
const showFullTextSearch: MutableRefObject<boolean> = useRef<boolean>(userContext.apiType === "SQL");
useEffect(() => { useEffect(() => {
const sourceContainerOptions: IDropdownOption[] = []; const sourceContainerOptions: IDropdownOption[] = [];
useDatabases.getState().databases.forEach((database: Database) => { useDatabases.getState().databases.forEach((database: Database) => {
@ -140,10 +142,6 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
return isVectorSearchEnabled() && (isServerlessAccount() || showCollectionThroughputInput()); return isVectorSearchEnabled() && (isServerlessAccount() || showCollectionThroughputInput());
}; };
const showFullTextSearchParameters = (): boolean => {
return isFullTextSearchEnabled() && (isServerlessAccount() || showCollectionThroughputInput());
};
const getAnalyticalStorageTtl = (): number => { const getAnalyticalStorageTtl = (): number => {
if (!isSynapseLinkEnabled()) { if (!isSynapseLinkEnabled()) {
return undefined; return undefined;
@ -228,7 +226,7 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
}; };
} }
if (showFullTextSearchParameters()) { if (showFullTextSearch) {
indexingPolicy.fullTextIndexes = fullTextIndexes; indexingPolicy.fullTextIndexes = fullTextIndexes;
} }
@ -387,7 +385,7 @@ export const AddGlobalSecondaryIndexPanel = (props: AddGlobalSecondaryIndexPanel
}} }}
/> />
)} )}
{showFullTextSearchParameters() && ( {showFullTextSearch && (
<FullTextSearchComponent <FullTextSearchComponent
{...{ fullTextPolicy, setFullTextPolicy, setFullTextIndexes, setFullTextPolicyValidated }} {...{ fullTextPolicy, setFullTextPolicy, setFullTextIndexes, setFullTextPolicyValidated }}
/> />

View File

@ -172,6 +172,17 @@ exports[`AddGlobalSecondaryIndexPanel render default panel 1`] = `
} }
setEnableAnalyticalStore={[Function]} setEnableAnalyticalStore={[Function]}
/> />
<FullTextSearchComponent
fullTextPolicy={
{
"defaultLanguage": "en-US",
"fullTextPaths": [],
}
}
setFullTextIndexes={[Function]}
setFullTextPolicy={[Function]}
setFullTextPolicyValidated={[Function]}
/>
<AdvancedComponent <AdvancedComponent
setSubPartitionKeys={[Function]} setSubPartitionKeys={[Function]}
setUseHashV1={[Function]} setUseHashV1={[Function]}

View File

@ -20,7 +20,3 @@ export const isServerlessAccount = (): boolean => {
export const isVectorSearchEnabled = (): boolean => { export const isVectorSearchEnabled = (): boolean => {
return userContext.apiType === "SQL" && isCapabilityEnabled(Constants.CapabilityNames.EnableNoSQLVectorSearch); return userContext.apiType === "SQL" && isCapabilityEnabled(Constants.CapabilityNames.EnableNoSQLVectorSearch);
}; };
export const isFullTextSearchEnabled = (): boolean => {
return userContext.apiType === "SQL" && isCapabilityEnabled(Constants.CapabilityNames.EnableNoSQLFullTextSearch);
};