2

我正在尝试检索我的收藏中的第 n 个条目。
这似乎可以使用find(),但我认为有一个更清洁的解决方案使用findOne(),也许sort()
任何人都可以帮忙写一个更好的方法吗?

$mongo = new Mongo();
$db = $mongo->mydb;
$collection = $db->user;

$cursor = $collection->find();
$i=0;
foreach ($cursor as $obj){
    if ($i==3)
        echo $obj["_id"];//echo's the 3rd entry id
    $i++;
}

这里提供的解决方案不适用于我的问题,这就是我问这个问题的原因。

4

2 回答 2

4

Skip() 没有有效地使用索引,因此在集合中的任何字段上放置索引都是没有意义的。

由于您希望skip()第 n 个文档,如果 的值skip()较低(取决于您的系统,但在完整的集合扫描中通常低于 100K 行),那么它可能没问题。问题是通常情况下并非如此。Mongo,即使有索引,也需要扫描整个结果集,然后才能跳过它,这将导致无论查询中的什么内容都进行完整的集合扫描。

如果您要经常以随机方式执行此操作,最好使用递增 ID 结合另一个集合findAndModify来生成准确的文档编号(http://www.mongodb.org/display/DOCS/How+to+Make +an+自动+递增+字段)。

然而,这会引发问题,您必须保留此 ID,尤其是在发生删除时。解决此问题的一种方法是将文档标记为已删除,而不是实际删除它们。当您查询您省略删除的确切文档时,limit()通过一个允许您获取下一个最接近该位置的文档,如下所示:

$cur = $db->collection->find(array('ai_id' => array('$gt' => 403454), 'deleted' => 0))->limit(1);
$cursor->next();
$doc = $cursor->current();
于 2012-09-25T07:34:42.003 回答
2

从上面的代码中使用 (n-1) 的跳过:

$cursor = $collection->find();
$cursor->skip(3);
$cursor->next();
$doc = $cursor->current();

但我认为最好的方法可能是在文档中保留一个可以用作索引的计数器。

于 2012-09-24T20:52:31.360 回答