0

我正在尝试建立一个类似于 Yahoo & Answer 或 StackOverflow 的网站(不同的类别,没有竞争),我被困在这一点上,我非常感谢你们的任何指导,因为我对 MongoDB 非常陌生.

顺便说一下,我在 Node.js 和 MongoDB 上使用 Express 框架。

问题是找到为用户和问题/答案数据构建数据库的最有效方法。

目前,有一个 Questions 模型,里面每个类别都有一个文档。每个文档都包含问题本身、答案和其他信息,如下所述:

math{
    OpenQuestions{
        'x+2=5, whats x?' : {
            asker: 'peter',
            likes: 12,
            answers: {
                'x is 3' : {
                    answerer: 'john',
                    likes: 25
                },
                'x is 2' : {
                    answerer: 'MATHSUX',
                    likes: 0
                }   
            }
        }
    }
    ClosedQuestions{
        //same as OpenQuestions
    }
}

通过这种方式显示问题非常容易,因为我们可以根据对象的创建时间轻松检索问题并在主问题页面上相应地获取它们。

但是,如果用户想查看他提出的问题,我能想到的唯一方法是遍历每个subject.OpenQuestions.QuestionItSelf.asker,并检查是否是用户本人,然后获取该用户名的所有对象匹配,这将是一个巨大的计算. 我相信还有更好的方法,你们觉得呢?

4

2 回答 2

1

MongoDB 每个文档的大小限制为 16MB。此外,当您的文档变大时,MongoDB 的表现也不是很好。出于性能原因,MongoDB 尝试将文档保存在硬盘驱动器的连续部分中,因此当文档增长时,需要不断地重新分配硬盘空间。

由于这些原因,将所有问题存储在一个文档中并不是一个好主意。

最好创建一个问题集合并为每个问题提供一个单独的文档。为了提高搜索性能,您可以创建一些适当的索引

顺便说一句:我不确定 MongoDB 是否适合您的项目。您的应用程序听起来非常相关,并且不像它可以从 MongoDB 的面向文档的概念中受益。另一方面,你的分层思维方式听起来更符合Redis哲学。但这只是主观意见。

于 2013-08-18T12:17:23.893 回答
1

首先,将问题作为关键是一个坏主意。创建一个question属性并将该属性的值作为问题的文本。MongoDB 没有太多用于查询键值的工具。几乎你所拥有的就是$exists,甚至不支持通配符。对每个答案做同样的事情,而不是让答案的文本成为一个键,有一个answer键并让值成为答案的文本。

接下来,没有理由将所有问题都保留为子文档。您可以将状态移动到文档的属性(例如状态:“打开”或状态:“关闭”或状态:“已回答但未关闭”)。如果您需要预先计算状态 - 将答案作为子文档可能更有意义,然后您可以根据答案的状态得出状态(即,如果问题没有任何答案都显示为未回答,如果有答案但没有答案标记为解决方案,则已回答但未解决,如果答案标记为解决方案则关闭,等等)。

然后,让主题成为问题的属性,而不是每个主题的集合。如果你这样做,那么为提问者寻找问题就像

db.questions.find({asker: 'John'}, {question:1, _id:0})

这将显示约翰提出的所有问题的文本

您的最终架构将是一个问题集合,其文档结构如下所示:

    {
        question: 'x+2=5, whats x?'
        asker: 'peter',
        likes: 12,
        subject: 'math',
        answers: [
            { answer: 'x is 3', answerer: 'john', likes: 25, solution: true },
            { answer: 'x is 2', answerer: 'MATHSUX', likes: 0}
        ],
        status: 'solved'
    }
于 2013-08-18T16:48:31.540 回答