今週作業をして疑問が湧いたので調べてみました。何か事情があってチェックボックス(複数選択)タイプのカスタムフィールドを用意しており、そのフィールドのチェック状況に応じて記事を抽出したいという主旨です。
※19:05追記 「Movable Type 再構築高速化 <mt:SearchEntryField> (by PowerCMS) | MD-Blog | MONSTER DIVE」を読んでmt:searchentryfield
のことを思い出しました。ただせっかく書いたのでこのまま残しておきます。(ただ、もしかするとソートの挙動が僕のと違うのでは、という気がします。)
試しに「対象学部(ベースネームentry_faculty
)」というチェックボックス(複数選択)タイプのカスタムフィールドを用意し、オプションに私の母校に存在する学部「法学部,経済経営学部,メディア情報学部,スポーツ科学部,心理学部,現代文化学部」を指定しました。テーマに含まれる記事が20件登録されていたので、10件の記事に対して適当にチェックを付けていきました。
mt_entry_meta
テーブルを見ると、以下のようにデータが入っていました。チェックボックスの値の前後にカンマが付いた状態で保存されるようです。
entry_meta_entry_id | entry_meta_type | entry_meta_vchar |
---|---|---|
34 | field.entry_faculty | ,メディア情報学部, |
33 | field.entry_faculty | ,法学部,経済経営学部, |
この結果から先日2月3日に書いた記事「PowerCMS 5で前後がリンクやPDFではない記事をEntryPrevious / EntryNextで出力したい」のようにSQLを書いてもよいかと思いましたが、もう少し過去を振り返ると2015年12月に「MTでカスタムフィールドのLIKEフィルタやX以上・Y未満のフィルタを実現する」という記事を書いており、カスタムフィールドの特殊な検索を実現する「ExtendEntryFieldFilter」を試作していました。
テンプレートは以下のようになります。MTSpeedMeterで処理時間も計測します。
<mt:speedmeter name="カスタムフィールドをLIKE検索">
<mt:entries field:entry_faculty="LIKE","%,メディア情報学部,%" limit="3">
<mt:entriesheader><ul></mt:entriesheader>
<li><mt:entrytitle escape="html" /></li>
<mt:entriesfooter></ul></mt:entriesfooter>
</mt:entries>
</mt:speedmeter>
再構築を実施すると、メディア情報学部にチェックが入った6件の記事の内、最新の3件が表示されました。ログに記録された処理時間は概ね0.03秒前後にでした。対象記事を抽出するために発行されたクエリは以下でした。
SELECT entry_id
FROM mt_entry, mt_entry_meta
WHERE (entry_blog_id = '2') AND (entry_status = '2') AND (entry_class = 'entry') AND (entry_meta_vchar LIKE '%,メディア情報学部,%') AND (entry_meta_type = 'field.entry_faculty') AND (entry_meta_entry_id = entry_id)
ORDER BY entry_authored_on DESC, entry_id DESC
LIMIT 3
記事が1,000件や2,000件になり、なおかつカスタムフィールド数が多いとmt_entry_meta
テーブルの行数もかなり増える、さらにLIKE検索なのでどのぐらいの速度になるかは気になりますが、少なくともmt:entries lastn="0"
とmt:if name="faculty" like=",メディア情報学部"
の組み合わせよりは速いのでは?と考えています。もし遅ければ、学部毎に単一のチェックボックスにすると(管理画面はカスタマイズして複数選択に見せる感じで)LIKE検索は避けられそうです。