Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full text Search functionality #31683

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion sdk/cosmosdb/cosmos/review/cosmos.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,7 @@ export interface ContainerDefinition {
computedProperties?: ComputedProperty[];
conflictResolutionPolicy?: ConflictResolutionPolicy;
defaultTtl?: number;
fullTextPolicy?: FullTextPolicy;
geospatialConfig?: {
type: GeospatialType;
};
Expand Down Expand Up @@ -1095,6 +1096,23 @@ export class FeedResponse<TResource> {
readonly resources: TResource[];
}

// @public
export interface FullTextIndex {
path: string;
}

// @public
export interface FullTextPath {
language: string;
path: string;
}

// @public
export interface FullTextPolicy {
defaultLanguage: string;
fullTextPaths: FullTextPath[];
}

// @public (undocumented)
export type GatewayStatistics = {
activityId?: string;
Expand Down Expand Up @@ -1161,6 +1179,15 @@ export enum HTTPMethod {
put = "PUT"
}

// @public
export interface HybridSearchQueryInfo {
componentQueryInfos: QueryInfo[];
globalStatisticsQuery: string;
requiresGlobalStatistics: boolean;
skip: number;
take: number;
}

// @public (undocumented)
export interface Index {
// (undocumented)
Expand Down Expand Up @@ -1192,6 +1219,7 @@ export interface IndexingPolicy {
automatic?: boolean;
compositeIndexes?: CompositePath[][];
excludedPaths?: IndexedPath[];
fullTextIndexes?: FullTextIndex[];
includedPaths?: IndexedPath[];
indexingMode?: keyof typeof IndexingMode;
// (undocumented)
Expand Down Expand Up @@ -1452,10 +1480,11 @@ export type OperationWithItem = OperationBase & {

// @public (undocumented)
export interface PartitionedQueryExecutionInfo {
hybridSearchQueryInfo?: HybridSearchQueryInfo;
// (undocumented)
partitionedQueryExecutionInfoVersion: number;
// (undocumented)
queryInfo: QueryInfo;
queryInfo?: QueryInfo;
// (undocumented)
queryRanges: QueryRange[];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { GeospatialType } from "../../documents/GeospatialType";
import { ChangeFeedPolicy } from "../ChangeFeed/ChangeFeedPolicy";
import { ComputedProperty } from "../../documents/ComputedProperty";
import { VectorEmbeddingPolicy } from "../../documents/VectorEmbeddingPolicy";
import { FullTextPolicy } from "../../documents/FullTextPolicy";

export interface ContainerDefinition {
/** The id of the container. */
Expand All @@ -31,4 +32,6 @@ export interface ContainerDefinition {
computedProperties?: ComputedProperty[];
/** The vector embedding policy information for storing items in a container. */
vectorEmbeddingPolicy?: VectorEmbeddingPolicy;
/** The full text policy information for storing items in a container. */
fullTextPolicy?: FullTextPolicy;
}
2 changes: 2 additions & 0 deletions sdk/cosmosdb/cosmos/src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -491,4 +491,6 @@ export enum QueryFeature {
MultipleAggregates = "MultipleAggregates",
NonStreamingOrderBy = "NonStreamingOrderBy",
ListAndSetAggregate = "ListAndSetAggregate",
CountIf = "CountIf",
HybridSearch = "HybridSearch",
}
30 changes: 30 additions & 0 deletions sdk/cosmosdb/cosmos/src/documents/FullTextPolicy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

/**
* Represents a full text policy for a collection in the Azure Cosmos DB service.
*/
export interface FullTextPolicy {
/**
* The default language for the full text .
*/
defaultLanguage: string;
/**
* The paths to be indexed for full text search.
*/
fullTextPaths: FullTextPath[];
}

/**
* Represents a full text path to be indexed in the Azure Cosmos DB service.
*/
export interface FullTextPath {
/**
* The path to be indexed for full text search.
*/
path: string;
/**
* The language for the full text path.
*/
language: string;
}
10 changes: 10 additions & 0 deletions sdk/cosmosdb/cosmos/src/documents/IndexingPolicy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export interface IndexingPolicy {
vectorIndexes?: VectorIndex[];
/** An array of {@link CompositeIndexes} representing composite indexes to be included. */
compositeIndexes?: CompositePath[][];
/** An array of {@link FullTextIndex} representing full text indexes to be included. */
fullTextIndexes?: FullTextIndex[];
}

/* The target data type of a spatial path */
Expand Down Expand Up @@ -96,3 +98,11 @@ export interface CompositePath {
/** The order of the composite index, either "ascending" or "descending". */
order: "ascending" | "descending";
}

/**
* Represents a full text index in the indexing policy.
*/
export interface FullTextIndex {
/** The path in the JSON document to index. */
path: string;
}
1 change: 1 addition & 0 deletions sdk/cosmosdb/cosmos/src/documents/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ export * from "./UserDefinedFunctionType";
export * from "./GeospatialType";
export * from "./ComputedProperty";
export * from "./VectorEmbeddingPolicy";
export * from "./FullTextPolicy";
3 changes: 3 additions & 0 deletions sdk/cosmosdb/cosmos/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ export {
VectorEmbeddingDataType,
VectorEmbeddingDistanceFunction,
VectorIndexType,
FullTextIndex,
FullTextPolicy,
FullTextPath,
} from "./documents";

export { UniqueKeyPolicy, UniqueKey } from "./client/Container/UniqueKeyPolicy";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { GlobalStatistics } from "../../request/globalStatistics";
import { Aggregator } from "./Aggregator";

export class GlobalStatisticsAggregator implements Aggregator {
private globalStatistics: GlobalStatistics;

constructor() {
this.globalStatistics = {
documentCount: 0,
fullTextStatistics: [],
};
}

public aggregate(other: GlobalStatistics): void {
if (!other) {
return;
}
// Aggregate document count
this.globalStatistics.documentCount += other.documentCount;
// Ensure `fullTextStatistics` is initialized
if (!other.fullTextStatistics || other.fullTextStatistics.length === 0) {
return;
}

// Initialize `this.globalStatistics.fullTextStatistics` if it's empty
if (this.globalStatistics.fullTextStatistics.length === 0) {
this.globalStatistics.fullTextStatistics = other.fullTextStatistics.map((stat) => ({
totalWordCount: stat.totalWordCount,
hitCounts: [...stat.hitCounts],
}));
} else {
// Loop through `other.fullTextStatistics` to add values to `this.globalStatistics.fullTextStatistics`
for (let i = 0; i < other.fullTextStatistics.length; i++) {
const otherStat = other.fullTextStatistics[i];

// Ensure the index `i` is initialized
if (!this.globalStatistics.fullTextStatistics[i]) {
this.globalStatistics.fullTextStatistics[i] = {
totalWordCount: 0,
hitCounts: [],
};
}

// Add totalWordCount
this.globalStatistics.fullTextStatistics[i].totalWordCount += otherStat.totalWordCount;

// Aggregate `hitCounts`
for (let j = 0; j < otherStat.hitCounts.length; j++) {
// Initialize hit count if necessary
if (this.globalStatistics.fullTextStatistics[i].hitCounts.length <= j) {
this.globalStatistics.fullTextStatistics[i].hitCounts.push(0);
}
this.globalStatistics.fullTextStatistics[i].hitCounts[j] += otherStat.hitCounts[j];
}
}
}
}

public getResult(): GlobalStatistics {
return this.globalStatistics;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export class NonStreamingOrderByDistinctEndpointComponent implements ExecutionCo
private executionContext: ExecutionContext,
private queryInfo: QueryInfo,
private priorityQueueBufferSize: number,
private emitRawOrderByPayload: boolean = false,
) {
this.sortOrders = this.queryInfo.orderBy;
const comparator = new OrderByComparator(this.sortOrders);
Expand Down Expand Up @@ -128,7 +129,11 @@ export class NonStreamingOrderByDistinctEndpointComponent implements ExecutionCo
this.finalResultArray = new Array(finalArraySize);
// Only keep the final result array size number of items in the final result array and discard the rest.
for (let count = finalArraySize - 1; count >= 0; count--) {
this.finalResultArray[count] = this.nonStreamingOrderByPQ.dequeue()?.payload;
if (this.emitRawOrderByPayload) {
this.finalResultArray[count] = this.nonStreamingOrderByPQ.dequeue();
} else {
this.finalResultArray[count] = this.nonStreamingOrderByPQ.dequeue()?.payload;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class NonStreamingOrderByEndpointComponent implements ExecutionContext {
private sortOrders: any[],
private priorityQueueBufferSize: number,
private offset: number = 0,
private emitRawOrderByPayload: boolean = false,
) {
const comparator = new OrderByComparator(this.sortOrders);
this.nonStreamingOrderByPQ = new FixedSizePriorityQueue<NonStreamingOrderByResult>(
Expand Down Expand Up @@ -88,7 +89,12 @@ export class NonStreamingOrderByEndpointComponent implements ExecutionContext {
}
// If pq is not empty, return the result from pq.
if (!this.nonStreamingOrderByPQ.isEmpty()) {
const item = this.nonStreamingOrderByPQ.dequeue()?.payload;
let item;
if (this.emitRawOrderByPayload) {
item = this.nonStreamingOrderByPQ.dequeue();
} else {
item = this.nonStreamingOrderByPQ.dequeue()?.payload;
}
return {
result: item,
headers: resHeaders,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,26 @@ export class OrderByEndpointComponent implements ExecutionContext {
* @param executionContext - Underlying Execution Context
* @hidden
*/
constructor(private executionContext: ExecutionContext) {}
constructor(
private executionContext: ExecutionContext,
private emitRawOrderByPayload: boolean = false,
) {}
/**
* Execute a provided function on the next element in the OrderByEndpointComponent.
*/
public async nextItem(diagnosticNode: DiagnosticNodeInternal): Promise<Response<any>> {
const { result: item, headers } = await this.executionContext.nextItem(diagnosticNode);
return {
result: item !== undefined ? item.payload : undefined,
headers,
};
if (this.emitRawOrderByPayload) {
return {
result: item !== undefined ? item : undefined,
headers,
};
} else {
return {
result: item !== undefined ? item.payload : undefined,
headers,
};
}
}

/**
Expand Down
Loading