如何建模MongoDB数据库以有效地显示给定数组字段的值集

时间:2014-02-15 12:14:53

标签: mongodb

让我们假设我们想为一个存储有关图书数据的应用程序设计一个MongoDB数据库。

每本书都有很多标签:

Book = {
    title,       // String
    description, // String
    tags: []     // Array of String
}

我想要一个页面,我可以在其中列出所有标签(可能有数万个标签)并将其分页。

运行查询以聚合所有图书的所有标记集并在用户想要查看此页面时消除重复项是低效的。

如何设计我的数据库以使上述场景高效且响应迅速?

P.S:理想情况下,我不喜欢有一个Topic集合来解决这个问题。

2 个答案:

答案 0 :(得分:2)

以下查询将为您提供已排序的所有不同标记:

db.books.distinct("tags", {}).sort({tags : 1});

但是,要使其高效,您需要索引标记字段。这样,索引将用于获取和排序结果。

db.books.ensureIndex({tags: 1});

正如您在文档(http://docs.mongodb.org/manual/reference/method/db.collection.distinct/)中看到的那样,不同的操作将使用索引(如果可用),如果它像您的情况一样被覆盖,甚至更好。

答案 1 :(得分:0)

我认为,解决方案之一可能如下所示:

Book = {
    title,       // String
    description, // String
    tags: []     // Array of String (Tag names)
}

Tag = {
    name         // String
}
标签的

name应该是唯一的,因此如果用户添加新书并为其添加一些标记,您可以在Tags集合中找到此标记,如果此标记存在,则添加name到Book文档中的tags数组,如果此标记不存在,则将其添加到Tags集合中,并将其name添加到Book文档中的tags数组中。当用户点击某个标签查看所有相关图书时,您应该会在tags数组中找到所有带有此标记的图书。此外,您可以使用_id字段作为标记名称,并使用String而不是ObjectId。

另一种解决方案:

Book = {
    title,       // String
    description  // String
}

Tag = {
    name,        // String
    books: []    // Array of books titles or ids
}

在这种情况下,当用户添加一些书籍和标签时,您应该在标签集合中找到此标签,如果该标签不存在则创建该标签,然后在此标签中将书籍_id添加到books数组文献。当用户点击某个标签查看所有相关图书时,您可以在标记文档中找到所有使用books数组的图书。