symfony(MySQL)で前後の記事(次のレコード)を取得する
ブログとかでよくあるような「前の記事」「次の記事」リンクを表示しようと思ってちょっと悩んだ。
記事リストのページで次のリストを取るような場合は普通にページング処理をすればいいだけなので簡単だが、MySQLで「前のレコード」「次のレコード」を取るようなクエリがないので、記事単位だと以外と面倒なことに気づいた。
前提として、そのサイトは記事の新しい順(降順)で表示している。
没案1
ページャと同じ様に記事リストを取得し、ループを回しながら現在の記事を探して前後の記事を取得する。負荷がかかりそうな上に処理が面倒なので却下
没案2
現在の記事付近の塊を適当に取ってきて、適当に前後の記事っぽいものを取る。適当すぎる上に負荷が(ry
採用案
前の記事(getPreviousEntry)の場合…現在の記事の日時より後の記事を抜き出して、日時の昇順(早い日付順)にするとだいたい前の記事が取れる次の記事(getPreviousEntry)の場合…現在の記事の日時より前の記事を抜き出して、日時の降順(遅い日付順)にするとだいたい次の記事が取れる
この方法の問題点同じ公開日時の記事があると飛ばされることだが、
運用的に秒単位で公開日時の同じ記事というのはほぼほぼありえないので(゚ε゚)キニシナイ!!
symfony1.4 のpropelでmodelを書いたが、他の環境でも考え方は一緒かな。
public static function getPreviousEntry($entryId) { $entry = EntryPeer::retrieveByPk($entryId); $c = new Criteria(); $c->add(self::DELETE, 0); $c->add(self::PUBLISH_AT, $entry->getPublishAt(), '>'); $c->addAscendingOrderByColumn(EntryPeer::PUBLISH_AT); $c->setLimit(1); return self::doSelectOne($c); } public static function getNextEntry($entryId) { $entry = EntryPeer::retrieveByPk($entryId); $c = new Criteria(); $c->add(self::DELETE, 0); $c->add(self::PUBLISH_AT, $entry->getPublishAt(), '<'); $c->addDescendingOrderByColumn(EntryPeer::PUBLISH_AT); $c->setLimit(1); return self::doSelectOne($c); }
結構いい方法な気がする