无法使用猫鼬进行 populate()

问题描述 投票:0回答:1

我是 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;

在此查询中,我想使用“items”属性(引用 Item 文档)检索链接到 noteId 的所有项目的数组。正如您在上面所看到的,我确保在两个文档之间进行引用,一方面使用 items 属性及其 ref Item,另一方面使用 NoteId 属性,其 id 对应于正确的注释并引用该注释文件。

最好有例子。我正在使用 Mongo Atlas 快速部署数据库。我用 Postman 创建了一条注释,其 id 是“6553448ef2c06064f266f785”:

Note document

还有两个项目,每个项目都引用 noteId“6553448ef2c06064f266f785”:

Item document

不幸的是,当我使用 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 中的请求和响应

request

我找到了另一种解决方案,使用“虚拟”,但它不是最优化的解决方案,我担心会损失性能。

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”之间进行简单的填充。

node.js mongoose mongoose-schema ref mongoose-populate
1个回答
0
投票

您的注释架构看起来不错。您有一个

items
属性,该属性已被正确定义为
mongoose.Schema.Types.ObjectId
与相应的
ref:'Note'
的数组,因此看起来像教科书。

我的建议是显式地将

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});
   }
});
© www.soinside.com 2019 - 2024. All rights reserved.