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

一个带有注释的问题,比如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吗?然后我必须为评论创建一个新的集合吗?


当前回答

我知道这是相当古老的,但如果你正在寻找OP关于如何只返回指定注释的问题的答案,你可以像这样使用$(查询)操作符:

db.question.update({'comments.content': 'xxx'}, {'comments.$': true})

其他回答

实际上,我很好奇为什么没有人谈论UML规范。经验法则是,如果您有一个聚合,那么您应该使用引用。但如果它是一个组合,那么耦合更强,您应该使用嵌入式文档。

你很快就会明白为什么这是合乎逻辑的。如果一个对象可以独立于父对象而存在,那么即使父对象不存在,您也会希望访问它。因为不能将它嵌入到不存在的父节点中,所以必须让它活在自己的数据结构中。如果存在父对象,只需通过在父对象中添加对象的引用将它们链接在一起。

不知道这两种关系有什么区别? 下面是一个解释它们的链接: UML中的聚合与组合

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

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

E.G.

评论 账户 用户 博客 ...

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

文档:

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

子文档:

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

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

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

你可以用f.ex。

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

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

我知道这是相当古老的,但如果你正在寻找OP关于如何只返回指定注释的问题的答案,你可以像这样使用$(查询)操作符:

db.question.update({'comments.content': 'xxx'}, {'comments.$': true})

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

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

总结:

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