提问人:Tony mpt 提问时间:11/14/2023 更新时间:11/14/2023 访问量:56
不能用猫鼬做populate()
Cannot do populate() with mongoose
问:
我是 MongoDB 和 Mongoose 的新手,我想在两个文档之间执行 populate()。在查阅文档并寻找答案后,我向您寻求帮助。 我有两个模型:
笔记模型
const mongoose = require('mongoose');
const noteSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
title: {
type: String,
required: true
},
color: {
type: String,
required: true
},
position: {
type: Number,
required: true
},
isCheckBoxMode: {
type: Boolean,
required: true
},
items: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Item'
}]
}, {timestamps: true });
const Note = mongoose.model('Note', noteSchema);
module.exports = Note;
项目模型
const mongoose = require('mongoose');
const itemSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
text: {
type: String,
required: true
},
isCompleted: {
type: Boolean,
required: true
},
noteId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Note',
required: true
},
}, {timestamps: true });
const Item = mongoose.model('Item', itemSchema);
module.exports = Item;
在此查询中,我想使用引用 Item 文档的“items”属性检索链接到 noteId 的所有项目的数组。如上所述,我确保在两个文档之间进行引用,一方面使用 items 属性及其 ref Item,另一方面使用 NoteId 属性,其 id 对应于正确的注释并引用 Note 文档。
最好有一个例子。我正在使用 Mongo Atlas 快速部署数据库。我用 Postman 创建了一个 ID 为“6553448ef2c06064f266f785”的注释:
以及两个项目,每个项目引用 noteId “6553448ef2c06064f266f785”:
不幸的是,当我使用 populate('items') 发送请求以检索我的项目内容时,我收到一个空数组:
router.get('/:noteId', (req, res, next) => {
const id = req.params.noteId;
Note.findById(id)
.populate('items')
.exec()
.then(doc => {
if (doc) {
res.status(200).json({
notes: doc,
});
}else {
res.status(404).json({message : 'No Valid entry found for provided ID'});
}
})
.catch(err => {
console.log(err);
res.status(500).json({error: err});
});
});
Postman 中的请求和响应
我找到了另一种解决方案,使用“虚拟”,但它不是最优化的解决方案,我害怕失去性能。
const mongoose = require('mongoose');
const noteSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
title: {
type: String,
required: true
},
color: {
type: String,
required: true
},
position: {
type: Number,
required: true
},
isCheckBoxMode: {
type: Boolean,
required: true
},
}, {timestamps: true });
noteSchema.virtual('items', {
ref: 'Item',
localField: '_id',
foreignField: 'noteId'
});
noteSchema.set('toObject', { virtuals: true });
noteSchema.set('toJSON', { virtuals: true });
const Note = mongoose.model('Note', noteSchema);
module.exports = Note;
对不起,如果我的问题有点愚蠢,但我搜索了很长时间,找不到任何解决方案。提前感谢您的帮助
我试图在 Mongoose 文档以及其他 Stack Overflow 帖子之后链接这两个文档,但没有奏效。此外,我设置了一个有效的“虚拟”,并允许我检索所有项目,但这并未优化。此外,当我使用 POST 路由添加项目时,如果在我的请求中,我也将项目的 id 添加到注释的“items”数组中,则填充有效。 但这也不是一个优化的解决方案。我想在两个“refs”之间做一个简单的填充。
答:
您的 Note 架构看起来不错。您有一个属性,该属性已被正确定义为具有相应数组的数组,因此看起来是教科书。items
mongoose.Schema.Types.ObjectId
ref:'Note'
我的建议是将 and 属性显式传递给该方法并采用如下模式:path
model
populate
async/await
router.get('/:noteId', async (req, res, next) => { //< Mark as async
try{
const id = req.params.noteId;
const doc = await Note.findById(id).populate({ //< use await
path: 'items', model: Item //< pass in the path and model
});
if(!doc){
return res.status(400).json({
message : 'No Valid entry found for provided ID'
});
}else{
return res.status(200).json({
notes: doc,
});
}
}catch(err){
console.log(err);
res.status(500).json({error: err});
}
});
注意:请确保数组中有值。从指南针屏幕截图中看不清楚,因为数组在显示屏中折叠。最后,你的内在是正确的,你不需要虚拟。ObjectId
items
items
评论
async/await
path
model
note
items
objectIds
save
评论