如何使用mongodb和php正确处理分页查询?

2022-08-30 22:15:47

我这样做对吗?我去看了一些带有MySQL的旧PHP代码,我已经设法让它工作,但是我想知道是否有一种“更干净”和“更快”的方式来实现这一点。

首先,我需要获得“文档”的总数

$total_documents = $collection->find(array("tags" => $tag, 
        "seeking" => $this->session->userdata('gender'), 
        "gender" => $this->session->userdata('seeking')))->count();

$skip = (int)($docs_per_page * ($page - 1));
$limit = $docs_per_page;
$total_pages = ceil($total_documents / $limit);

用于填充数组的查询,以便我可以使用分页进行显示

$data['result'] = $collection->find(array("tags" => $tag, 
        "seeking" => $this->session->userdata('gender'), 
        "gender" => $this->session->userdata('seeking')))->limit($limit)->skip($skip)->sort(array("_id" => -1));

我的问题是,我可以一次性运行查询吗?我基本上运行了两次相同的查询,除了第二次我传递值以在记录之间跳过。

-- 新代码 ...

好吧,除非有人知道另一种方法来做到这一点(如果可能的话),否则我会说这是行不通的。话虽如此,我改变了通过mongodb运行查询的方式,从而产生了更好看的代码。;-)我试图尽量减少到DB的行程,但哦,好吧,希望这不会对性能造成影响。我的另一个尝试是计算数组中元素的数量,但很快发现这不起作用,因为$limit和$skip参数会给出ITS的文档总数。

$skip = (int)($docs_per_page * ($page - 1));
$limit = $docs_per_page;

$query = array("loc" => array('$near' => array('lat' => $latitude, 'lon' => $longitute) ),
        "tags" => $tag, "seeking" => $this->session->userdata('gender'),
        "gender" => $this->session->userdata('seeking'));

$fields = array("username", "zipcode", "tags", "birth_date");
$total_documents = $collection->find($query, array("_id"))->count();
$data['result'] = $collection->find($query, $fields)->limit($limit)->skip($skip);

答案 1

由于 find()->limit()->skip() 的结果是Mongo_Cursor因此您不必执行实际查询两次。

以下方法也应该有效:

$skip = (int)($docs_per_page * ($page - 1));
$limit = $docs_per_page;

$query = array("loc" => array('$near' => array('lat' => $latitude, 'lon' => $longitute) ),
    "tags" => $tag, "seeking" => $this->session->userdata('gender'),
    "gender" => $this->session->userdata('seeking'));

$fields = array("username", "zipcode", "tags", "birth_date");
$cursor = $collection->find($query, $fields)->limit($limit)->skip($skip);
$total_documents = $cursor->count();
$data['result'] = $cursor;

顺便说一句,我首先误读了你的问题,我以为你不知道限制和跳过。


答案 2

是的,你做对了。您可以一次性运行查询。

下面是一个分页示例:

function printStudents(pageNumber, nPerPage) {
   print("Page: " + pageNumber);
   db.students.find().skip((pageNumber-1)*nPerPage).limit(nPerPage).forEach( function(student) { print(student.name + "<p>"); } );
}

参考:高级查询 - MongoDB:http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-{{skip%28%29}}


推荐