• 《MongoDB入门教程》第13篇 限制返回结果数量


    本篇我们学习 MongoDB 中的 limit() 方法,它可以限制查询返回的文档数量。

    limit() 方法

    find() 方法可能会查找出大量的文档,但是应用程序不一定需要所有的返回结果。为了限制返回文档的数量,可以使用 limit() 方法:

    db.collection.find(<query>).limit(<documentCount>)
    
    • 1

    其中, 的取值范围为 -2 31 到 231。如果指定了超出该范围的参数, limit() 返回的结果不确定。

    如果 指定了负数值,limit() 返回结果和对应正数参数的结果相同。另外,系统在返回一个批次的文档之后将会关闭游标。如果查询结果的数量不止一个批次,实际返回的结果数量将会小于指定的数量。

    如果将 设置为 0,相当于没有限制返回结果的数量。

    limit() 方法和 SQL 语句中的 LIMIT 子句作用类似。

    如果想要使用 limit() 方法获取确定内容的结果,需要先对结果进行排序:

    cursor
       .sort({...})
       .limit(<documentCount>)
    
    • 1
    • 2
    • 3

    在实际应用中,我们通常结合 limit() 和 skip() 方法实现分页功能。skip() 方法用于指定从哪一个文档开始返回结果:

    cursor.skip(<offset>)
    
    • 1

    以下语法用于返回第 pageNo 页中的文档,每页包含 documentCount 个文档:

    db.collection.find({...}
    ).sort({...}
    ).skip(pageNo > 0 ? ( ( pageNo - 1 ) * documentCount) : 0
    ).limit(documentCount);
    
    • 1
    • 2
    • 3
    • 4

    skip() 意味着 MongoDB 服务器需要从结果集中扫描并忽略指定数量的文档,然后开始返回结果。因此,随着 的增加,skip() 方法会越来越慢。

    limit() 和 skip() 方法和 SQL 中的 LIMIT OFFSET 子句作用类似。

    limit() 示例

    接下来的示例将会使用以下产品集合:

    db.products.insertMany([
        { "_id" : 1, "name" : "xPhone", "price" : 799, "releaseDate" : ISODate("2011-05-14T00:00:00Z"), "spec" : { "ram" : 4, "screen" : 6.5, "cpu" : 2.66 }, "color" : [ "white", "black" ], "storage" : [ 64, 128, 256 ] },
        { "_id" : 2, "name" : "xTablet", "price" : 899, "releaseDate" : ISODate("2011-09-01T00:00:00Z"), "spec" : { "ram" : 16, "screen" : 9.5, "cpu" : 3.66 }, "color" : [ "white", "black", "purple" ], "storage" : [ 128, 256, 512 ] },
        { "_id" : 3, "name" : "SmartTablet", "price" : 899, "releaseDate" : ISODate("2015-01-14T00:00:00Z"), "spec" : { "ram" : 12, "screen" : 9.7, "cpu" : 3.66 }, "color" : [ "blue" ], "storage" : [ 16, 64, 128 ] },
        { "_id" : 4, "name" : "SmartPad", "price" : 699, "releaseDate" : ISODate("2020-05-14T00:00:00Z"), "spec" : { "ram" : 8, "screen" : 9.7, "cpu" : 1.66 }, "color" : [ "white", "orange", "gold", "gray" ], "storage" : [ 128, 256, 1024 ] },
        { "_id" : 5, "name" : "SmartPhone", "price" : 599, "releaseDate" : ISODate("2022-09-14T00:00:00Z"), "spec" : { "ram" : 4, "screen" : 9.7, "cpu" : 1.66 }, "color" : [ "white", "orange", "gold", "gray" ], "storage" : [ 128, 256 ] },
        { "_id" : 6, "name" : "xWidget", "spec" : { "ram" : 64, "screen" : 9.7, "cpu" : 3.66 }, "color" : [ "black" ], "storage" : [ 1024 ] },
        { "_id" : 7, "name" : "xReader", "price" : null, "spec" : { "ram" : 64, "screen" : 6.7, "cpu" : 3.66 }, "color" : [ "black", "white" ], "storage" : [ 128 ] }
    ])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    示例一:查找最昂贵的产品

    以下示例使用 limit() 方法获取产品集合中最贵的产品,返回结果中包含了 _id、name 以及 price 字段:

    db.products.find({}, {
        name: 1,
        price: 1
    }).sort({
        price: -1
    }).limit(1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    查询返回的结果如下:

    [ { _id: 2, name: 'xTablet', price: 899 } ]
    
    • 1

    在示例中,我们按照价格从高到低对产品进行排序,然后使用 limit() 返回了排名第一的产品。产品集合中包含了 2 个价格为 899 的产品,因此返回的文档取决于它们在磁盘中的存储顺序。

    为了返回确定性的结果,排序结果必须具有唯一性。例如:

    db.products.find({}, {
        name: 1,
        price: 1
    }).sort({
        price: -1,
        name: 1
    }).limit(1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    查询返回的结果如下:

    [ { _id: 3, name: 'SmartTablet', price: 899 } ]
    
    • 1

    示例同时使用了价格和名称进行排序,当价格相同时按照名称升序进行排列,此时查询返回了确定的结果。

    示例二:实现分页查询功能

    假如我们想要将产品进行分页展示,每页显示 2 个产品。以下查询使用 skip() 和 limit() 方法获取了第 2 页中的文档:

    db.products.find({}, {
        name: 1,
        price: 1
    }).sort({
        price: -1,
        name: 1
    }).skip(2).limit(2);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    查询结果如下:

    [
      { _id: 1, name: 'xPhone', price: 799 },
      { _id: 4, name: 'SmartPad', price: 699 }
    ]
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    用VS开发一款“飞机大战“单机游戏<C++>
    Spring循环依赖
    C++ Reference: Standard C++ Library reference: C Library: cwchar: wcsstr
    7.3 服务端漏洞:密码找回逻辑漏洞检测和重现
    随手记面试录
    Spring创建Bean实例的方式
    @Transactional & @Aysnc & 循环依赖 & 事务同步问题
    梯度下降法总是在同一点收敛吗?
    MobaXterm如何连接CentOS7的Linux虚拟机?Redis可视化客户端工具如何连接Linux版Redis?
    如何拓展同城的客户群体?小魔推助力把握同城精准流量!
  • 原文地址:https://blog.csdn.net/horses/article/details/126740327