Skip to content

Commit 32fd472

Browse files
committed
perf: some more micro optimizations for find() and findOne() re: #14906
1 parent 1a2faa7 commit 32fd472

File tree

2 files changed

+22
-19
lines changed

2 files changed

+22
-19
lines changed

lib/document.js

+1-6
Original file line numberDiff line numberDiff line change
@@ -741,15 +741,10 @@ function init(self, obj, doc, opts, prefix) {
741741
let schemaType;
742742
let path;
743743
let i;
744-
let index = 0;
745744
const strict = self.$__.strictMode;
746745
const docSchema = self.$__schema;
747746

748-
while (index < len) {
749-
_init(index++);
750-
}
751-
752-
function _init(index) {
747+
for (let index = 0; index < len; ++index) {
753748
i = keys[index];
754749
// avoid prototype pollution
755750
if (i === '__proto__' || i === 'constructor') {

lib/query.js

+21-13
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,22 @@ const queryOptionMethods = new Set([
6565
'wtimeout'
6666
]);
6767

68+
const opToThunk = new Map([
69+
['countDocuments', '_countDocuments'],
70+
['distinct', '__distinct'],
71+
['estimatedDocumentCount', '_estimatedDocumentCount'],
72+
['find', '_find'],
73+
['findOne', '_findOne'],
74+
['findOneAndReplace', '_findOneAndReplace'],
75+
['findOneAndUpdate', '_findOneAndUpdate'],
76+
['replaceOne', '_replaceOne'],
77+
['updateMany', '_updateMany'],
78+
['updateOne', '_updateOne'],
79+
['deleteMany', '_deleteMany'],
80+
['deleteOne', '_deleteOne'],
81+
['findOneAndDelete', '_findOneAndDelete']
82+
]);
83+
6884
/**
6985
* Query constructor used for building queries. You do not need
7086
* to instantiate a `Query` directly. Instead use Model functions like
@@ -4397,22 +4413,14 @@ Query.prototype.exec = async function exec(op) {
43974413
if (this.model == null) {
43984414
throw new MongooseError('Query must have an associated model before executing');
43994415
}
4400-
this._validateOp();
4401-
4402-
if (!this.op) {
4403-
return;
4404-
}
44054416

4406-
if (this.options && this.options.sort) {
4407-
const keys = Object.keys(this.options.sort);
4408-
if (keys.includes('')) {
4409-
throw new Error('Invalid field "" passed to sort()');
4410-
}
4417+
const thunk = opToThunk.get(this.op);
4418+
if (!thunk) {
4419+
throw new MongooseError('Query has invalid `op`: "' + this.op + '"');
44114420
}
44124421

4413-
let thunk = '_' + this.op;
4414-
if (this.op === 'distinct') {
4415-
thunk = '__distinct';
4422+
if (this.options && this.options.sort && typeof this.options.sort === 'object' && this.options.sort.hasOwnProperty('')) {
4423+
throw new Error('Invalid field "" passed to sort()');
44164424
}
44174425

44184426
if (this._executionStack != null) {

0 commit comments

Comments
 (0)