Mongoose 虚拟填充返回 null

Posted

技术标签:

【中文标题】Mongoose 虚拟填充返回 null【英文标题】:Mongoose virtual populate returns null 【发布时间】:2019-06-17 00:59:49 【问题描述】:

我正在 mongoose 和 GraphQL 上设置后端,但在 mongoose 中的虚拟填充存在一些问题。

这是一个 node.js 应用程序,运行在 mongoose 5.4.0 版本和 node 11.5.0 版本上。我试图遵循这两个指南但没有成功

http://thecodebarbarian.com/mongoose-virtual-populate https://thecodebarbarian.com/mongoose-4.13-virtual-populate-dynamic-refs-fields

const gameStatusSchema = new mongoose.Schema(
    userID: String,
    gameID:  type: mongoose.Schema.Types.ObjectId, ref: "Game",
    gameStatus: Number
, 
    timestamps: true,
    toObject:  virtuals: true ,
    toJSON:  virtuals: true 
);

const gameSchema = new mongoose.Schema(
    gameTitle: String,
    gameDescription: String,
    gameType: Number,
    gameTypeID: String,
    gamePosition: Number,
, 
    timestamps: true,
    toObject:  virtuals: true ,
    toJSON:  virtuals: true 
);

gameSchema.virtual("gameStatus", 
    ref: "GameStatus",
    localField: "_id",
    foreignField: "gameID",
    justOne: true
);

const newGame = await Game.findById(id)
.populate("gameStatus");
console.log(newGame);

newGame 对象甚至不包含 gameStatus 属性。如果我添加.toJSON(virtuals: true) gameStatus 显示为空。

以下是来自 mongo 的 JSON 对象示例

gameStatus object

    "_id" : ObjectId("5c473a872721eb7327377fa2"),
    "userID" : "5c3629deed4593ab3b435614",
    "gameID" : ObjectId("5c472bc4b6b5f745bbbd7f6a"),
    "gameStatus" : 8


game Object

    "_id" : ObjectId("5c472bc4b6b5f745bbbd7f6a"),
    "gameTitle" : "Lotto",
    "gameDescription" : "Test",
    "gameType" : 1,
    "gameTypeID" : "5c472bc4b6b5f745bbbd7f69",
    "gamePosition" : 8,
    "course" : ObjectId("5c35e5e53757a7a29c33565f"),
    "createdAt" : ISODate("2019-01-22T14:42:12.267Z"),
    "updatedAt" : ISODate("2019-01-22T14:42:12.267Z"),
    "__v" : 0

我希望上面的代码可以让我查询我的游戏对象并使用虚拟填充的 gameStatus 对象获取游戏对象,但它返回 null。如果有人可以看看我的问题会很高兴。

【问题讨论】:

你能告诉我你在哪里创建模型吗?以及您是如何创建它的? 我不确定我是否理解你的问题@MuhammadFaizan。它们是在单独的文件中创建的。导入 Mongoose,导出模型。包含模型的文件夹有一个 index.ts 文件,其中所有模型都作为模块导出。 const Game = mongoose.model("Game", gameSchema); export default Game; 我不认为这是相关的,但你应该在时间戳旁边的选项中添加 toJSON 和 toObject:true @BenSower 是的。我正在请求以下 ID,它在上述两个对象中都表示:5c472bc4b6b5f745bbbd7f6a。我还尝试将 toJSON 和 toObject 移到包含时间戳的大括号中,但没有任何区别。 你能看看这个独立的要点,看看它是否适合你吗? gist.github.com/BenSower/d20479c18cdd77ded3cf1dbbb0230b50 使用的是 mongoose 5.4.2 和 mongodb 3.6.3 【参考方案1】:

默认情况下,虚拟字段不活动。 您应该将它们设置为活动字段。像这样

user.set('toObject',  virtuals: true );    // add this
user.set('toJSON',  virtuals: true );      // add this

如果需要也可以这样做

user.set('toObject',  virtuals: true );    // add this
user.set('toJSON',  virtuals: true );      // add this
user.plugin(mongooseLeanVirtuals);           // add this

【讨论】:

【参考方案2】:

为集合命名时出了点问题。 Mongoose 通常将“es”添加到集合名称中,如复数形式。在 mongoose mongoose.set("debug", true); 中启用调试并看到它正在寻找错误的集合后,我发现了这一点。在这种情况下,集合名称缺少“es”。

这个堆栈溢出线程稍微解释一下

Why does mongoose always add an s to the end of my collection name

我通过将 collection: "gameStatus" 添加到我的 mongoose 架构选项来解决它。

【讨论】:

以上是关于Mongoose 虚拟填充返回 null的主要内容,如果未能解决你的问题,请参考以下文章

使用 Mongoose 进行虚拟填充

Mongoose 使用多个本地/外键对填充虚拟

Mongoose 填充返回 null

Mongoose 填充返回空数组

Mongoose 填充返回空数组

Mongoose 填充返回的 ObjectId 和空数组