mongodb的聚合函数的$skip + $limit 方法运用 和 顺序优化。

本文介绍MongoDB中聚合管道的优化技巧,特别是针对$skip和$limit操作符的使用顺序进行优化,以提高查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://docs.mongoing.com/manual-zh/core/aggregation-pipeline-optimization.html

$skip + $limit 顺序优化

如果你的管道中, $skip 后面跟着 $limit ,优化器会把 $limit 移到 $skip 前面,这个时候,$limit 的值会加上 $skip 的个数。

例如,如果管道由以下部分组成:

{ $skip: 10 },
{ $limit: 5 }

During the optimization phase, the optimizer transforms the sequence to the following:

{ $limit: 15 },
{ $skip: 10 }

对于类似 $sort + $limit 合并 ,例如 $sort + $skip + $limit ,优化器允许你做很多优化。详情请查看 $sort + $limit 合并 ,也可以在 $sort + $skip + $limit 顺序 中查看例子。

对于在 分片集合上的聚合 ,优化器可以减少从每个分片返回的文档个数。



1、db.memos.find({})
查询memos文档结果;

2、db.memos.aggregate({$skip:3})
跳过查询结果前三行;

3、db.memos.aggregate({$limit:3})

获取查询结果前三行;


1、db.memos.find({})如下:


    "_id" : 1.0, 
    "name" : "sue", 
    "age" : 19.0, 
    "type" : 1.0, 
    "status" : "P", 
    "favorites" : {
        "artist" : "Picasso", 
        "food" : "pizza"
    }, 
    "finished" : [
        17.0, 
        3.0
    ], 
    "badges" : [
        "blue", 
        "black"
    ], 
    "points" : [
        {
            "points" : 85.0, 
            "bonus" : 20.0
        }, 
        {
            "points" : 85.0, 
            "bonus" : 10.0
        }
    ]
}

    "_id" : 6.0, 
    "name" : "abc", 
    "age" : 43.0, 
    "type" : 1.0, 
    "status" : "A", 
    "favorites" : {
        "food" : "pizza", 
        "artist" : "Picasso"
    }, 
    "finished" : [
        18.0, 
        12.0
    ], 
    "badges" : [
        "black", 
        "blue"
    ], 
    "points" : [
        {
            "points" : 78.0, 
            "bonus" : 8.0
        }, 
        {
            "points" : 57.0, 
            "bonus" : 7.0
        }
    ]
}

    "_id" : 7.0, 
    "name" : "abc", 
    "age" : 43.0, 
    "type" : 1.0, 
    "status" : "A", 
    "favorites" : {
        "food" : "pizza", 
        "artist" : "Picasso"
    }, 
    "finished" : [
        21.0, 
        14.0
    ], 
    "badges" : [
        "black", 
        "blue"
    ], 
    "points" : [
        {
            "points" : 78.0, 
            "bonus" : 8.0
        }, 
        {
            "points" : 57.0, 
            "bonus" : 7.0
        }
    ]
}

    "_id" : 8.0, 
    "name" : "sue", 
    "age" : 49.0, 
    "type" : 1.0, 
    "status" : "P", 
    "favorites" : {
        "artist" : "Picasso", 
        "food" : "pizza"
    }, 
    "finished" : [
        17.0, 
        3.0
    ], 
    "badges" : [
        "blue", 
        "black"
    ], 
    "points" : [
        {
            "points" : 85.0, 
            "bonus" : 20.0
        }, 
        {
            "points" : 85.0, 
            "bonus" : 10.0
        }
    ]
}

    "_id" : 9.0, 
    "name" : "sue", 
    "age" : 19.0, 
    "type" : 1.0, 
    "status" : "P", 
    "favorites" : {
        "artist" : "Picasso", 
        "food" : "pizza"
    }, 
    "finished" : [
        17.0, 
        3.0
    ], 
    "badges" : [
        "blue", 
        "black"
    ], 
    "points" : [
        {
            "points" : 85.0, 
            "bonus" : 20.0
        }, 
        {
            "points" : 85.0, 
            "bonus" : 10.0
        }
    ]
}

    "_id" : 10.0, 
    "name" : "abc", 
    "age" : 43.0, 
    "type" : 1.0, 
    "status" : "A", 
    "favorites" : {
        "food" : "pizza", 
        "artist" : "Picasso"
    }, 
    "finished" : [
        18.0, 
        12.0
    ], 
    "badges" : [
        "black", 
        "blue"
    ], 
    "points" : [
        {
            "points" : 78.0, 
            "bonus" : 8.0
        }, 
        {
            "points" : 57.0, 
            "bonus" : 7.0
        }
    ]
}

    "_id" : 11.0, 
    "name" : "abc", 
    "age" : 43.0, 
    "type" : 1.0, 
    "status" : "A", 
    "favorites" : {
        "food" : "pizza", 
        "artist" : "Picasso"
    }, 
    "finished" : [
        21.0, 
        14.0
    ], 
    "badges" : [
        "black", 
        "blue"
    ], 
    "points" : [
        {
            "points" : 78.0, 
            "bonus" : 8.0
        }, 
        {
            "points" : 57.0, 
            "bonus" : 7.0
        }
    ]
}

    "_id" : 12.0, 
    "name" : "sue", 
    "age" : 49.0, 
    "type" : 1.0, 
    "status" : "P", 
    "favorites" : {
        "artist" : "Picasso", 
        "food" : "pizza"
    }, 
    "finished" : [
        17.0, 
        3.0
    ], 
    "badges" : [
        "blue", 
        "black"
    ], 
    "points" : [
        {
            "points" : 85.0, 
            "bonus" : 20.0
        }, 
        {
            "points" : 85.0, 
            "bonus" : 10.0
        }
    ]
}

### MongoDB 聚合函数概述 MongoDB 提供了多种方式来进行复杂的数据处理分析,其中最常用的是聚合框架。该框架允许用户定义一系列的操作阶段(pipeline stages),这些阶段可以依次对输入文档进行转换、过滤其他形式的加工[^1]。 #### 聚合管道 (Aggregation Pipeline) 聚合管道由多个阶段组成,每个阶段都会接收前一阶段的结果并对其进行进一步处理。常见的操作有 `$match` 用于筛选符合条件的记录;`$group` 可以按照指定字段分组并对每组应用累积表达式计算总或其他统计数据;还有 `$sort`, `$skip`, `$limit` 等用来控制输出顺序以及数量限制等功能[^2]。 #### 单一目的聚合方法 除了完整的聚合管道外,MongoDB 还支持一些简单的内置命令来完成特定的任务,比如 `count()` 计算集合中文档的数量,或是 `distinct()` 获取某个字段的不同取值列表。这类方法通常更简单易用,在不需要构建多步流程的情况下非常方便。 #### Java 中使用 Aggregation Framework 实现示例 下面是一个基于 Spring Data MongoDB 的例子,展示了如何利用 Java 编程语言调用 MongoDB聚合功能: ```java // 定义聚合条件 Criteria criteria = Criteria.where("author").is("John Doe"); MatchOperation matchStage = Aggregation.match(criteria); GroupOperation groupByCategoryAndCount = Aggregation.group("category") .count().as("total"); ProjectionOperation projectFields = Aggregation.project() .andExpression("_id").as("categoryName") .andExpression("total").as("numberOfPosts"); SortOperation sortTotalDesc = Aggregation.sort(Sort.Direction.DESC, "total"); Aggregation agg = Aggregation.newAggregation( matchStage, groupByCategoryAndCount, projectFields, sortTotalDesc ); // 执行聚合查询 AggregationResults<JSONObject> results = mongoTemplate.aggregate(agg, "posts", JSONObject.class); List<JSONObject> resultList = results.getMappedResults(); ``` 这段代码实现了如下逻辑:先匹配作者名为 John Doe 的文章,接着按类别汇总各分类下的帖子数目,并投影出新的结构只保留必要的信息最后依据总数降序排列结果集[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值