Storing data fields that are related to each other but not accessed together can create bloated documents that lead to excessive RAM and bandwidth usage. 存储彼此相关但不能一起访问的数据字段会创建臃肿的文档,导致RAM和带宽的过度使用。The working set, consisting of frequently accessed data and indexes, is stored in the RAM allotment. When the working set fits in RAM, MongoDB can query from memory instead of from disk, which improves performance. 工作集由频繁访问的数据和索引组成,存储在RAM分配中。当工作集适合RAM时,MongoDB可以从内存而不是磁盘进行查询,从而提高了性能。However, if documents are too large, the working set might not fit into RAM, causing performance to degrade as MongoDB has to access data from disk.然而,如果文档太大,工作集可能无法装入RAM,导致性能下降,因为MongoDB必须从磁盘访问数据。
To prevent bloated documents, restructure your schema with smaller documents and use document references to separate fields that aren't returned together. This approach reduces the working set size and improves performance.为了防止文档膨胀,请用较小的文档重构架构,并使用文档引用来分隔不一起返回的字段。这种方法减少了工作集的大小并提高了性能。
About this Task关于此任务
Consider the following schema that contains book information used on a bookstore website's main page. The main page only displays the book title, author, and front cover image. You must click on the book to see additional details.考虑以下模式,其中包含书店网站主页上使用的书籍信息。主页只显示书名、作者和封面图片。你必须点击这本书才能看到更多细节。
{
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.
}
In the current schema, to display the information for the website's main page, all of the book information must be queried. To reduce document size and streamline queries, you can split the large document into two smaller collections.在当前模式中,要显示网站主页的信息,必须查询所有书籍信息。为了减小文档大小并简化查询,您可以将大文档拆分为两个较小的集合。
Example示例
In the following example, the book information is split into two collections: 在以下示例中,图书信息分为两个集合:mainBookInfo and additionalBookDetails.mainBookInfo和additionalBookDetails。
ThemainBookInfocollection contains the information displayed on the website's main page.mainBookInfo集合包含网站主页上显示的信息。TheadditionalBookDetailscollection contains extra details revealed after a user clicks on the book.additionalBookDetails集合包含用户点击书籍后显示的额外细节。
The mainBookInfo collection:mainBookInfo集合:
db.mainBookInfo.insertOne(
{
_id: 1234,
title: "Tale of Two Cities",
author: "Charles Dickens",
genre: "Historical Fiction",
cover_image: "<url>"
}
)
The additionalBookDetails collection: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."
}
)
The two collections are linked by the 这两个集合由_id field in the mainBookInfo collection and the bookId field in the additionalBookDetails collection. mainBookInfo集合中的_id字段和additionalBookDetails集合中的bookId字段链接。On the home page, only the 在主页上,只有mainBookInfo collection is used to provide the necessary information. mainBookInfo集合用于提供必要的信息。When a user selects a book to learn more about, the website queries the 当用户选择一本书以了解更多信息时,网站会使用additionalBookDetails collection using the _id field to match with the bookId field._id字段与bookId字段匹配来查询additionalBookDetails集合。
By splitting the information into two collections, you ensure that your documents do not grow too large and exceed RAM allotment.通过将信息拆分为两个集合,您可以确保文档不会变得太大,也不会超过RAM分配。
Join Collections with $lookup使用$lookup加入集合
To join the data from the 要连接mainBookInfo collection and the additionalBookDetails collection, the application needs to perform a $lookup operation.mainBookInfo集合和additionalBookDetails集合中的数据,应用程序需要执行$lookup操作。
The following aggregation operation joins the 以下聚合操作将前一个示例中的mainBookInfo and additionalBookDetails collection from the previous example.mainBookInfo和additionalBookDetails集合连接起来。
db.mainBookInfo.aggregate( [
{
$lookup: {
from: "additionalBookDetails",
localField: "_id",
foreignField: "bookId",
as: "details"
}
},
{
$replaceRoot: {
newRoot: { $mergeObjects: [ { $arrayElemAt: [ "$details", 0 ] }, "$$ROOT" ] }
}
},
{
$project: { details: 0 }
}
] )
The operation returns the following:该操作返回以下内容:
[
{
_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.'
}
]
In this example, the 在此示例中,$lookup operation joins the mainBookInfo collection with the additionalBookDetails collection using the _id and bookId fields. $lookup操作使用_id和bookId字段将mainBookInfo集合与additionalBookDetails集合连接起来。The $mergeObjects and $replaceRoot operations merge the joined documents from the mainBookInfo and additionalBookDetails collections.$mergeObjects和$replaceRoot操作合并了来自mainBookInfo和additionalBookDetails集合的已连接文档。