CoolFace
Apppublic

opusdev/vector-similarity-api

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes
db.ts623 linesDownload Raw Back to src
1import { Admin } from './admin';2import { type BSONSerializeOptions, type Document, resolveBSONOptions } from './bson';3import { ChangeStream, type ChangeStreamDocument, type ChangeStreamOptions } from './change_stream';4import { Collection, type CollectionOptions } from './collection';5import * as CONSTANTS from './constants';6import { AggregationCursor } from './cursor/aggregation_cursor';7import { ListCollectionsCursor } from './cursor/list_collections_cursor';8import { RunCommandCursor, type RunCursorCommandOptions } from './cursor/run_command_cursor';9import { MongoInvalidArgumentError } from './error';10import type { MongoClient, PkFactory } from './mongo_client';11import type { Abortable, TODO_NODE_3286 } from './mongo_types';12import type { AggregateOptions } from './operations/aggregate';13import { type CreateCollectionOptions, createCollections } from './operations/create_collection';14import {15  type DropCollectionOptions,16  dropCollections,17  DropDatabaseOperation,18  type DropDatabaseOptions19} from './operations/drop';20import { executeOperation } from './operations/execute_operation';21import {22  CreateIndexesOperation,23  type CreateIndexesOptions,24  type IndexDescriptionCompact,25  type IndexDescriptionInfo,26  type IndexInformationOptions,27  type IndexSpecification28} from './operations/indexes';29import type { CollectionInfo, ListCollectionsOptions } from './operations/list_collections';30import { ProfilingLevelOperation, type ProfilingLevelOptions } from './operations/profiling_level';31import { RemoveUserOperation, type RemoveUserOptions } from './operations/remove_user';32import { RenameOperation, type RenameOptions } from './operations/rename';33import { RunCommandOperation, type RunCommandOptions } from './operations/run_command';34import {35  type ProfilingLevel,36  SetProfilingLevelOperation,37  type SetProfilingLevelOptions38} from './operations/set_profiling_level';39import { DbStatsOperation, type DbStatsOptions } from './operations/stats';40import { ReadConcern } from './read_concern';41import { ReadPreference, type ReadPreferenceLike } from './read_preference';42import { DEFAULT_PK_FACTORY, filterOptions, MongoDBNamespace, resolveOptions } from './utils';43import { WriteConcern, type WriteConcernOptions } from './write_concern';44 45// Allowed parameters46const DB_OPTIONS_ALLOW_LIST = [47  'writeConcern',48  'readPreference',49  'readPreferenceTags',50  'native_parser',51  'forceServerObjectId',52  'pkFactory',53  'serializeFunctions',54  'raw',55  'authSource',56  'ignoreUndefined',57  'readConcern',58  'retryMiliSeconds',59  'numberOfRetries',60  'useBigInt64',61  'promoteBuffers',62  'promoteLongs',63  'bsonRegExp',64  'enableUtf8Validation',65  'promoteValues',66  'compression',67  'retryWrites',68  'timeoutMS'69];70 71/** @internal */72export interface DbPrivate {73  options?: DbOptions;74  readPreference?: ReadPreference;75  pkFactory: PkFactory;76  readConcern?: ReadConcern;77  bsonOptions: BSONSerializeOptions;78  writeConcern?: WriteConcern;79  namespace: MongoDBNamespace;80}81 82/** @public */83export interface DbOptions extends BSONSerializeOptions, WriteConcernOptions {84  /** If the database authentication is dependent on another databaseName. */85  authSource?: string;86  /** Force server to assign _id values instead of driver. */87  forceServerObjectId?: boolean;88  /** The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST). */89  readPreference?: ReadPreferenceLike;90  /** A primary key factory object for generation of custom _id keys. */91  pkFactory?: PkFactory;92  /** Specify a read concern for the collection. (only MongoDB 3.2 or higher supported) */93  readConcern?: ReadConcern;94  /** Should retry failed writes */95  retryWrites?: boolean;96  /**97   * @experimental98   * Specifies the time an operation will run until it throws a timeout error99   */100  timeoutMS?: number;101}102 103/**104 * The **Db** class is a class that represents a MongoDB Database.105 * @public106 *107 * @example108 * ```ts109 * import { MongoClient } from 'mongodb';110 *111 * interface Pet {112 *   name: string;113 *   kind: 'dog' | 'cat' | 'fish';114 * }115 *116 * const client = new MongoClient('mongodb://localhost:27017');117 * const db = client.db();118 *119 * // Create a collection that validates our union120 * await db.createCollection<Pet>('pets', {121 *   validator: { $expr: { $in: ['$kind', ['dog', 'cat', 'fish']] } }122 * })123 * ```124 */125export class Db {126  /** @internal */127  s: DbPrivate;128 129  /**130   * Gets the MongoClient associated with the Db.131   * @public132   */133  readonly client: MongoClient;134 135  public static SYSTEM_NAMESPACE_COLLECTION = CONSTANTS.SYSTEM_NAMESPACE_COLLECTION;136  public static SYSTEM_INDEX_COLLECTION = CONSTANTS.SYSTEM_INDEX_COLLECTION;137  public static SYSTEM_PROFILE_COLLECTION = CONSTANTS.SYSTEM_PROFILE_COLLECTION;138  public static SYSTEM_USER_COLLECTION = CONSTANTS.SYSTEM_USER_COLLECTION;139  public static SYSTEM_COMMAND_COLLECTION = CONSTANTS.SYSTEM_COMMAND_COLLECTION;140  public static SYSTEM_JS_COLLECTION = CONSTANTS.SYSTEM_JS_COLLECTION;141 142  /**143   * Creates a new Db instance.144   *145   * Db name cannot contain a dot, the server may apply more restrictions when an operation is run.146   *147   * @param client - The MongoClient for the database.148   * @param databaseName - The name of the database this instance represents.149   * @param options - Optional settings for Db construction.150   */151  constructor(client: MongoClient, databaseName: string, options?: DbOptions) {152    options = options ?? {};153 154    // Filter the options155    options = filterOptions(options, DB_OPTIONS_ALLOW_LIST);156 157    // Ensure there are no dots in database name158    if (typeof databaseName === 'string' && databaseName.includes('.')) {159      throw new MongoInvalidArgumentError(`Database names cannot contain the character '.'`);160    }161 162    // Internal state of the db object163    this.s = {164      // Options165      options,166      // Unpack read preference167      readPreference: ReadPreference.fromOptions(options),168      // Merge bson options169      bsonOptions: resolveBSONOptions(options, client),170      // Set up the primary key factory or fallback to ObjectId171      pkFactory: options?.pkFactory ?? DEFAULT_PK_FACTORY,172      // ReadConcern173      readConcern: ReadConcern.fromOptions(options),174      writeConcern: WriteConcern.fromOptions(options),175      // Namespace176      namespace: new MongoDBNamespace(databaseName)177    };178 179    this.client = client;180  }181 182  get databaseName(): string {183    return this.s.namespace.db;184  }185 186  // Options187  get options(): DbOptions | undefined {188    return this.s.options;189  }190 191  /**192   * Check if a secondary can be used (because the read preference is *not* set to primary)193   */194  get secondaryOk(): boolean {195    return this.s.readPreference?.preference !== 'primary' || false;196  }197 198  get readConcern(): ReadConcern | undefined {199    return this.s.readConcern;200  }201 202  /**203   * The current readPreference of the Db. If not explicitly defined for204   * this Db, will be inherited from the parent MongoClient205   */206  get readPreference(): ReadPreference {207    if (this.s.readPreference == null) {208      return this.client.readPreference;209    }210 211    return this.s.readPreference;212  }213 214  get bsonOptions(): BSONSerializeOptions {215    return this.s.bsonOptions;216  }217 218  // get the write Concern219  get writeConcern(): WriteConcern | undefined {220    return this.s.writeConcern;221  }222 223  get namespace(): string {224    return this.s.namespace.toString();225  }226 227  public get timeoutMS(): number | undefined {228    return this.s.options?.timeoutMS;229  }230 231  /**232   * Create a new collection on a server with the specified options. Use this to create capped collections.233   * More information about command options available at https://www.mongodb.com/docs/manual/reference/command/create/234   *235   * Collection namespace validation is performed server-side.236   *237   * @param name - The name of the collection to create238   * @param options - Optional settings for the command239   */240  async createCollection<TSchema extends Document = Document>(241    name: string,242    options?: CreateCollectionOptions243  ): Promise<Collection<TSchema>> {244    options = resolveOptions(this, options);245    return await createCollections<TSchema>(this, name, options);246  }247 248  /**249   * Execute a command250   *251   * @remarks252   * This command does not inherit options from the MongoClient.253   *254   * The driver will ensure the following fields are attached to the command sent to the server:255   * - `lsid` - sourced from an implicit session or options.session256   * - `$readPreference` - defaults to primary or can be configured by options.readPreference257   * - `$db` - sourced from the name of this database258   *259   * If the client has a serverApi setting:260   * - `apiVersion`261   * - `apiStrict`262   * - `apiDeprecationErrors`263   *264   * When in a transaction:265   * - `readConcern` - sourced from readConcern set on the TransactionOptions266   * - `writeConcern` - sourced from writeConcern set on the TransactionOptions267   *268   * Attaching any of the above fields to the command will have no effect as the driver will overwrite the value.269   *270   * @param command - The command to run271   * @param options - Optional settings for the command272   */273  async command(command: Document, options?: RunCommandOptions & Abortable): Promise<Document> {274    // Intentionally, we do not inherit options from parent for this operation.275    return await executeOperation(276      this.client,277      new RunCommandOperation(278        this.s.namespace,279        command,280        resolveOptions(undefined, {281          ...resolveBSONOptions(options),282          timeoutMS: options?.timeoutMS ?? this.timeoutMS,283          session: options?.session,284          readPreference: options?.readPreference,285          signal: options?.signal286        })287      )288    );289  }290 291  /**292   * Execute an aggregation framework pipeline against the database.293   *294   * @param pipeline - An array of aggregation stages to be executed295   * @param options - Optional settings for the command296   */297  aggregate<T extends Document = Document>(298    pipeline: Document[] = [],299    options?: AggregateOptions300  ): AggregationCursor<T> {301    return new AggregationCursor(302      this.client,303      this.s.namespace,304      pipeline,305      resolveOptions(this, options)306    );307  }308 309  /** Return the Admin db instance */310  admin(): Admin {311    return new Admin(this);312  }313 314  /**315   * Returns a reference to a MongoDB Collection. If it does not exist it will be created implicitly.316   *317   * Collection namespace validation is performed server-side.318   *319   * @param name - the collection name we wish to access.320   * @returns return the new Collection instance321   */322  collection<TSchema extends Document = Document>(323    name: string,324    options: CollectionOptions = {}325  ): Collection<TSchema> {326    if (typeof options === 'function') {327      throw new MongoInvalidArgumentError('The callback form of this helper has been removed.');328    }329    return new Collection<TSchema>(this, name, resolveOptions(this, options));330  }331 332  /**333   * Get all the db statistics.334   *335   * @param options - Optional settings for the command336   */337  async stats(options?: DbStatsOptions): Promise<Document> {338    return await executeOperation(339      this.client,340      new DbStatsOperation(this, resolveOptions(this, options))341    );342  }343 344  /**345   * List all collections of this database with optional filter346   *347   * @param filter - Query to filter collections by348   * @param options - Optional settings for the command349   */350  listCollections(351    filter: Document,352    options: Exclude<ListCollectionsOptions, 'nameOnly'> & { nameOnly: true } & Abortable353  ): ListCollectionsCursor<Pick<CollectionInfo, 'name' | 'type'>>;354  listCollections(355    filter: Document,356    options: Exclude<ListCollectionsOptions, 'nameOnly'> & { nameOnly: false } & Abortable357  ): ListCollectionsCursor<CollectionInfo>;358  listCollections<359    T extends Pick<CollectionInfo, 'name' | 'type'> | CollectionInfo =360      | Pick<CollectionInfo, 'name' | 'type'>361      | CollectionInfo362  >(filter?: Document, options?: ListCollectionsOptions & Abortable): ListCollectionsCursor<T>;363  listCollections<364    T extends Pick<CollectionInfo, 'name' | 'type'> | CollectionInfo =365      | Pick<CollectionInfo, 'name' | 'type'>366      | CollectionInfo367  >(368    filter: Document = {},369    options: ListCollectionsOptions & Abortable = {}370  ): ListCollectionsCursor<T> {371    return new ListCollectionsCursor<T>(this, filter, resolveOptions(this, options));372  }373 374  /**375   * Rename a collection.376   *377   * @remarks378   * This operation does not inherit options from the MongoClient.379   *380   * @param fromCollection - Name of current collection to rename381   * @param toCollection - New name of of the collection382   * @param options - Optional settings for the command383   */384  async renameCollection<TSchema extends Document = Document>(385    fromCollection: string,386    toCollection: string,387    options?: RenameOptions388  ): Promise<Collection<TSchema>> {389    // Intentionally, we do not inherit options from parent for this operation.390    return await executeOperation(391      this.client,392      new RenameOperation(393        this.collection<TSchema>(fromCollection) as TODO_NODE_3286,394        toCollection,395        resolveOptions(undefined, {396          ...options,397          new_collection: true,398          readPreference: ReadPreference.primary399        })400      ) as TODO_NODE_3286401    );402  }403 404  /**405   * Drop a collection from the database, removing it permanently. New accesses will create a new collection.406   *407   * @param name - Name of collection to drop408   * @param options - Optional settings for the command409   */410  async dropCollection(name: string, options?: DropCollectionOptions): Promise<boolean> {411    options = resolveOptions(this, options);412    return await dropCollections(this, name, options);413  }414 415  /**416   * Drop a database, removing it permanently from the server.417   *418   * @param options - Optional settings for the command419   */420  async dropDatabase(options?: DropDatabaseOptions): Promise<boolean> {421    return await executeOperation(422      this.client,423      new DropDatabaseOperation(this, resolveOptions(this, options))424    );425  }426 427  /**428   * Fetch all collections for the current db.429   *430   * @param options - Optional settings for the command431   */432  async collections(options?: ListCollectionsOptions): Promise<Collection[]> {433    options = resolveOptions(this, options);434    const collections = await this.listCollections({}, { ...options, nameOnly: true }).toArray();435 436    return collections437      .filter(438        // Filter collections removing any illegal ones439        ({ name }) => !name.includes('$')440      )441      .map(({ name }) => new Collection(this, name, this.s.options));442  }443 444  /**445   * Creates an index on the db and collection.446   *447   * @param name - Name of the collection to create the index on.448   * @param indexSpec - Specify the field to index, or an index specification449   * @param options - Optional settings for the command450   */451  async createIndex(452    name: string,453    indexSpec: IndexSpecification,454    options?: CreateIndexesOptions455  ): Promise<string> {456    const indexes = await executeOperation(457      this.client,458      CreateIndexesOperation.fromIndexSpecification(this, name, indexSpec, options)459    );460    return indexes[0];461  }462 463  /**464   * Remove a user from a database465   *466   * @param username - The username to remove467   * @param options - Optional settings for the command468   */469  async removeUser(username: string, options?: RemoveUserOptions): Promise<boolean> {470    return await executeOperation(471      this.client,472      new RemoveUserOperation(this, username, resolveOptions(this, options))473    );474  }475 476  /**477   * Set the current profiling level of MongoDB478   *479   * @param level - The new profiling level (off, slow_only, all).480   * @param options - Optional settings for the command481   */482  async setProfilingLevel(483    level: ProfilingLevel,484    options?: SetProfilingLevelOptions485  ): Promise<ProfilingLevel> {486    return await executeOperation(487      this.client,488      new SetProfilingLevelOperation(this, level, resolveOptions(this, options))489    );490  }491 492  /**493   * Retrieve the current profiling Level for MongoDB494   *495   * @param options - Optional settings for the command496   */497  async profilingLevel(options?: ProfilingLevelOptions): Promise<string> {498    return await executeOperation(499      this.client,500      new ProfilingLevelOperation(this, resolveOptions(this, options))501    );502  }503 504  /**505   * Retrieves this collections index info.506   *507   * @param name - The name of the collection.508   * @param options - Optional settings for the command509   */510  indexInformation(511    name: string,512    options: IndexInformationOptions & { full: true }513  ): Promise<IndexDescriptionInfo[]>;514  indexInformation(515    name: string,516    options: IndexInformationOptions & { full?: false }517  ): Promise<IndexDescriptionCompact>;518  indexInformation(519    name: string,520    options: IndexInformationOptions521  ): Promise<IndexDescriptionCompact | IndexDescriptionInfo[]>;522  indexInformation(name: string): Promise<IndexDescriptionCompact>;523  async indexInformation(524    name: string,525    options?: IndexInformationOptions526  ): Promise<IndexDescriptionCompact | IndexDescriptionInfo[]> {527    return await this.collection(name).indexInformation(resolveOptions(this, options));528  }529 530  /**531   * Create a new Change Stream, watching for new changes (insertions, updates,532   * replacements, deletions, and invalidations) in this database. Will ignore all533   * changes to system collections.534   *535   * @remarks536   * watch() accepts two generic arguments for distinct use cases:537   * - The first is to provide the schema that may be defined for all the collections within this database538   * - The second is to override the shape of the change stream document entirely, if it is not provided the type will default to ChangeStreamDocument of the first argument539   *540   * @remarks541   * When `timeoutMS` is configured for a change stream, it will have different behaviour depending542   * on whether the change stream is in iterator mode or emitter mode. In both cases, a change543   * stream will time out if it does not receive a change event within `timeoutMS` of the last change544   * event.545   *546   * Note that if a change stream is consistently timing out when watching a collection, database or547   * client that is being changed, then this may be due to the server timing out before it can finish548   * processing the existing oplog. To address this, restart the change stream with a higher549   * `timeoutMS`.550   *551   * If the change stream times out the initial aggregate operation to establish the change stream on552   * the server, then the client will close the change stream. If the getMore calls to the server553   * time out, then the change stream will be left open, but will throw a MongoOperationTimeoutError554   * when in iterator mode and emit an error event that returns a MongoOperationTimeoutError in555   * emitter mode.556   *557   * To determine whether or not the change stream is still open following a timeout, check the558   * {@link ChangeStream.closed} getter.559   *560   * @example561   * In iterator mode, if a next() call throws a timeout error, it will attempt to resume the change stream.562   * The next call can just be retried after this succeeds.563   * ```ts564   * const changeStream = collection.watch([], { timeoutMS: 100 });565   * try {566   *     await changeStream.next();567   * } catch (e) {568   *     if (e instanceof MongoOperationTimeoutError && !changeStream.closed) {569   *       await changeStream.next();570   *     }571   *     throw e;572   * }573   * ```574   *575   * @example576   * In emitter mode, if the change stream goes `timeoutMS` without emitting a change event, it will577   * emit an error event that returns a MongoOperationTimeoutError, but will not close the change578   * stream unless the resume attempt fails. There is no need to re-establish change listeners as579   * this will automatically continue emitting change events once the resume attempt completes.580   *581   * ```ts582   * const changeStream = collection.watch([], { timeoutMS: 100 });583   * changeStream.on('change', console.log);584   * changeStream.on('error', e => {585   *     if (e instanceof MongoOperationTimeoutError && !changeStream.closed) {586   *         // do nothing587   *     } else {588   *         changeStream.close();589   *     }590   * });591   * ```592   * @param pipeline - An array of {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation-pipeline/|aggregation pipeline stages} through which to pass change stream documents. This allows for filtering (using $match) and manipulating the change stream documents.593   * @param options - Optional settings for the command594   * @typeParam TSchema - Type of the data being detected by the change stream595   * @typeParam TChange - Type of the whole change stream document emitted596   */597  watch<598    TSchema extends Document = Document,599    TChange extends Document = ChangeStreamDocument<TSchema>600  >(pipeline: Document[] = [], options: ChangeStreamOptions = {}): ChangeStream<TSchema, TChange> {601    // Allow optionally not specifying a pipeline602    if (!Array.isArray(pipeline)) {603      options = pipeline;604      pipeline = [];605    }606 607    return new ChangeStream<TSchema, TChange>(this, pipeline, resolveOptions(this, options));608  }609 610  /**611   * A low level cursor API providing basic driver functionality:612   * - ClientSession management613   * - ReadPreference for server selection614   * - Running getMores automatically when a local batch is exhausted615   *616   * @param command - The command that will start a cursor on the server.617   * @param options - Configurations for running the command, bson options will apply to getMores618   */619  runCursorCommand(command: Document, options?: RunCursorCommandOptions): RunCommandCursor {620    return new RunCommandCursor(this, command, options);621  }622}623