Проблема с взаимной ссылкой на документ в Mongoose - PullRequest
0 голосов
/ 26 декабря 2018

Я искал повсюду, чтобы найти способ ссылаться на документы взаимно в Mongoose.Но вся документация, включая Заполнение , содержит только примеры, которые сохраняют 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)
        }
    })
})

Неловкая вещь, которая случается, заключается в том, что когда я перехожу по маршруту "/ category", чтобы создать новую категорию, это ответ, который я получаю от сервера, и это именно то, что я хочу:

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

Но когда я использую оболочку mongo для поиска категорий, вот что на самом деле сохраняется в базе данных:

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

и массив sub_categories пустой !!!

1 Ответ

0 голосов
/ 26 декабря 2018

Вы задали два вопроса, и вот мое мнение относительно первого, касающегося взаимно ссылающихся документов:

Если вы не знаете, что существует довольно небольшое, конечное количество подкатегорий, не используйте массив дляхранить ссылки.Если подкатегории могут расти без ограничений, вы можете столкнуться с проблемами с производительностью позже.(например, см. эту статью для получения дополнительной информации)

Начиная с mongoose 4.5, существует замечательная функция под названием «виртуальное заполнение», которая, я думаю, является более элегантным решением вашей проблемы.Для этого вы можете просто создать виртуальное поле в своей категории, которое будет автоматически извлекать массив подкатегорий для него, например, так:

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

Если использовать это так, фактическое поле не будет сохранено вколлекции категорий, но если вы правильно запросите документ, вы сможете использовать его точно так же, без проблем сохранения массивов ссылок:

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

По этой теме есть отличная статья.здесь: http://thecodebarbarian.com/mongoose-virtual-populate

Это также должно решить (или, по крайней мере, обойти) вашу вторую проблему, так как поле больше не сохраняется в БД.Почему он не отображает данные, я не знаю, но я считаю, что вы должны быть в состоянии отладить это, добавив сначала проверку того, что правильные данные были записаны в БД в вашем коде (например, перед возвратом данных, запустите Category.find() чтобы убедиться, что вы действительно обновили БД и не только вернули устаревший объект, который не был сохранен в БД).Если вам действительно интересно, почему это происходит, подумайте о создании нового, более конкретного вопроса только для этой проблемы с минимальным кодом задачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...