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>;
当使用 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>;