express + mongodb でページャ機能を実装

前提

要素 バージョン
node 7.4.0
express 4.14.0
mongodb 3.2.9

概要

  • expressで動作しているAPIサーバに対して、mongodbに格納されているデータをリクエストする際に、ページを指定して取得する要素を絞り込む。
  • ページ番号はクライアントからサーバに対して送信する
  • 1ページあたりのデータ件数はサーバ側で固定する(今回は5件)
  • expressでmongodbを利用するための前準備などは割愛する

使用するmongodbのメソッド

メソッド名 説明
find(query) queryで指定したデータを取得する
skip(n) データを取得する際に先頭N件をスキップする
limit(n) データを取得する際に最大N件までとする

これらを組み合わせて以下のようにチェインすることでページングが実装できる

find(検索条件).skip((ページ番号 – 1) * 1ページあたりの件数).limit(1ページあたりの件数)

実装

今回は、Photoコレクションに含まれる全ての写真データを対象に、ページ番号のみをクライアントから指定して取得する

/* リクエストからページ番号を取得(デフォルト1) */
let page = Number(req.body.page) || 1;

/* 1ページあたりのデータ件数を5件にする */
let numPerPage = 5;

/* 全ての写真を取得 */
let c = collection('photo').find({});

/* 写真の枚数を取得 */
c.count().then(function(count) {

  /* 総ページ数を計算 */
  let pageNum = Math.ceil(count / numPerPage);

  /* 指定されたページ番号が総ページを上回っていた場合総ページ番号で置き換え */
  if (page > pageNum) { page = pageNum; }

  /* ページングを実行 */
  c.skip((page - 1) * numPerPage).limit(numPerPage).toArray(function(err, docs) {
    /* 写真一覧及びページング情報をクライアントに返却 */
    res.send({
      page: page,
      pageNum: pageNum,
      count: count,
      photo: docs,
    });
  });
});

所感

  • ページング処理とSPAの相性は抜群。僅かな待機時間もなくページを切り替えることができて気持ちいい
  • countとtoArrayで非同期処理が2回続いているので、Promissを使えばもっとキレイなコードになると思うが、Promissの使い方が上手く掴めなかったので今回は普通に入れ子を利用した

参考

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です