计算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 }); 

现在,这些lastVallastSeen是你存储在类似于“会话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所有值,并确保所有结果都必须是“小于或等于”(降序) lastVallogging的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”的结果。 但这完全是另一个问题。