计算sorting分页给定logging的跳过值
我正在尝试使用PHP驱动程序来计算mongo db集合中给定logging的跳过值。 因此,拿一个给定的logging,找出整个集合内的logging索引。 这可能吗?
目前我正在select所有logging并手动对结果数组进行索引。
这被称为“向前分页”,这是一个概念,当使用“sorting”结果时,您可以使用这个概念在“向前”方向上通过结果进行“高效分页”。
包括JavaScript逻辑(因为它在shell中工作),但不难翻译。
一般概念:
{ "_id": 1, "a": 3 }, { "_id": 2, "a": 3 }, { "_id": 3, "a": 3 }, { "_id": 4, "a": 2 }, { "_id": 5, "a": 1 }, { "_id": 6, "a": 0 }
考虑这些“已经sorting”的文档(为了方便)作为我们希望通过每页“两个”项“页”的结果的示例。
首先,你做这样的事情:
var lastVal = null, lastSeen = []; db.collection.find().sort({ "a": -1 }).limit(2).forEach(function(doc) { if ( lastVal != doc.a ) { lastSeen = []; } lastVal = doc.a; lastSeen.push( doc._id ); // do something useful with each document matched });
现在,这些lastVal
和lastSeen
是你存储在类似于“会话variables”的东西,而不是在下一个请求中可以通过web应用程序访问的东西,或者其他类似的地方。
他们应该包含的是你正在sorting的最后一个值,以及自从该值没有改变以来看到的“唯一” _id
值列表。 因此:
lastVal = 3, lastSeen = [1,2];
关键是,当“下一页”的请求来了,那么你想要使用这些variables如下所示:
var lastVal = 3, lastSeen = [1,2]; db.collection.find({ "_id": { "$nin": lastSeen }, "a": { "$lte": lastVal } }).sort({ "a": -1 }).limit(2).forEach(function(doc) { if ( lastVal != doc.a ) { lastSeen = []; } lastVal = doc.a; lastSeen.push( doc._id ); // do something useful with each document matched });
所做的就是从结果列表中“排除” lastSeen
中logging的_id
所有值,并确保所有结果都必须是“小于或等于”(降序) lastVal
logging的sorting字段“a”。
这会产生集合中的下两个结果:
{ "_id": 3, "a": 3 }, { "_id": 4, "a": 2 },
但处理完后我们的价值如下所示:
lastVal = 2, lastSeen = [4];
所以现在的逻辑是,你不需要排除之前看到的其他_id
值,因为你只是真的在寻找“a”的值而不是“小于或等于” lastVal
,因为只有“一个”在这个值看到的_id
值只能排除那个值。
这当然会产生使用上面相同代码的下一页:
{ "_id": 5, "a": 1 }, { "_id": 6, "a": 0 }
这是通过一般结果“向前翻页”最有效的方法,对于“sorting”结果的有效分页特别有用。
但是,如果你想在任何阶段跳到第20
页或类似的行动,那么这不适合你。 你被传统的.skip()
和.limit()
方法所困,因为没有其他合理的方法来“计算”这个。
所以这一切都取决于你的应用程序是如何实现“分页”以及你可以忍受的。 .skip()
和.limit()
方法遭受“跳过”的性能,可以通过使用这里的方法来避免。
另一方面,如果你想“跳转到页面”,那么“跳过”是唯一真正的select,除非你想build立一个“caching”的结果。 但这完全是另一个问题。