我想设计一个带有一些评论的问题结构。注释应该使用哪种关系:嵌入还是引用?

一个带有注释的问题,比如stackoverflow,会有这样的结构:

Question
    title = 'aaa'
    content = 'bbb'
    comments = ???

一开始,我想使用嵌入式注释(我认为MongoDB中推荐使用embed),像这样:

Question
    title = 'aaa'
    content = 'bbb'
    comments = [ { content = 'xxx', createdAt = 'yyy'}, 
                 { content = 'xxx', createdAt = 'yyy'}, 
                 { content = 'xxx', createdAt = 'yyy'} ]

这很清楚,但我担心这种情况:如果我想编辑一个指定的评论,我如何获得它的内容和它的问题?没有_id让我找到一个,也没有question_ref让我找到它的问题。(也许有一种方法可以做到这一点没有_id和question_ref?)

我必须使用ref而不是embed吗?然后我必须为评论创建一个新的集合吗?


当前回答

好吧,我有点晚了,但仍然想分享我的模式创建方法。

我有可以用一个词描述的所有事物的模式,就像在经典的OOP中那样。

E.G.

评论 账户 用户 博客 ...

每个模式都可以保存为Document或Subdocument,因此我对每个模式都声明了这一点。

文档:

可以作为参考。(例如,用户做了一个评论->评论有一个“由”的参考用户) 是应用程序中的“根”。(例如,博客文章->有一个关于博客文章的页面)

子文档:

只能使用一次/绝不是参考。(例如,评论保存在博客文章中) 在应用程序中从来都不是“根”。(评论只在博客页面中显示,但页面仍然是关于博客的)

其他回答

如果我想编辑一个指定的评论,我如何获得它的内容和 它的问题吗?

如果您已经记录了注释的数量和想要修改的注释的索引,那么您可以使用点操作符(SO示例)。

你可以用f.ex。

db.questions.update(
    {
        "title": "aaa"       
    }, 
    { 
        "comments.0.contents": "new text"
    }
)

(作为另一种编辑问题内评论的方式)

我在自己研究这个问题的时候看到了这个小演示。我惊讶于它的布局之好,无论是信息还是呈现方式。

http://openmymind.net/Multiple-Collections-Versus-Embedded-Documents

总结:

作为一般规则,如果您有很多[子文档]或它们很大,那么单独的集合可能是最好的。 更小和/或更少的文档往往更适合嵌入。

好吧,我有点晚了,但仍然想分享我的模式创建方法。

我有可以用一个词描述的所有事物的模式,就像在经典的OOP中那样。

E.G.

评论 账户 用户 博客 ...

每个模式都可以保存为Document或Subdocument,因此我对每个模式都声明了这一点。

文档:

可以作为参考。(例如,用户做了一个评论->评论有一个“由”的参考用户) 是应用程序中的“根”。(例如,博客文章->有一个关于博客文章的页面)

子文档:

只能使用一次/绝不是参考。(例如,评论保存在博客文章中) 在应用程序中从来都不是“根”。(评论只在博客页面中显示,但页面仍然是关于博客的)

一般来说,如果实体之间有一对一或一对多的关系,则嵌入是很好的选择;如果实体之间有多对多的关系,则引用是很好的选择。

是的,我们可以使用文件中的参考资料。就像SQL i连接一样填充另一个文档。在MongoDB中,它们没有连接来将一个关系文档映射到多个关系文档。相反,我们可以使用populate来实现我们的场景。

var mongoose = require('mongoose')
  , Schema = mongoose.Schema
  
var personSchema = Schema({
  _id     : Number,
  name    : String,
  age     : Number,
  stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});

var storySchema = Schema({
  _creator : { type: Number, ref: 'Person' },
  title    : String,
  fans     : [{ type: Number, ref: 'Person' }]
});

填充是自动用其他集合中的文档替换文档中的指定路径的过程。我们可以填充单个文档、多个文档、普通对象、多个普通对象或从查询返回的所有对象。让我们来看一些例子。

更多信息请访问:http://mongoosejs.com/docs/populate.html