Typescript Mongoose:为什么未定义聚合文档的方法

Typescript Mongoose: Why are methods of aggregated documents undefined

当使用 mongoose 聚合它时 returns ProfileDocuments 数组。 结果数组中的文档不包含 ProfileDocument 实现的方法。 这导致无法在数据库中的文档上调用诸如 checkPassword 之类的文档方法。

聚合示例

ProfileSchema.statics.findByLogin = async function (login: string) {
  // why do methods of aggregated documents not work?
  const results = await this.aggregate([{
    $match: { 
      $or:[{username: login}, {mail: login}]
    }
  }])

  if (results.length === 0) {
    throw new Error('Profile not found')
  }

  const profile = await this.findById(results[0]._id)

  console.log(results[0].checkPassword)
  console.log(profile.checkPassword)

  return profile
}

控制台输出

undefined
[Function (anonymous)]

方法实现

interface ProfileDocument extends IProfile, Document {
  getDisplayname: () => Promise<string>
}

ProfileSchema.methods.checkPassword = async function (password: string) {
  return await bcrypt.compare(password, this.pass)
}

根据 mongoose 文档,

The documents returned from aggregates are plain javascript objects, not mongoose documents (since any shape of document can be returned).

正如@Thakur 提到的聚合returns 原始文档。 Mongoose 提供了一个 hydrate 方法来将方法添加到文档中。

使用 ProfileSchema.hydrate(doc) 或在静态方法的上下文中 this.hydrate(doc) returns ProfileDocuments。

/**
 * Shortcut for creating a new Document from existing raw data, pre-saved in the DB.
 * The document returned has no paths marked as modified initially.
 */
hydrate(obj: any): EnforceDocument<T, TMethods>;