mongoose 8.2.1 → 8.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/document.js CHANGED
@@ -742,7 +742,7 @@ function init(self, obj, doc, opts, prefix) {
742
742
  if (i === '__proto__' || i === 'constructor') {
743
743
  return;
744
744
  }
745
- path = prefix + i;
745
+ path = prefix ? prefix + i : i;
746
746
  schemaType = docSchema.path(path);
747
747
  // Should still work if not a model-level discriminator, but should not be
748
748
  // necessary. This is *only* to catch the case where we queried using the
@@ -751,7 +751,8 @@ function init(self, obj, doc, opts, prefix) {
751
751
  return;
752
752
  }
753
753
 
754
- if (!schemaType && utils.isPOJO(obj[i])) {
754
+ const value = obj[i];
755
+ if (!schemaType && utils.isPOJO(value)) {
755
756
  // assume nested object
756
757
  if (!doc[i]) {
757
758
  doc[i] = {};
@@ -759,29 +760,30 @@ function init(self, obj, doc, opts, prefix) {
759
760
  self[i] = doc[i];
760
761
  }
761
762
  }
762
- init(self, obj[i], doc[i], opts, path + '.');
763
+ init(self, value, doc[i], opts, path + '.');
763
764
  } else if (!schemaType) {
764
- doc[i] = obj[i];
765
+ doc[i] = value;
765
766
  if (!strict && !prefix) {
766
- self[i] = obj[i];
767
+ self[i] = value;
767
768
  }
768
769
  } else {
769
770
  // Retain order when overwriting defaults
770
- if (doc.hasOwnProperty(i) && obj[i] !== void 0 && !opts.hydratedPopulatedDocs) {
771
+ if (doc.hasOwnProperty(i) && value !== void 0 && !opts.hydratedPopulatedDocs) {
771
772
  delete doc[i];
772
773
  }
773
- if (obj[i] === null) {
774
+ if (value === null) {
774
775
  doc[i] = schemaType._castNullish(null);
775
- } else if (obj[i] !== undefined) {
776
- const wasPopulated = obj[i].$__ == null ? null : obj[i].$__.wasPopulated;
777
- if ((schemaType && !wasPopulated) && !opts.hydratedPopulatedDocs) {
776
+ } else if (value !== undefined) {
777
+ const wasPopulated = value.$__ == null ? null : value.$__.wasPopulated;
778
+
779
+ if (schemaType && !wasPopulated && !opts.hydratedPopulatedDocs) {
778
780
  try {
779
781
  if (opts && opts.setters) {
780
782
  // Call applySetters with `init = false` because otherwise setters are a noop
781
783
  const overrideInit = false;
782
- doc[i] = schemaType.applySetters(obj[i], self, overrideInit);
784
+ doc[i] = schemaType.applySetters(value, self, overrideInit);
783
785
  } else {
784
- doc[i] = schemaType.cast(obj[i], self, true);
786
+ doc[i] = schemaType.cast(value, self, true);
785
787
  }
786
788
  } catch (e) {
787
789
  self.invalidate(e.path, new ValidatorError({
@@ -793,7 +795,7 @@ function init(self, obj, doc, opts, prefix) {
793
795
  }));
794
796
  }
795
797
  } else {
796
- doc[i] = obj[i];
798
+ doc[i] = value;
797
799
  }
798
800
  }
799
801
  // mark as hydrated
@@ -1388,6 +1390,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
1388
1390
  if (schema.options &&
1389
1391
  Array.isArray(schema.options[typeKey]) &&
1390
1392
  schema.options[typeKey].length &&
1393
+ schema.options[typeKey][0] &&
1391
1394
  schema.options[typeKey][0].ref &&
1392
1395
  _isManuallyPopulatedArray(val, schema.options[typeKey][0].ref)) {
1393
1396
  popOpts = { [populateModelSymbol]: val[0].constructor };
@@ -136,11 +136,10 @@ function iter(i) {
136
136
  let promise = null;
137
137
  let timeout = null;
138
138
  if (syncCollectionMethods[i] && typeof lastArg === 'function') {
139
- this.addQueue(() => {
140
- lastArg.call(this, null, this[i].apply(this, _args.slice(0, _args.length - 1)));
141
- }, []);
139
+ this.addQueue(i, _args);
140
+ callback = lastArg;
142
141
  } else if (syncCollectionMethods[i]) {
143
- promise = new Promise((resolve, reject) => {
142
+ promise = new this.Promise((resolve, reject) => {
144
143
  callback = function collectionOperationCallback(err, res) {
145
144
  if (timeout != null) {
146
145
  clearTimeout(timeout);
package/lib/model.js CHANGED
@@ -351,12 +351,22 @@ Model.prototype.$__handleSave = function(options, callback) {
351
351
 
352
352
  const update = delta[1];
353
353
  if (this.$__schema.options.minimize) {
354
- minimize(update);
355
- // minimize might leave us with an empty object, which would
356
- // lead to MongoDB throwing a "Update document requires atomic operators" error
357
- if (Object.keys(update).length === 0) {
358
- handleEmptyUpdate.call(this);
359
- return;
354
+ for (const updateOp of Object.values(update)) {
355
+ if (updateOp == null) {
356
+ continue;
357
+ }
358
+ for (const key of Object.keys(updateOp)) {
359
+ if (updateOp[key] == null || typeof updateOp[key] !== 'object') {
360
+ continue;
361
+ }
362
+ if (!utils.isPOJO(updateOp[key])) {
363
+ continue;
364
+ }
365
+ minimize(updateOp[key]);
366
+ if (Object.keys(updateOp[key]).length === 0) {
367
+ updateOp[key] = null;
368
+ }
369
+ }
360
370
  }
361
371
  }
362
372
 
@@ -3075,7 +3085,7 @@ Model.startSession = function() {
3075
3085
  * @param {Object} [options] see the [mongodb driver options](https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#insertMany)
3076
3086
  * @param {Boolean} [options.ordered=true] if true, will fail fast on the first error encountered. If false, will insert all the documents it can and report errors later. An `insertMany()` with `ordered = false` is called an "unordered" `insertMany()`.
3077
3087
  * @param {Boolean} [options.rawResult=false] if false, the returned promise resolves to the documents that passed mongoose document validation. If `true`, will return the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/InsertManyResult.html) with a `mongoose` property that contains `validationErrors` and `results` if this is an unordered `insertMany`.
3078
- * @param {Boolean} [options.lean=false] if `true`, skips hydrating and validating the documents. This option is useful if you need the extra performance, but Mongoose won't validate the documents before inserting.
3088
+ * @param {Boolean} [options.lean=false] if `true`, skips hydrating the documents. This means Mongoose will **not** cast or validate any of the documents passed to `insertMany()`. This option is useful if you need the extra performance, but comes with data integrity risk. Consider using with [`castObject()`](https://mongoosejs.com/docs/api/model.html#Model.castObject()).
3079
3089
  * @param {Number} [options.limit=null] this limits the number of documents being processed (validation/casting) by mongoose in parallel, this does **NOT** send the documents in batches to MongoDB. Use this option if you're processing a large number of documents and your app is running out of memory.
3080
3090
  * @param {String|Object|Array} [options.populate=null] populates the result documents. This option is a no-op if `rawResult` is set.
3081
3091
  * @param {Boolean} [options.throwOnValidationError=false] If true and `ordered: false`, throw an error if one of the operations failed validation, but all valid operations completed successfully.
@@ -3136,6 +3146,13 @@ Model.$__insertMany = function(arr, options, callback) {
3136
3146
  const results = ordered ? null : new Array(arr.length);
3137
3147
  const toExecute = arr.map((doc, index) =>
3138
3148
  callback => {
3149
+ // If option `lean` is set to true bypass validation and hydration
3150
+ if (lean) {
3151
+ // we have to execute callback at the nextTick to be compatible
3152
+ // with parallelLimit, as `results` variable has TDZ issue if we
3153
+ // execute the callback synchronously
3154
+ return immediate(() => callback(null, doc));
3155
+ }
3139
3156
  if (!(doc instanceof _this)) {
3140
3157
  if (doc != null && typeof doc !== 'object') {
3141
3158
  return callback(new ObjectParameterError(doc, 'arr.' + index, 'insertMany'));
@@ -3216,7 +3233,7 @@ Model.$__insertMany = function(arr, options, callback) {
3216
3233
  callback(null, []);
3217
3234
  return;
3218
3235
  }
3219
- const docObjects = docAttributes.map(function(doc) {
3236
+ const docObjects = lean ? docAttributes : docAttributes.map(function(doc) {
3220
3237
  if (doc.$__schema.options.versionKey) {
3221
3238
  doc[doc.$__schema.options.versionKey] = 0;
3222
3239
  }
@@ -3229,9 +3246,11 @@ Model.$__insertMany = function(arr, options, callback) {
3229
3246
 
3230
3247
  _this.$__collection.insertMany(docObjects, options).then(
3231
3248
  res => {
3232
- for (const attribute of docAttributes) {
3233
- attribute.$__reset();
3234
- _setIsNew(attribute, false);
3249
+ if (!lean) {
3250
+ for (const attribute of docAttributes) {
3251
+ attribute.$__reset();
3252
+ _setIsNew(attribute, false);
3253
+ }
3235
3254
  }
3236
3255
 
3237
3256
  if (ordered === false && throwOnValidationError && validationErrors.length > 0) {
@@ -3333,6 +3352,9 @@ Model.$__insertMany = function(arr, options, callback) {
3333
3352
  return !isErrored;
3334
3353
  }).
3335
3354
  map(function setIsNewForInsertedDoc(doc) {
3355
+ if (lean) {
3356
+ return doc;
3357
+ }
3336
3358
  doc.$__reset();
3337
3359
  _setIsNew(doc, false);
3338
3360
  return doc;
@@ -3375,6 +3397,7 @@ function _setIsNew(doc, val) {
3375
3397
  * trip to MongoDB.
3376
3398
  *
3377
3399
  * Mongoose will perform casting on all operations you provide.
3400
+ * The only exception is [setting the `update` operator for `updateOne` or `updateMany` to a pipeline](https://www.mongodb.com/docs/manual/reference/method/db.collection.bulkWrite/#updateone-and-updatemany): Mongoose does **not** cast update pipelines.
3378
3401
  *
3379
3402
  * This function does **not** trigger any middleware, neither `save()`, nor `update()`.
3380
3403
  * If you need to trigger
@@ -3410,6 +3433,15 @@ function _setIsNew(doc, val) {
3410
3433
  * console.log(res.insertedCount, res.modifiedCount, res.deletedCount);
3411
3434
  * });
3412
3435
  *
3436
+ * // Mongoose does **not** cast update pipelines, so no casting for the `update` option below.
3437
+ * // Mongoose does still cast `filter`
3438
+ * await Character.bulkWrite([{
3439
+ * updateOne: {
3440
+ * filter: { name: 'Annika Hansen' },
3441
+ * update: [{ $set: { name: 7 } }] // Array means update pipeline, so Mongoose skips casting
3442
+ * }
3443
+ * }]);
3444
+ *
3413
3445
  * The [supported operations](https://www.mongodb.com/docs/manual/reference/method/db.collection.bulkWrite/#db.collection.bulkWrite) are:
3414
3446
  *
3415
3447
  * - `insertOne`
@@ -3939,7 +3971,7 @@ Model.hydrate = function(obj, projection, options) {
3939
3971
  * - `updateMany()`
3940
3972
  *
3941
3973
  * @param {Object} filter
3942
- * @param {Object|Array} update
3974
+ * @param {Object|Array} update. If array, this update will be treated as an update pipeline and not casted.
3943
3975
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
3944
3976
  * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3945
3977
  * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
@@ -3979,7 +4011,7 @@ Model.updateMany = function updateMany(conditions, doc, options) {
3979
4011
  * - `updateOne()`
3980
4012
  *
3981
4013
  * @param {Object} filter
3982
- * @param {Object|Array} update
4014
+ * @param {Object|Array} update. If array, this update will be treated as an update pipeline and not casted.
3983
4015
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
3984
4016
  * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3985
4017
  * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
package/lib/mongoose.js CHANGED
@@ -506,12 +506,14 @@ Mongoose.prototype.pluralize = function(fn) {
506
506
  *
507
507
  * // or
508
508
  *
509
- * const collectionName = 'actor'
510
- * const M = mongoose.model('Actor', schema, collectionName)
509
+ * const collectionName = 'actor';
510
+ * const M = mongoose.model('Actor', schema, collectionName);
511
511
  *
512
512
  * @param {String|Function} name model name or class extending Model
513
513
  * @param {Schema} [schema] the schema to use.
514
514
  * @param {String} [collection] name (optional, inferred from model name)
515
+ * @param {Object} [options]
516
+ * @param {Boolean} [options.overwriteModels=false] If true, overwrite existing models with the same name to avoid `OverwriteModelError`
515
517
  * @return {Model} The model associated with `name`. Mongoose will create the model if it doesn't already exist.
516
518
  * @api public
517
519
  */
package/lib/query.js CHANGED
@@ -3880,7 +3880,7 @@ Query.prototype._replaceOne = async function _replaceOne() {
3880
3880
  * - `updateMany()`
3881
3881
  *
3882
3882
  * @param {Object} [filter]
3883
- * @param {Object|Array} [update] the update command
3883
+ * @param {Object|Array} [update] the update command. If array, this update will be treated as an update pipeline and not casted.
3884
3884
  * @param {Object} [options]
3885
3885
  * @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
3886
3886
  * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
@@ -3950,7 +3950,7 @@ Query.prototype.updateMany = function(conditions, doc, options, callback) {
3950
3950
  * - `updateOne()`
3951
3951
  *
3952
3952
  * @param {Object} [filter]
3953
- * @param {Object|Array} [update] the update command
3953
+ * @param {Object|Array} [update] the update command. If array, this update will be treated as an update pipeline and not casted.
3954
3954
  * @param {Object} [options]
3955
3955
  * @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
3956
3956
  * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
package/lib/schema.js CHANGED
@@ -1014,6 +1014,9 @@ reserved.collection = 1;
1014
1014
 
1015
1015
  Schema.prototype.path = function(path, obj) {
1016
1016
  if (obj === undefined) {
1017
+ if (this.paths[path] != null) {
1018
+ return this.paths[path];
1019
+ }
1017
1020
  // Convert to '.$' to check subpaths re: gh-6405
1018
1021
  const cleanPath = _pathToPositionalSyntax(path);
1019
1022
  let schematype = _getPath(this, path, cleanPath);
@@ -698,22 +698,21 @@ const methods = {
698
698
 
699
699
  if ((atomics.$push && atomics.$push.$each && atomics.$push.$each.length || 0) !== 0 &&
700
700
  atomics.$push.$position != atomic.$position) {
701
- throw new MongooseError('Cannot call `Array#push()` multiple times ' +
702
- 'with different `$position`');
703
- }
701
+ if (atomic.$position != null) {
702
+ [].splice.apply(arr, [atomic.$position, 0].concat(values));
703
+ ret = arr.length;
704
+ } else {
705
+ ret = [].push.apply(arr, values);
706
+ }
704
707
 
705
- if (atomic.$position != null) {
708
+ this._registerAtomic('$set', this);
709
+ } else if (atomic.$position != null) {
706
710
  [].splice.apply(arr, [atomic.$position, 0].concat(values));
707
711
  ret = this.length;
708
712
  } else {
709
713
  ret = [].push.apply(arr, values);
710
714
  }
711
715
  } else {
712
- if ((atomics.$push && atomics.$push.$each && atomics.$push.$each.length || 0) !== 0 &&
713
- atomics.$push.$position != null) {
714
- throw new MongooseError('Cannot call `Array#push()` multiple times ' +
715
- 'with different `$position`');
716
- }
717
716
  atomic = values;
718
717
  ret = _basePush.apply(arr, values);
719
718
  }
@@ -145,7 +145,7 @@ ArraySubdocument.prototype.$__fullPath = function(path, skipIndex) {
145
145
  */
146
146
 
147
147
  ArraySubdocument.prototype.$__pathRelativeToParent = function(path, skipIndex) {
148
- if (this.__index == null) {
148
+ if (this.__index == null || (!this.__parentArray || !this.__parentArray.$path)) {
149
149
  return null;
150
150
  }
151
151
  if (skipIndex) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "8.2.1",
4
+ "version": "8.2.2",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
@@ -229,7 +229,7 @@ type ResolvePathType<PathValueType, Options extends SchemaTypeOptions<PathValueT
229
229
  ObtainDocumentPathType<Item, TypeKey>[] :
230
230
  // If the type key isn't callable, then this is an array of objects, in which case
231
231
  // we need to call ObtainDocumentType to correctly infer its type.
232
- ObtainDocumentType<Item, any, { typeKey: TypeKey }>[] :
232
+ Types.DocumentArray<ObtainDocumentType<Item, any, { typeKey: TypeKey }>> :
233
233
  IsSchemaTypeFromBuiltinClass<Item> extends true ?
234
234
  ObtainDocumentPathType<Item, TypeKey>[] :
235
235
  IsItRecordAndNotAny<Item> extends true ?
package/types/models.d.ts CHANGED
@@ -156,6 +156,85 @@ declare module 'mongoose' {
156
156
 
157
157
  const Model: Model<any>;
158
158
 
159
+ export type AnyBulkWriteOperation<TSchema = AnyObject> = {
160
+ insertOne: InsertOneModel<TSchema>;
161
+ } | {
162
+ replaceOne: ReplaceOneModel<TSchema>;
163
+ } | {
164
+ updateOne: UpdateOneModel<TSchema>;
165
+ } | {
166
+ updateMany: UpdateManyModel<TSchema>;
167
+ } | {
168
+ deleteOne: DeleteOneModel<TSchema>;
169
+ } | {
170
+ deleteMany: DeleteManyModel<TSchema>;
171
+ };
172
+
173
+ export interface InsertOneModel<TSchema> {
174
+ document: mongodb.OptionalId<TSchema>
175
+ }
176
+
177
+ export interface ReplaceOneModel<TSchema = AnyObject> {
178
+ /** The filter to limit the replaced document. */
179
+ filter: FilterQuery<TSchema>;
180
+ /** The document with which to replace the matched document. */
181
+ replacement: mongodb.WithoutId<TSchema>;
182
+ /** Specifies a collation. */
183
+ collation?: mongodb.CollationOptions;
184
+ /** The index to use. If specified, then the query system will only consider plans using the hinted index. */
185
+ hint?: mongodb.Hint;
186
+ /** When true, creates a new document if no document matches the query. */
187
+ upsert?: boolean;
188
+ }
189
+
190
+ export interface UpdateOneModel<TSchema = AnyObject> {
191
+ /** The filter to limit the updated documents. */
192
+ filter: FilterQuery<TSchema>;
193
+ /** A document or pipeline containing update operators. */
194
+ update: UpdateQuery<TSchema>;
195
+ /** A set of filters specifying to which array elements an update should apply. */
196
+ arrayFilters?: AnyObject[];
197
+ /** Specifies a collation. */
198
+ collation?: mongodb.CollationOptions;
199
+ /** The index to use. If specified, then the query system will only consider plans using the hinted index. */
200
+ hint?: mongodb.Hint;
201
+ /** When true, creates a new document if no document matches the query. */
202
+ upsert?: boolean;
203
+ }
204
+
205
+ export interface UpdateManyModel<TSchema = AnyObject> {
206
+ /** The filter to limit the updated documents. */
207
+ filter: FilterQuery<TSchema>;
208
+ /** A document or pipeline containing update operators. */
209
+ update: UpdateQuery<TSchema>;
210
+ /** A set of filters specifying to which array elements an update should apply. */
211
+ arrayFilters?: AnyObject[];
212
+ /** Specifies a collation. */
213
+ collation?: mongodb.CollationOptions;
214
+ /** The index to use. If specified, then the query system will only consider plans using the hinted index. */
215
+ hint?: mongodb.Hint;
216
+ /** When true, creates a new document if no document matches the query. */
217
+ upsert?: boolean;
218
+ }
219
+
220
+ export interface DeleteOneModel<TSchema = AnyObject> {
221
+ /** The filter to limit the deleted documents. */
222
+ filter: FilterQuery<TSchema>;
223
+ /** Specifies a collation. */
224
+ collation?: mongodb.CollationOptions;
225
+ /** The index to use. If specified, then the query system will only consider plans using the hinted index. */
226
+ hint?: mongodb.Hint;
227
+ }
228
+
229
+ export interface DeleteManyModel<TSchema = AnyObject> {
230
+ /** The filter to limit the deleted documents. */
231
+ filter: FilterQuery<TSchema>;
232
+ /** Specifies a collation. */
233
+ collation?: mongodb.CollationOptions;
234
+ /** The index to use. If specified, then the query system will only consider plans using the hinted index. */
235
+ hint?: mongodb.Hint;
236
+ }
237
+
159
238
  /**
160
239
  * Models are fancy constructors compiled from `Schema` definitions.
161
240
  * An instance of a model is called a document.
@@ -201,17 +280,11 @@ declare module 'mongoose' {
201
280
  * round trip to the MongoDB server.
202
281
  */
203
282
  bulkWrite<DocContents = TRawDocType>(
204
- writes: Array<
205
- mongodb.AnyBulkWriteOperation<
206
- DocContents extends mongodb.Document ? DocContents : any
207
- > & MongooseBulkWritePerWriteOptions>,
283
+ writes: Array<AnyBulkWriteOperation<DocContents extends Document ? any : (DocContents extends {} ? DocContents : any)>>,
208
284
  options: mongodb.BulkWriteOptions & MongooseBulkWriteOptions & { ordered: false }
209
285
  ): Promise<mongodb.BulkWriteResult & { mongoose?: { validationErrors: Error[] } }>;
210
286
  bulkWrite<DocContents = TRawDocType>(
211
- writes: Array<
212
- mongodb.AnyBulkWriteOperation<
213
- DocContents extends mongodb.Document ? DocContents : any
214
- > & MongooseBulkWritePerWriteOptions>,
287
+ writes: Array<AnyBulkWriteOperation<DocContents extends Document ? any : (DocContents extends {} ? DocContents : any)>>,
215
288
  options?: mongodb.BulkWriteOptions & MongooseBulkWriteOptions
216
289
  ): Promise<mongodb.BulkWriteResult>;
217
290
 
@@ -36,7 +36,8 @@ declare module 'mongoose' {
36
36
  | PipelineStage.SortByCount
37
37
  | PipelineStage.UnionWith
38
38
  | PipelineStage.Unset
39
- | PipelineStage.Unwind;
39
+ | PipelineStage.Unwind
40
+ | PipelineStage.VectorSearch;
40
41
 
41
42
  export namespace PipelineStage {
42
43
  export interface AddFields {
@@ -308,5 +309,17 @@ declare module 'mongoose' {
308
309
  /** [`$unwind` reference](https://www.mongodb.com/docs/manual/reference/operator/aggregation/unwind/) */
309
310
  $unwind: string | { path: string; includeArrayIndex?: string; preserveNullAndEmptyArrays?: boolean }
310
311
  }
312
+ export interface VectorSearch {
313
+ /** [`$vectorSearch` reference](https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/) */
314
+ $vectorSearch: {
315
+ index: string,
316
+ path: string,
317
+ queryVector: number[],
318
+ numCandidates: number,
319
+ limit: number,
320
+ filter?: Expression,
321
+ }
322
+ }
323
+
311
324
  }
312
325
  }
package/types/query.d.ts CHANGED
@@ -627,6 +627,12 @@ declare module 'mongoose' {
627
627
  QueryOp
628
628
  >;
629
629
 
630
+ /** Add pre middleware to this query instance. Doesn't affect other queries. */
631
+ pre(fn: Function): this;
632
+
633
+ /** Add post middleware to this query instance. Doesn't affect other queries. */
634
+ post(fn: Function): this;
635
+
630
636
  /** Get/set the current projection (AKA fields). Pass `null` to remove the current projection. */
631
637
  projection(fields?: ProjectionFields<DocType> | string): ProjectionFields<DocType>;
632
638
  projection(fields: null): null;