理解猫鼬中的关系和外键

Jie*_*eng 19 join foreign-keys mongoose mongodb

在MongoDB/Mongoose中,如何定义关系?我想我见过几种方法,但我不确定我是否理解这些差异或何时使用哪种方式.我正在使用Mongoose 3

我已经定义TodoTodoList模型,关系是显而易见的.所以按照文档http://mongoosejs.com/docs/documents.html,我已经定义了类:

# Todo.coffee
mongoose = require "mongoose"

todoSchema = mongoose.Schema
    name: String
    desc: String
    dueOn: Date
    completedOn: Date

module.exports = mongoose.model "Todo", todoSchema

# TodoList.coffee

mongoose = require "mongoose"
Todo = require "./Todo"

todoListSchema = mongoose.Schema
    name: String
    todos: [Todo.schema]

module.exports = mongoose.model "TodoList", todoListSchema
Run Code Online (Sandbox Code Playgroud)

然后我尝试测试这些类:

list = new TodoList
    name: "List 1"
    todos: [
        { name: "Todo 1", desc: "Hello", dueOn: new Date(2012,10,1), completedOn: new Date(2012,10,2) }
        { name: "Todo 2" }
        { name: "Todo 3", desc: "Hello 2", dueOn: new Date(2012,10,6), completedOn: new Date(2012,10,2) }
        { name: "Todo 4" }
    ]
#list.todos.push { name: "Todo 5" }
console.log "List", list
list.save (err) ->
    if !err
        TodoList.find {}, (err, lists) ->
            console.log "TODOS"
            console.log lists.length, lists
            done(err)
    else 
        console.log "ERROR!!!"
        done err
Run Code Online (Sandbox Code Playgroud)

当我尝试做什么时Todo.find()我什么也得不到,所以Model(Todo.coffee)有点多余?它看起来像Todo存储在TodoList,作为一个用户我可能不在乎,但我想知道有什么影响?例如.文件会变得太大吗?1 TodoList有太多Todos?那有关系吗?如果我允许嵌套Todos(不是我想仅仅为了理解而做),那么分别存储文件会更好吗?如果我愿意,我该怎么做?我什么时候做?

我看到另一种方法,实际上是在Mongoose 2中,如果它可能在3中,那就是使用ObjectId而不是使用嵌套文档.也许这是分开存储?

Zac*_*bit 36

我还是Node,Mongoose和Mongo的新手,但我想我至少可以解决你的部分问题.:)

您当前的方法与我最初尝试的方法相同.基本上,它最终存储它与此非常相似(用JS编写,因为我不知道CoffeeScript):

var todoListSchema = new mongoose.Schema({
    name: String,
    todos: [{
        name: String,
        desc: String,
        dueOn: Date,
        completedOn: Date
    }]
});
Run Code Online (Sandbox Code Playgroud)

我后来找到了这个方法,这就是我想要的,我想你想要的是什么:

var todoListSchema = new mongoose.Schema({
    name: String,
    todos: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Todo' //Edit: I'd put the schema. Silly me.
    }]
});
Run Code Online (Sandbox Code Playgroud)

这将存储一个ObjectIds数组,然后您可以Query#populate在Mongoose中加载它们.

我不知道技术含义,但如果我将它们分开,我的大脑会更有意义,这就是我正在做的事情.:)

编辑:以下是一些可能有用的官方文档:http://mongoosejs.com/docs/populate.html

  • Schema.Types.ObjectId具有v2兼容版本:Schema.ObjectId; 这让我困惑了一会儿 (4认同)