Подтвердить что ты не робот

Отображение многих-ко-многим с помощью Mongoose

У меня есть FlashcardSchemas и PackageSchemas в моем дизайне. Одна флешка может принадлежать различным пакетам, а пакет может содержать различные карточки.

Ниже вы можете увидеть сокращенную версию моих определений схемы mongoose:

// package-schema.js
var Schema = mongoose.Schema,
    ObjectId = Schema.ObjectId;

var PackageSchema = new Schema({
    id          : ObjectId,
    title       : { type: String, required: true },
    flashcards  : [ FlashcardSchema ]
});

var exports = module.exports = mongoose.model('Package', PackageSchema);

// flashcard-schema.js
var Schema = mongoose.Schema,
    ObjectId = Schema.ObjectId;

var FlashcardSchema = new Schema({
    id      : ObjectId,
    type        : { type: String, default: '' },
    story       : { type: String, default: '' },
    packages    : [ PackageSchema ]
});

var exports = module.exports = mongoose.model('Flashcard', FlashcardSchema);

Как видно из комментариев выше, эти два определения схемы относятся к отдельным файлам и ссылаются друг на друга.

Я получаю исключение, заявляющее, что PackageSchema не определено, как и ожидалось. Как я могу сопоставить отношение "многие ко многим" с мангустом?

4b9b3361

Ответ 1

Вы делаете это правильно, однако проблема заключается в том, что вы должны включать PackageSchema в flashcard-schema.js и наоборот. В противном случае эти файлы не имеют представления о том, что вы ссылаетесь на

var Schema = mongoose.Schema,
    ObjectId = Schema.ObjectId;
    PackageSchema = require('./path/to/package-schema.js')

var FlashcardSchema = new Schema({
    id      : ObjectId,
    type        : { type: String, default: '' },
    story       : { type: String, default: '' },
    packages    : [ PackageSchema ]
});

Ответ 2

Я новичок в node, mongoDB и mongoose, но я думаю, что правильный способ сделать это:

var PackageSchema = new Schema({
    id: ObjectId,
    title: { type: String, required: true },
    flashcards: [ {type : mongoose.Schema.ObjectId, ref : 'Flashcard'} ]
});

var FlashcardSchema = new Schema({
    id: ObjectId,
    type: { type: String, default: '' },
    story: { type: String, default: '' },
    packages: [ {type : mongoose.Schema.ObjectId, ref : 'Package'} ]
});

Таким образом, вы сохраняете только ссылку на объект, а не встроенный объект.

Ответ 3

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

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

Ответ 4

Вы можете использовать метод Schema.add(), чтобы избежать проблемы с прямой ссылкой.

Это (непроверенное) решение помещает схему в один .js файл

модели /index.js

var Schema = mongoose.Schema,
    ObjectId = Schema.ObjectId;

// avoid forward referencing
var PackageSchema = new Schema();
var FlashcardSchema = new Schema();

PackageSchema.add({
    id          : ObjectId,
    title       : { type: String, required: true },
    flashcards  : [ FlashcardSchema ]
});

FlashcardSchema.add({
    id      : ObjectId,
    type        : { type: String, default: '' },
    story       : { type: String, default: '' },
    packages    : [ PackageSchema ]
});

// Exports both types
module.exports = {
    Package:   mongoose.model('Package', PackageSchema),
    Flashcard: mongoose.model('Flashcard', FlashcardSchema)
};  

Ответ 5

https://www.npmjs.com/package/mongoose-relationship

##Many-To-Many with Multiple paths

var mongoose = require("mongoose"),
    Schema = mongoose.Schema,
    relationship = require("mongoose-relationship");

var ParentSchema = new Schema({
    children:[{ type:Schema.ObjectId, ref:"Child" }]
});
var Parent = mongoose.models("Parent", ParentSchema);

var OtherParentSchema = new Schema({
    children:[{ type:Schema.ObjectId, ref:"Child" }]
});
var OtherParent = mongoose.models("OtherParent", OtherParentSchema);

var ChildSchema = new Schema({
    parents: [{ type:Schema.ObjectId, ref:"Parent", childPath:"children" }]
    otherParents: [{ type:Schema.ObjectId, ref:"OtherParent", childPath:"children" }]
});
ChildSchema.plugin(relationship, { relationshipPathName:['parents', 'otherParents'] });
var Child = mongoose.models("Child", ChildSchema)

var parent = new Parent({});
parent.save();
var otherParent = new OtherParent({});
otherParent.save();

var child = new Child({});
child.parents.push(parent);
child.otherParents.push(otherParent);
child.save() //both parent and otherParent children property will now contain the child id 
child.remove()