MongoDB aggregation$project是否减少了要保存在内存中的数据量?
我想知道在MongoDB aggregation$project是否减少了要保存在内存中的数据量?,mongodb,performance,mongoose,aggregation-framework,Mongodb,Performance,Mongoose,Aggregation Framework,我想知道在$match语句之后编写$project是否会减少内存中要保存的数据量。例如,如果我们希望从用户文档中获得具有分页的数组元素,如下所示: const skip = 20; const limit = 50; UserModel.aggregate([ { $match: { _id: userId } }, { $project: { _id: 0, postList: 1 } }, { $slice: ["$p
$match
语句之后编写$project
是否会减少内存中要保存的数据量。例如,如果我们希望从用户文档中获得具有分页的数组元素,如下所示:
const skip = 20;
const limit = 50;
UserModel.aggregate([
{ $match: { _id: userId } },
{ $project: { _id: 0, postList: 1 } },
{ $slice: ["$postList", skip, limit] },
{ $lookup: ...
]);
假设用户文档中还有其他列表,并且它们的大小非常大
因此,
$project
是否有助于通过不在内存中获取其他大型列表来提高性能?每个聚合阶段都会扫描集合(如果是第一阶段)或前一阶段的输入文档。比如说,
- 匹配(过滤文档)-这将减少 文档的总体大小
- 项目(转换或塑造文档)-这可以减少(或 增加)文件的大小;文件的数量仍然存在 同样的
- 组-减少文档数量并更改大小
- 跳过,限制-减少文档数量
- 排序-文档的大小或数量没有变化, 等等
{allowDiskuse:true}
,此选项的使用将影响查询性能。如果聚合工作时没有任何与内存相关的问题(如由于超出内存限制而导致查询终止),则查询性能不会直接出现问题
如果在管道早期使用,$match
和$sort
阶段使用索引。这可以提高性能
向管道中添加阶段意味着额外的处理,并且会影响整体性能。这是因为前一阶段的文档必须经过这个额外的阶段。在聚合管道中,文档通过每个阶段传递,就像在管道中一样,该阶段执行一些数据转换。如果您可以避免某个阶段,那么它有时会有利于整体查询性能。当数量很大时,有一个额外的(不必要的)阶段肯定是一个缺点。您必须同时考虑内存限制以及文档的大小和数量
$project
可用于减小文档的大小。但是,有必要增加这个阶段吗?这取决于我上面提到的因素以及您的实施和应用。文件()说:
聚合管道可以确定它是否只需要
用于获取结果的文档中的字段。若有,管道
将只使用那些必需的字段,从而减少数据量
通过管道
$project
不会提高/降低性能。它用于包括
、排除
和转换
数据。只有当结果集中的任何文档超过16Mb时,MongoDB才会失败。看一看,如果我在管道的最后阶段使用$project来转换结果,而不是在开始时,那么它不会影响性能?e、 g.如果用户文档中有一个大小为10000的关注者列表,我只想释放大小为100的帖子列表。聚合阶段为:1.匹配_id2.使用查找在用户模型中填充不同字段(如标记的用户),3.投影帖子列表。在第二步中只投影帖子列表不就可以减少查找前的内存消耗吗?将MongoDB想象成loop
。您可以用汤完全填满它,也可以稍微填满一点,您是否会增加/减少勺子
性能?在我的情况下,在$match
之后的后续管道阶段中仅使用postList
,因此我在第二阶段仅添加到项目postList
。但正如你所描述的(我从你的描述中的理解是),我不需要自己做这件事。管道优化自动为我做到这一点。我说的对吗?在这种情况下,比赛和项目提前进行是一个优势。匹配阶段减少了要处理的文档数量。该项目减小了文档的大小。由于这两个阶段都是如此,因此对管道进行了优化。在应用程序中,投影将字段限制为一个,这一点很重要(这是必需的,而不是额外的阶段)。查询优化器可能会做进一步的优化(我不知道它是什么),因为您也在使用其他阶段,如skip、limit等。