PHP - mongodb 客户端 - 跳过和限制使用
Posted
技术标签:
【中文标题】PHP - mongodb 客户端 - 跳过和限制使用【英文标题】:PHP - mongodb client - skip and limit usage 【发布时间】:2013-04-04 15:47:16 【问题描述】:可能这是一个愚蠢的问题,但无论如何我有疑问。
请看一下这个查询:
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
【问题讨论】:
【参考方案1】:现在的问题是:当我明确要求跳过 1750 时,为什么 mongodb 会返回 1760 文档?
因为服务器端 skip()
正是这样做的:它迭代前 1750 个结果,然后再获得 10 个结果(根据限制)。
正如@devesh 所说,这就是为什么应该避免非常大的分页,因为 MongoDB 没有有效地使用 skip()
或 limit()
的索引。
【讨论】:
【参考方案2】:我认为你已经中了靶心,我认为这就是为什么 mongoDB 文档要求我们避免大跳过 http://docs.mongodb.org/manual/reference/method/cursor.skip/ 的原因。请看这里它会回答你的结果。使用将与 $gt 运算符一起使用的其他键会快得多。就像第 1 页中最后一个键的日期时间戳一样,然后在日期时间上使用 $get。
cursor.skip() 方法通常代价高昂,因为它需要服务器从集合或索引的开头步行以获取偏移或跳过位置,然后再开始返回结果
【讨论】:
我不能使用 Datetime,因为它是一个博客。当发布新帖子时,所有现有帖子,其日期时间只是“转移”。即使我直接转到 page/200 我也不知道第一次发布此页面的日期时间。以上是关于PHP - mongodb 客户端 - 跳过和限制使用的主要内容,如果未能解决你的问题,请参考以下文章