【问题标题】:limit(1).skip(1) : Why does it return second document and not nothing?limit(1).skip(1) :为什么它返回第二个文档而不是什么?
【发布时间】:2016-01-03 03:06:33
【问题描述】:

我是 mongodb 的新手,所以请多多包涵。我用谷歌搜索了这个,但找不到令人信服的答案。 我了解以下内容应限制结果中的 n1 个文档并跳过其中的 n2 个。

>db.mycol.find({},{"title":1}).limit(n1).skip(n2)

为什么下面的查询应该返回集合中的第二个文档?它不应该什么都不返回吗? (限制一个给出第一个文档并跳过这让我们一无所获)。

>db.mycol.find({},{"title":1}).limit(1).skip(1)

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    当你把limit 放在skip 之前,你想做什么?

    如果你限制N元素然后跳过K

    这在逻辑上等同于跳过K 并限制N-K

    我想优化器也知道这一点,并期望你也一样。

    pipeline optimization

    【讨论】:

    • 我只是在玩命令,但这很有趣,谢谢!
    • 这应该也意味着limit(1).skip(1)变成skip(1).limit(0)吧?
    • 我怀疑,根据规格它不会改变。
    【解决方案2】:

    我了解以下内容应限制结果中的 n1 个文档并跳过其中的 n2 个

    不,你搞错了。这是发生了什么:

    1. 您的查询由查询优化器处理,它会将.sort().skip().limit() 放入正是这个顺序
    2. 通过使用索引或集合扫描来识别要返回的文档
    3. 现在它们根据.sort() 子句的参数(如果存在)进行排序
    4. 根据.skip() 子句的参数跳过该文档排序列表的第一个文档数。
    5. 现在,返回了与.limit() 子句参数相等的多个文档

    其实很容易证明:

    > db.bg.insert({a:1})
    WriteResult({ "nInserted" : 1 })
    > db.bg.insert({a:2})
    WriteResult({ "nInserted" : 1 })
    > db.bg.insert({a:3})
    WriteResult({ "nInserted" : 1 })
    > db.bg.insert({a:4})
    WriteResult({ "nInserted" : 1 })
    > db.bg.find()
    { "_id" : ObjectId("56889a8a32a39e5b2c96acb5"), "a" : 1 }
    { "_id" : ObjectId("56889a8d32a39e5b2c96acb6"), "a" : 2 }
    { "_id" : ObjectId("56889a9032a39e5b2c96acb7"), "a" : 3 }
    { "_id" : ObjectId("56889ad332a39e5b2c96acb8"), "a" : 4 }
    
    // According to your logic, this query would be empty
    // (Only one doc returned, and of that returned one skipped)
    // But it bears a result…
    > db.bg.find().sort({a:-1}).limit(1).skip(1)
    { "_id" : ObjectId("56889a9032a39e5b2c96acb7"), "a" : 3 }
    
    // …actually the same result when switching the place of the clauses
    > db.bg.find().sort({a:-1}).skip(1).limit(1)
    { "_id" : ObjectId("56889a9032a39e5b2c96acb7"), "a" : 3 }
    
    // Even when we put the sort clause to the end.
    // If the query optimizer would not have enforced the order mentioned
    // we would have natural order as in the default query,
    // then skip 1 (we would be at {a:2}),and limit to that document, making
    // the sort clause useless.
    // But, as you can see, it is the same result as before
    > db.bg.find().skip(1).limit(1).sort({a:-1})
    { "_id" : ObjectId("56889a9032a39e5b2c96acb7"), "a" : 3 }
    

    【讨论】:

      【解决方案3】:

      https://docs.mongodb.org/v3.0/reference/method/cursor.skip/

      NOTE
      You must apply cursor.skip() to the cursor before retrieving any documents from the database.
      

      而在查询结果时应用限制。

      因此 find 会查找所有符合条件的文档,并在检索文档之前应用 Skip 并检索限制中给出的文档数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多