膨胀文档
存储相关但未一起访问的数据字段可能会创建膨胀的文档,导致过度使用RAM和带宽。工作集,包括频繁访问的数据和索引,存储在RAM配额中。当工作集适合RAM时,MongoDB可以从内存而不是从磁盘查询,从而提高性能。然而,如果文档太大,工作集可能无法适应RAM,导致性能下降,因为MongoDB必须从磁盘访问数据。工作集,由频繁访问的数据和索引组成,存储在RAM配额中。当工作集适合RAM时,MongoDB可以从内存而不是从磁盘查询,从而提高性能。然而,如果文档太大,工作集可能无法适应RAM,导致性能下降,因为MongoDB必须从磁盘访问数据。
为了防止文档膨胀,使用较小的文档重构模式,并使用文档引用来分离不一起返回的字段。这种方法可以减少工作集大小并提高性能。
关于此任务
考虑以下模式,该模式包含在书店网站主页上使用的书籍信息。主页仅显示书籍标题、作者和封面图像。您必须点击书籍才能查看其他详细信息。
{ title: "Tale of Two Cities", author: "Charles Dickens", genre: "Historical Fiction", cover_image: "<url>", year: 1859, pages: 448, price: 15.99, description: "A historical novel set during the French Revolution. }
在当前模式中,要显示网站主页的信息,必须查询所有书籍信息。为了减少文档大小并简化查询,可以将大型文档拆分为两个较小的集合。
示例
在下面的示例中,书籍信息被分为两个集合mainBookInfo 和 additionalBookDetails。
mainBookInfo集合包含在网站主页上显示的信息。additionalBookDetails集合包含用户点击书籍后显示的额外细节。
mainBookInfo 集合
db.mainBookInfo.insertOne( { _id: 1234, title: "Tale of Two Cities", author: "Charles Dickens", genre: "Historical Fiction", cover_image: "<url>" } )
additionalBookDetails 集合
db.additionalBookDetails.insertOne( { title: "Tale of Two Cities", bookId: 1234, year: 1859, pages: 448, price: 15.99, description: "A historical novel set during the French Revolution." } )
这两个集合通过 mainBookInfo 集合中的 _id 字段和 additionalBookDetails 集合中的 bookId 字段相连接。在主页上,只使用 mainBookInfo 集合提供必要的信息。当用户选择一本书以了解更多信息时,网站使用 _id 字段来查询 additionalBookDetails 集合,并与 bookId 字段匹配。
通过将信息分为两个集合,您可以确保您的文档不会变得过大,从而超过 RAM 配额。
使用 $lookup 连接集合
为了连接来自 mainBookInfo 集合和 additionalBookDetails 集合的数据,应用程序需要执行 $lookup 操作。
以下聚合操作连接了先前的示例中的 mainBookInfo 和 additionalBookDetails 集合。
db.mainBookInfo.aggregate( [ { $lookup: { from: "additionalBookDetails", localField: "_id", foreignField: "bookId", as: "details" } }, { $replaceRoot: { newRoot: { $mergeObjects: [ { $arrayElemAt: [ "$details", 0 ] }, "$$ROOT" ] } } }, { $project: { details: 0 } } ] )
操作返回以下内容
[ { _id: ObjectId('666b1235eda086b5e22dbcf1'), title: 'Tale of Two Cities', author: 'Charles Dickens', genre: 'Historical Fiction', cover_image: '<url>', bookId: 1234, year: 1859, pages: 448, price: 15.99, description: 'A historical novel set during the French Revolution.' } ]
在本例中,$lookup 操作通过 _id 和 bookId 字段将 mainBookInfo 集合与 additionalBookDetails 集合并联。$mergeObjects 和 $replaceRoot 操作将来自 mainBookInfo 和 additionalBookDetails 集合的合并文档合并。