在 TypeScript 中使用查詢助手

查詢助手 讓您在 Mongoose 查詢上定義自訂輔助方法。查詢助手使用鏈式語法使查詢更語義化。

以下是一個 JavaScript 中查詢助手如何運作的範例。

ProjectSchema.query.byName = function(name) {
  return this.find({ name: name });
};
const 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');

手動輸入的查詢助手

在 TypeScript 中,您可以使用單獨的查詢助手介面來定義查詢助手。Mongoose 的 Model 接受 3 個泛型參數

  1. DocType
  2. 一個 TQueryHelpers 類型
  3. 一個 TMethods 類型

第二個泛型參數 TQueryHelpers 應該是一個介面,其中包含每個查詢助手的函數簽名。以下是一個建立帶有 byName 查詢助手的 ProjectModel 的範例。

import { HydratedDocument, Model, QueryWithHelpers, Schema, model, connect } from 'mongoose';

interface Project {
  name?: string;
  stars?: number;
}

interface ProjectQueryHelpers {
  byName(name: string): QueryWithHelpers<
    HydratedDocument<Project>[],
    HydratedDocument<Project>,
    ProjectQueryHelpers
  >
}

type ProjectModelType = Model<Project, ProjectQueryHelpers>;

const ProjectSchema = new Schema<
  Project,
  Model<Project, ProjectQueryHelpers>,
  {},
  ProjectQueryHelpers
>({
  name: String,
  stars: Number
});

ProjectSchema.query.byName = function byName(
  this: QueryWithHelpers<any, HydratedDocument<Project>, ProjectQueryHelpers>,
  name: string
) {
  return this.find({ name: name });
};

// 2nd param to `model()` is the Model class to return.
const ProjectModel = model<Project, ProjectModelType>('Project', ProjectSchema);

run().catch(err => console.log(err));

async function run(): Promise<void> {
  await connect('mongodb://127.0.0.1:27017/test');

  // Equivalent to `ProjectModel.find({ stars: { $gt: 1000 }, name: 'mongoose' })`
  await ProjectModel.find().where('stars').gt(1000).byName('mongoose');
}

自動輸入的查詢助手

Mongoose 確實支援自動輸入的查詢助手,這些助手在結構描述選項中提供。查詢助手函數可以定義如下

import { Schema, model } from 'mongoose';

const ProjectSchema = new Schema({
  name: String,
  stars: Number
}, {
  query: {
    byName(name: string) {
      return this.find({ name });
    }
  }
});

const ProjectModel = model('Project', ProjectSchema);

// Equivalent to `ProjectModel.find({ stars: { $gt: 1000 }, name: 'mongoose' })`
await ProjectModel.find().where('stars').gt(1000).byName('mongoose');