Skip to content

refactor(NODE-7083): index operations to modernized operation #4611

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

Merged
merged 6 commits into from
Aug 7, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
43 changes: 17 additions & 26 deletions src/operations/indexes.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import type { Document } from '../bson';
import { type Connection } from '../cmap/connection';
import { CursorResponse } from '../cmap/wire_protocol/responses';
import { CursorResponse, MongoDBResponse } from '../cmap/wire_protocol/responses';
import type { Collection } from '../collection';
import { type AbstractCursorOptions } from '../cursor/abstract_cursor';
import { MongoCompatibilityError } from '../error';
import { type OneOrMore } from '../mongo_types';
import type { Server } from '../sdam/server';
import type { ClientSession } from '../sessions';
import { type TimeoutContext } from '../timeout';
import { isObject, maxWireVersion, type MongoDBNamespace } from '../utils';
import {
type CollationOptions,
CommandOperation,
type CommandOperationOptions,
ModernizedCommandOperation,
type OperationParent
Expand Down Expand Up @@ -246,7 +242,8 @@ type ResolvedIndexDescription = Omit<IndexDescription, 'key' | 'version'> & {
};

/** @internal */
export class CreateIndexesOperation extends CommandOperation<string[]> {
export class CreateIndexesOperation extends ModernizedCommandOperation<string[]> {
override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
override options: CreateIndexesOptions;
collectionName: string;
indexes: ReadonlyArray<ResolvedIndexDescription>;
Expand All @@ -260,6 +257,8 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
super(parent, options);

this.options = options ?? {};
// collation is set on each index, it should not be defined at the root
this.options.collation = undefined;
this.collectionName = collectionName;
this.indexes = indexes.map((userIndex: IndexDescription): ResolvedIndexDescription => {
// Ensure the key is a Map to preserve index key ordering
Expand All @@ -273,6 +272,7 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
key
};
});
this.ns = parent.s.namespace;
}

static fromIndexDescriptionArray(
Expand All @@ -299,15 +299,11 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
return 'createIndexes';
}

override async execute(
server: Server,
session: ClientSession | undefined,
timeoutContext: TimeoutContext
): Promise<string[]> {
override buildCommandDocument(connection: Connection): Document {
const options = this.options;
const indexes = this.indexes;

const serverWireVersion = maxWireVersion(server);
const serverWireVersion = maxWireVersion(connection);

const cmd: Document = { createIndexes: this.collectionName, indexes };

Expand All @@ -319,13 +315,11 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
}
cmd.commitQuorum = options.commitQuorum;
}
return cmd;
}

// collation is set on each index, it should not be defined at the root
this.options.collation = undefined;

await super.executeCommand(server, session, cmd, timeoutContext);

const indexNames = indexes.map(index => index.name || '');
override handleOk(_response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): string[] {
const indexNames = this.indexes.map(index => index.name || '');
return indexNames;
}
}
Expand All @@ -334,7 +328,8 @@ export class CreateIndexesOperation extends CommandOperation<string[]> {
export type DropIndexesOptions = CommandOperationOptions;

/** @internal */
export class DropIndexOperation extends CommandOperation<Document> {
export class DropIndexOperation extends ModernizedCommandOperation<Document> {
override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
override options: DropIndexesOptions;
collection: Collection;
indexName: string;
Expand All @@ -345,19 +340,15 @@ export class DropIndexOperation extends CommandOperation<Document> {
this.options = options ?? {};
this.collection = collection;
this.indexName = indexName;
this.ns = collection.fullNamespace;
}

override get commandName() {
return 'dropIndexes' as const;
}

override async execute(
server: Server,
session: ClientSession | undefined,
timeoutContext: TimeoutContext
): Promise<Document> {
const cmd = { dropIndexes: this.collection.collectionName, index: this.indexName };
return await super.executeCommand(server, session, cmd, timeoutContext);
override buildCommandDocument(_connection: Connection): Document {
return { dropIndexes: this.collection.collectionName, index: this.indexName };
}
}

Expand Down
32 changes: 16 additions & 16 deletions src/operations/search_indexes/create.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type { Document } from '../../bson';
import { type Document } from '../../bson';
import { type Connection } from '../../cmap/connection';
import { MongoDBResponse } from '../../cmap/wire_protocol/responses';
import type { Collection } from '../../collection';
import type { Server } from '../../sdam/server';
import type { ServerCommandOptions } from '../../sdam/server';
import type { ClientSession } from '../../sessions';
import { type TimeoutContext } from '../../timeout';
import { AbstractOperation } from '../operation';
import { ModernizedOperation } from '../operation';

/**
* @public
Expand All @@ -20,37 +22,35 @@ export interface SearchIndexDescription extends Document {
}

/** @internal */
export class CreateSearchIndexesOperation extends AbstractOperation<string[]> {
export class CreateSearchIndexesOperation extends ModernizedOperation<Document> {
override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
private readonly collection: Collection;
private readonly descriptions: ReadonlyArray<SearchIndexDescription>;

constructor(collection: Collection, descriptions: ReadonlyArray<SearchIndexDescription>) {
super();
this.collection = collection;
this.descriptions = descriptions;
this.ns = collection.fullNamespace;
}

override get commandName() {
return 'createSearchIndexes' as const;
}

override async execute(
server: Server,
session: ClientSession | undefined,
timeoutContext: TimeoutContext
): Promise<string[]> {
override buildCommand(_connection: Connection, _session?: ClientSession): Document {
const namespace = this.collection.fullNamespace;
const command = {
return {
createSearchIndexes: namespace.collection,
indexes: this.descriptions
};
}

const res = await server.command(namespace, command, {
session,
timeoutContext
});
override handleOk(response: InstanceType<typeof this.SERVER_COMMAND_RESPONSE_TYPE>): string[] {
return super.handleOk(response).indexesCreated.map((val: { name: string }) => val.name);
}

const indexesCreated: Array<{ name: string }> = res?.indexesCreated ?? [];
return indexesCreated.map(({ name }) => name);
override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
return { session: this.session, timeoutContext };
}
}
27 changes: 16 additions & 11 deletions src/operations/search_indexes/update.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { Document } from '../../bson';
import { type Connection } from '../../cmap/connection';
import { MongoDBResponse } from '../../cmap/wire_protocol/responses';
import type { Collection } from '../../collection';
import type { Server } from '../../sdam/server';
import type { ServerCommandOptions } from '../../sdam/server';
import type { ClientSession } from '../../sessions';
import { type TimeoutContext } from '../../timeout';
import { AbstractOperation } from '../operation';
import { ModernizedOperation } from '../operation';

/** @internal */
export class UpdateSearchIndexOperation extends AbstractOperation<void> {
export class UpdateSearchIndexOperation extends ModernizedOperation<void> {
override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;
private readonly collection: Collection;
private readonly name: string;
private readonly definition: Document;
Expand All @@ -16,25 +19,27 @@ export class UpdateSearchIndexOperation extends AbstractOperation<void> {
this.collection = collection;
this.name = name;
this.definition = definition;
this.ns = collection.fullNamespace;
}

override get commandName() {
return 'updateSearchIndex' as const;
}

override async execute(
server: Server,
session: ClientSession | undefined,
timeoutContext: TimeoutContext
): Promise<void> {
override buildCommand(_connection: Connection, _session?: ClientSession): Document {
const namespace = this.collection.fullNamespace;
const command = {
return {
updateSearchIndex: namespace.collection,
name: this.name,
definition: this.definition
};
}

override handleOk(_response: MongoDBResponse): void {
// no response.
}

await server.command(namespace, command, { session, timeoutContext });
return;
override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
return { session: this.session, timeoutContext };
}
}