Query Helpers in TypeScript
Query helpers let you define custom helper methods on Mongoose queries. Query helpers make queries more semantic using chaining syntax.
ProjectSchema.query.byName = function(name) {
return this.find({ name: name });
};
var Project = mongoose.model('Project', ProjectSchema);
// Works. Any Project query, whether it be `find()`, `findOne()`,
// `findOneAndUpdate()`, `delete()`, etc. now has a `byName()` helper
Project.find().where('stars').gt(1000).byName('mongoose');
In TypeScript, Mongoose's Model
takes 3 generic parameters:
- The
DocType
- a
TQueryHelpers
type - a
TMethods
type
The 2nd generic parameter, TQueryHelpers
, should be an interface that contains a function signature for each of your query helpers.
Below is an example of creating a ProjectModel
with a byName
query helper.
import { Document, Model, Query, Schema, connect, model } from 'mongoose';
interface Project {
name: string;
stars: number;
}
const schema = new Schema<Project>({
name: { type: String, required: true },
stars: { type: Number, required: true }
});
// Query helpers should return `Query<any, Document<DocType>> & ProjectQueryHelpers`
// to enable chaining.
interface ProjectQueryHelpers {
byName(name: string): Query<any, Document<Project>> & ProjectQueryHelpers;
}
schema.query.byName = function(name): Query<any, Document<Project>> & ProjectQueryHelpers {
return this.find({ name: name });
};
// 2nd param to `model()` is the Model class to return.
const ProjectModel = model<Project, Model<Project, ProjectQueryHelpers>>('Project', schema);
run().catch(err => console.log(err));
async function run(): Promise<void> {
await connect('mongodb://localhost:27017/test', {
useNewUrlParser: true,
useUnifiedTopology: true
});
// Equivalent to `ProjectModel.find({ stars: { $gt: 1000 }, name: 'mongoose' })`
await ProjectModel.find().where('stars').gt(1000).byName('mongoose');
}