当我通过 ObjectId 字段查询时,我遇到猫鼬查询问题。传递
mongoose.Types.ObjectId
或 string
都会引发错误。当我将 ObjectId 转换为 mongoose.Schema.Types.ObjectId
时,TypeScript 才会停止抱怨,然后在运行时崩溃,因为它不是有效的 ObjectId。
interface DocumentWithTimestamp extends Document<ObjectId> {
createdAt: Date;
updatedAt: Date;
}
首先,我注意到 Document 将
_id
定义为 ObjectId | undefined
,这已经让一切变得复杂了。
我定义我的模式如下:
export interface LanguageSchema extends DocumentWithTimestamp {
langCode: string;
locale: string;
}
interface LanguageModel extends Model<LanguageSchema> {
mapToLanguage(language: LeanDocument<LanguageSchema> | LanguageSchema): Language;
}
const languageSchema = new Schema<LanguageSchema, LanguageModel>(
{
langCode: { type: String, required: true, trim: true },
locale: { type: String, unique: true, required: true, trim: true },
},
{ collection: 'language', timestamps: true, versionKey: false },
);
languageSchema.statics.mapToLanguage = function (language: LeanDocument<LanguageSchema> | LanguageSchema): Language {
return {
id: language._id?.toString() || '', // why is _id conditional...?
langCode: language.langCode,
locale: language.locale,
};
};
export const LanguageModel = model<LanguageSchema, LanguageModel>('Language', languageSchema);
现在通过 _id 或任何其他 ObjectId 字段查询我的 LanguageModel 会引发类型错误:
export async function findLanguagesByIds(languageIds: string[]) {
return LanguageModel.find({ _id: { $in: languageIds } }).lean();
}
错误:
Argument of type '{ _id: { $in: string[]; }; }' is not assignable to parameter of type 'Callback<LanguageSchema[]>'.
Object literal may only specify known properties, and '_id' does not exist in type 'Callback<LanguageSchema[]>'.
当我尝试将 string[] 转换为 Schema.Types.ObjectId[] 数组时,错误消失了,但这不是解决方案,因为它在运行时崩溃(Schema.Types.ObjectId 不是有效的 ObjectId)。
const languages = await LanguageModel.find({
_id: { $in: languageIds.map((id) => new mongoose.Schema.Types.ObjectId(id)) },
}).lean();
如果我转换为
mongoose.Types.ObjectId
(到真正的ObjectId),它会再次抛出错误......
如有任何帮助,我们将不胜感激!
我找到了解决问题的方法。
mongoose文档定义如下:
class Document<T = any, TQueryHelpers = any, DocType = any> {
constructor(doc?: any);
/** This documents _id. */
_id?: T;
// ...
}
我使用
Document<ObjectId>
扩展了它。然而,ObjectId 类型是 Schema 类型,例如
import { ObjectId } from "mongoose";
但它实际上应该是 mongoose 的实际 ObjectId 类型,而不是 Schema 类型!
修复:
import { Types } from "mongoose"
interface DocumentWithTimestamp extends Document<Types.ObjectId> {
createdAt: Date;
updatedAt: Date;
}
我有一个肮脏的解决方案
就我而言,我需要按用户 ID 进行过滤,同样的错误。
此解析修复了它:与 ObjectId 一样未知
const userId = req.userId as unknown as ObjectId;
const res: IPostDocument[] = await Post.find({userId: userId})
你也可以尝试这样做 --> { _id: 新的 ObjectId(id) }
并且您可以从 MongoDB 导入 ObjectId --> 从“MongoDB”导入{ObjectId};
谢谢