【问题标题】:php mongodb find nth entry in collectionphp mongodb在集合中找到第n个条目
【发布时间】:2012-09-16 08:28:01
【问题描述】:

我正在尝试检索我的收藏中的第 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++;
}

solution provided here 不适用于我的问题,这就是我问这个问题的原因。

【问题讨论】:

标签: php mongodb


【解决方案1】:

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

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

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

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

$cur = $db->collection->find(array('ai_id' => array('$gt' => 403454), 'deleted' => 0))->limit(1);
$cursor->next();
$doc = $cursor->current();

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 谢谢,您能详细说明为什么需要索引吗?顺便说一句,没有$cursor->next() 行,没有输出
    • 这样您就可以通过一个操作唯一地找到该文档,而不是可能必须“遍历”整个集合的光标(取决于您的跳过值)
    • 所以一个计数器像我原来的帖子?还是别的什么?
    • find() 选择集合中所有文档的光标,如果您可以直接使用 $collection->find(array('myIndex' => 3 ))
    • 您的意思是更改架构,以便在我的集合中有一个名为 myIndex 的字段吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    • 2015-11-01
    • 1970-01-01
    相关资源
    最近更新 更多