53

我的设计中有 FlashcardSchemas 和 PackageSchemas。一个抽认卡可以属于不同的包,一个包可以包含不同的抽认卡。

下面你可以看到我的猫鼬模式定义的精简版本:

// 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。如何映射与猫鼬的多对多关系?

4

6 回答 6

199

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

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

于 2013-04-14T16:55:38.350 回答
6

你这样做是正确的,但问题是你必须在 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 ]
});
于 2012-06-21T10:43:07.560 回答
2

您可以使用 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)
};  
于 2012-12-21T13:29:25.470 回答
0

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

如果做不到这一点,那么是的,可以使用第三个模式,但不要忘记它仍然只是每个对象的 id(没有连接,记住)所以你仍然必须在单独的查询中检索其他项目.

于 2012-06-21T09:52:41.177 回答
0
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's id 
child.remove() 
于 2015-12-03T17:49:27.980 回答
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;

于 2018-08-07T20:01:50.437 回答