PHP - mongodb客户端 - 跳过并限制使用

时间:2013-04-04 15:47:16

标签: php mongodb profiling

可能这是一个愚蠢的问题,但无论如何我有疑问。

请查看此查询:

db.posts.find({ "blog": "myblog", 
                "post_author_id": 649, 
                "shares.total": { "$gt": 0 } })
        .limit(10)
        .skip(1750)
        .sort({ "shares.total": -1, "tstamp_published": -1 });

实际上我在这个报告中看到了mongodb profiler:

mongos> db.system.profile.find({ nreturned : { $gt : 1000 } }).limit(10).sort( { millis : 1 } ).pretty();
{
    "ts" : ISODate("2013-04-04T13:28:08.906Z"),
    "op" : "query",
    "ns" : "mydb.posts",
    "query" : {
        "$query" : {
            "blog" : "myblog",
            "post_author_id" : 649,
            "shares.total" : {
                "$gt" : 0
            }
        },
        "$orderby" : {
            "shares.total" : -1,
            "tstamp_published" : -1
        }
    },
    "ntoreturn" : 1760,
    "nscanned" : 12242,
    "scanAndOrder" : true,
    "nreturned" : 1760,
    "responseLength" : 7030522,
    "millis" : 126,
    "client" : "10.0.232.69",
    "user" : ""
}

现在的问题是:当我明确要求跳过1750时,为什么mongodb会返回1760个文件?

这是我当前的Mongodb版本,在群集/分片中。

mongos> db.runCommand("buildInfo")
{
    "version" : "2.0.2",
    "gitVersion" : "514b122d308928517f5841888ceaa4246a7f18e3",
    "sysInfo" : "Linux bs-linux64.10gen.cc 2.6.21.7-2.ec2.v1.2.fc8xen #1 SMP Fri Nov 20 17:48:28 EST 2009 x86_64 BOOST_LIB_VERSION=1_41",
    "versionArray" : [
        2,
        0,
        2,
        0
    ],
    "bits" : 64,
    "debug" : false,
    "maxBsonObjectSize" : 16777216,
    "ok" : 1
}

2 个答案:

答案 0 :(得分:1)

  

现在的问题是:当我明确要求跳过1750时,为什么mongodb会返回1760个文件?

因为服务器端skip()完全相同:它会迭代前1750个结果,然后再获得10个(根据限制)。

正如@devesh所说,这就是为什么应该避免非常大的分页,因为MongoDB没有有效地使用skip()limit()的索引。

答案 1 :(得分:0)

我认为你已经受到了冲击,我认为这是为什么mongoDB文件要求我们避免大跳过http://docs.mongodb.org/manual/reference/method/cursor.skip/的原因。请看看这里它会回答你的结果。使用一些将与$ gt运算符一起使用的其他键将更快。就像页面1中最后一个键的日期时间戳一样,然后在日期时间使用$ get。

  

cursor.skip()方法通常很昂贵,因为它要求服务器从集合或索引的开头走,以在开始返回结果之前获取偏移或跳过位置