【问题标题】:Problem with reciprocal document referencing in MongooseMongoose 中互惠文档引用的问题
【发布时间】:2019-05-24 13:57:20
【问题描述】:

我到处寻找在 Mongoose 中相互引用文档的方法。但是包括Populate 在内的所有文档都只有将一个文档的objectID 保存在另一个文档中的示例。考虑到我有一个父文档(“类别”)和多个子文档(“子类别”),我想在子文档中引用父文档,反之亦然。我该怎么做?

我想到的最后一件事是在将文档保存到数据库之前添加 objectID 引用。这是代码:

类别架构:

let mongoose = require("mongoose")


let categorySchema = new mongoose.Schema({
    name: String,
    sale_type: String,
    sub_categories: [{type: mongoose.Schema.Types.ObjectId, ref: 
    "SubCategory" }]
})

module.exports = mongoose.model("Category", categorySchema)

子类别架构:

let mongoose = require("mongoose")

let subcategorySchema = new mongoose.Schema({
    name: String,
    sale_type: String,
    category: {type: mongoose.Schema.Types.ObjectId, ref: "Category" }
})

module.exports = mongoose.model("SubCategory", subcategorySchema)

主文件:(此路线用于制作新的“类别”)

app.post("/categories", function(req, res){
    let name = req.body.name
    let sale_type = req.body.sale_type
    let sub_categories = req.body.sub_categories.split(",")
    let category = new Category({
        _id: new mongoose.Types.ObjectId(),
        name: name,
        sale_type: sale_type,
        sub_categories: []
    })
    sub_categories.forEach(function(element){
        let sub_category = new SubCategory({
            _id: new mongoose.Types.ObjectId(),
            name: element,
            sale_type: sale_type,
            category: category._id
        })
        sub_category.save(function(err, subcat){
            if (err){
                console.log(err);
                res.status(500).send("")
            } else {
                category.sub_categories.push(subcat._id)
            }
        })
    })
    category.save(function(err, cat){
        if (err){
            console.log(err)
            res.status(500).send("")
        } else {
            res.status(200).json(cat)
        }
    })
})

发生的尴尬事情是,当我点击“/categories”路由创建一个新类别时,这是我从服务器得到的响应,这正是我想要的:

{
    "sub_categories": [
        "5c2340bf4641017050567fe8",
        "5c2340bf4641017050567fea"
    ],
    "_id": "5c2340bf4641017050567fe6",
    "name": "cat",
    "sale_type": "retail",
    "__v": 0
}

但是当我使用 mongo shell 查找类别时,这是实际保存在数据库中的内容:

{ "_id" : ObjectId("5c2340bf4641017050567fe6"), "sub_categories" : [ ], 
"name" : "cat", "sale_type" : "retail", "__v" : 0 }

sub_categories 数组为空!!!

【问题讨论】:

    标签: javascript mongodb express mongoose


    【解决方案1】:

    您问了两个问题,这是我对第一个问题的看法,涉及相互引用文档:

    除非您知道子类别的数量非常少且数量有限,否则不要使用数组来存储引用。如果子类别可以无限制地增长,您以后可能会遇到性能问题。 (例如,请参阅this 文章了解更多信息)

    从 mongoose 4.5 开始,有一个很棒的功能叫做“虚拟填充”,我认为这是一个更优雅的解决您的问题的方法。为此,您可以简单地在您的类别中创建一个虚拟字段,它会自动为其获取子类别数组,如下所示:

    // a `ref` property is how you enable virtual population
    Category.virtual('subcategories', {
      localField: '_id',
      ref: 'Subcategory',
      foreignField: 'category'
    });
    

    如果这样使用,Category 集合中将不会保存实际的字段,但如果您正确查询 doc,您将能够同样使用它,而不会出现保存引用数组的问题:

    Category.find().populate('subcategories')
    

    这里有一篇关于该主题的精彩文章:http://thecodebarbarian.com/mongoose-virtual-populate

    这也应该解决(或至少解决)您的第二个问题,因为该字段不再被持久化到数据库中。为什么它不显示我不知道的数据,但我相信你应该能够通过首先验证代码中是否将正确的数据写入数据库来调试它(例如,在返回数据之前,运行@987654325 @ 以确保您实际更新了数据库,并且不仅返回了一个陈旧的对象,而且还没有持久化到数据库中)。如果您真的对为什么会发生这种情况感兴趣,请考虑使用最少的问题代码为这个问题创建一个新的、更具体的问题。

    【讨论】:

      猜你喜欢
      • 2020-12-26
      • 2015-07-17
      • 1970-01-01
      • 2014-09-11
      • 2020-01-31
      • 2017-05-29
      • 2019-01-08
      • 2018-06-20
      • 2018-02-13
      相关资源
      最近更新 更多