使用Mongoose进行多对多映射

时间:2012-06-20 10:42:25

标签: node.js mongodb 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。如何与mongoose映射多对多关系?

6 个答案:

答案 0 :(得分:155)

我是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'} ]
});

这样,您只存储对象引用而不是嵌入对象。

答案 1 :(得分:3)

您正在以正确的方式执行此操作,但问题是您必须在flashcard-schema.js中包含PackageSchema,反之亦然。否则这些文件不知道你在引用什么

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 :(得分:1)

您可以使用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)
};  

答案 3 :(得分:0)

您认为这太像关系数据存储了。如果这是您想要的,请使用MySQL(或其他RDBMS)

如果失败了,那么是的,可以使用第三个模式,但不要忘记它仍然只是每个对象的id(没有连接,记住)所以你仍然需要检索彼此的项目一个单独的查询。

答案 4 :(得分:0)

ft_min_word_Len

答案 5 :(得分:0)

这是循环/循环依赖的问题。这就是使它在nodejs中工作的方式。有关更多详细信息,请参见http://exploringjs.com/es6/ch_modules.html#sec_modules-in-javascript

的“ CommonJS中的循环依赖关系”

//------ a.js ------
var b = require('b');
function foo() {
    b.bar();
}
exports.foo = foo;

//------ b.js ------
var a = require('a'); // (i)
function bar() {
    if (Math.random()) {
        a.foo(); // (ii)
    }
}
exports.bar = bar;