まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:wordpress

ワードプレスのインポートプラグインを使わず、データベース内のテーブル(wp_posts とか、wp_terms とか、・・)に直接 SQL を実行して、記事をインポートする方法を紹介します。単なる記事だと(簡単すぎて)つまらないので、カテゴリ付きの記事の、そのタイトルと本文をインポートすることに挑戦しました。 なお、ワードプレスのデータベーステーブルプリフィックスは設定によって変更可能ですが、以下はデフォルトである 'wp_' に設定されているものとして紹介します。


【記事のインポート】
単純な記事のインポートだけであれば wp_posts テーブルに post_status = 'publish', post_type = 'post' でデータを挿入するだけです(必要に応じて post_date や post_author なども):
insert into wp_posts( post_content, post_title, post_status, post_type ) values( '(本文)', '(タイトル)', 'publish', 'post' );

単純に記事を公開状態でインポートするだけなら、必要な記事のぶん上記コマンドを繰り返して実行するだけです。以下はカテゴリ情報を有効にする場合の追加作業です。


この SQL を実行した結果、auto_increment なプライマリキーである ID 値が確定します。この ID 値は記事のカテゴリーを指定する際に必要になるので取得しておきます。
select last_insert_id() as ID from wp_posts;


【カテゴリーのインポート】
記事にカテゴリを付与する手順は少し複雑です。

まずカテゴリの名称(と slug)を wp_terms テーブルに挿入します:
insert into wp_terms( name, slug ) values( '(カテゴリー名)', '(カテゴリー名を urlencode したもの)' );

この SQL を実行した結果、auto_increment なプライマリキーである term_id 値が確定するので、この値を取得します:
select last_insert_id() as term_id from wp_terms;

この term_id が所得できたら、次は wp_term_taxonomy テーブルにこの term_id と、term_id が示すカテゴリの記事が何件あるのかという情報を taxonomy 情報(='category')と一緒に wp_term_taxonomy テーブルに挿入します:
insert into wp_term_taxonomy( term_id, taxonomy, count ) values( (term_id の値), 'category', (このカテゴリに属する記事数) );

この SQL を実行した結果、auto_increment なプライマリキーである term_taxonomy_id 値が確定するので、この値を取得します:
select last_insert_id() as term_taxonomy_id from wp_term_taxonomy;

term_taxonomy_id が取得できたら、最初に取得した記事の ID 値と、カテゴリを示す term_taxonomy_id 値との組み合わせを wp_term_relationships テーブルに挿入します:
insert into wp_term_relationships( object_id, term_taxonomy_id ) values( (ID の値), (term_taxonomy_id の値) );

ちとややこしいですが、ここまでの作業でカテゴリに紐付いた記事のインポートが実現できます。ワードプレスDBのテーブルスキーマとの関連だとこんな感じになります:
2017072000


まとまったデータコンテンツをワードプレスに移行する、という場合は上記の作業を必要なだけ繰り返し自動的に行うようなツールを(プログラミングで)作ることになります。本文&タイトル&カテゴリ程度が決まっている単純構成であれば、(それらのデータを取り出す部分さえ作れれば)自動化もそんなに難しくないと思ってます。


超有名なコンテンツ管理システムであるワードプレスは数多くのプラグインも提供されており、プラグインを組み合わせるだけで色々な目的のサイトが構築できてしまいます。

ふとした事情でクラウドファンディング的なサイトを試験的に用意する必要が生じたのですが、「ワードプレスだけでサクッとクラウドファンディングサイトが作れたりしないだろうか?」と思い立って調べてみました。結論としては「色々あるけど、とりあえずクラウドファンディングが作れるプラグインは見つけた」ので、調べて構築した内容を以下に紹介します。


まず、クラウドファンディング用のワードプレスプラグインは有料/無料あわせて数多く存在しています。その中で以下に紹介するのは IgnitionDeck という団体(?)から提供されている IDCF(IgnitionDeck CrowdFunding) (及び IDCF 対応のテーマ)です:
2017040812



IDCF をワードプレスに導入するにはワードプレス管理画面のプラグイン導入から "IgnitionDeck" を検索し、"IgnitionDeck Crowdfunding & Commerce" を見つけて「今すぐインストール」します:
2017040801


他のプラグイン同様に、インストール後「有効化」をクリックすると、このプラグインが有効になります:
2017040802


IDCF プラグインを有効にしても、この段階では IgnitionDeck 未登録のためまだ使えません。管理画面に "IgnitionDeck" というメニューが追加されているので、メニューから IDCF を選び、 "Activate Now" ボタンをクリックして登録画面に遷移します:
2017040803


登録といっても名前、メールアドレス、そしてパスワードを入力するだけです。簡単:
2017040804


登録が完了すると次に行うべき手順が紹介された画面が表示されます。↓下図の3ステップです:
2017040805


1ステップ目、(ここまでの作業でいつの間にか導入されていた)"500 Framework" テーマを有効にします:
2017040806


2ステップ目、IDCF の設定を行います(そのまま Save でも可):
2017040807


そして3ステップ目、というかクラウドファンディングサイトとしてのスタート地点です。クラウドファンディングのプロジェクトが開始できるようになったので、何か1つ追加してみます:
2017040808


プロジェクトを保存すると、ワードプレスのトップ画面のプロジェクト一覧から確認できるようになります:
2017040802


プロジェクトを選択して開くと、クラウドファンディングの説明や目標額が確認でき、支援表明もできるようになっていることが確認できます:
2017040803


IDCF には有料のオプションもあり、サポートや追加で使えるツールキットが用意されているようです。が、まだあまり調べていません。こちらは気が向いたらということで。。


軽く使ってみた限りでの感想ですが、管理画面が英語なのはともかくとして、目標額などを入力すると自動的に米ドル扱いになってしまうことに気付きました(要は金額のデータとして "100" と入力すると、自動的に「100 米ドル」扱いになってしまう)。これをカスタマイズするには IDC メニューの CURRENCY SETTINGS から "JPY" を選択して更新しておくことで変更できました:
2017040801


もう一点、ファンディングの支援レベル(例えばレベル1はステッカーのみ、レベル2は商品そのもの1つ、レベル3は商品を10個まとめて、・・・みたいなもの)を複数追加しようとしたのですが、うまくできませんでした。ググってみると、同じ現象で悩んでるっぽい人向けの FAQ っぽいページを見つけたのですが「会員専用ページです」みたいなメッセージから先に進めず、未だに原因やワークアラウンドが分かっていません。会員としてログインしてるはずなんだけどな・・・ もしかすると、ここが無料版の制限なのかもしれません:
2017040801


もう一点。実際にユーザーがこのプロジェクトを支援しようと "Support Now" して、"Next Step" に進もうとすると、、:
2017040901


こんな画面に推移します:
2017040902


ここで何らかの入力フォーム(project_purchase_form ?)が出て来る想定なんだろうけど、ここをどうすると表示できるようになるのか? カスタマイズするにはどうするのか? といった情報を探していたのですが、どうやらここから先は無料版では提供されていない機能のようでした:
Ignitiondeck does not redirect me to Purchase Page


というわけで、まだ IDCF のフル機能を試せたわけではないのですが、ここまでは超簡単に作れてしまったことも事実。便利なプラグインをまた1つ発見してしまった。。


以前に「ノーツデータベースをまるごと IBM Watson に学習させて、問い合わせを行うサンプルアプリ」を作って紹介しました。なかなかに反響があり、タダで配布しなければよかった、と・・・調子に乗って同様のワードプレス環境向けサンプルを作ってみました。

ワードプレスは世界中で使われているオープンソースの CMS(コンテンツ管理システム)です。ちょっとデータが古いのですが、2014 年時点での 1000万サイトを対象にした調査によると CMS としてのシェアは約60%で、何よりも驚くのは全ウェブページ中の 26.6% がワードプレスを使って作られている、ということです(もう少し新しい情報持ってる人がいたら教えてください):
https://w3techs.com/technologies/overview/content_management/all

2016081201


と、それだけ利用者の多いワードプレスのデータをコグニティブエンジンである IBM Watson に学習させて、かつその学習データを使った問い合わせまでを実現できるようなプラグインを開発しました。 ぶっちゃけ、まだ「動作確認レベル」の段階ですが、このタイミングで一度公開して、多くの人に使ってみていただこうと思っています。


このプラグインを使うには、大きく2つの前提条件が必要です:
1. IBM Bluemix 環境
2. データの入ったワードプレス環境


まず 1. IBM Bluemix 環境です。IBM Bluemix にサインアップし、有効なアカウントを所有している必要があります。IBM Bluemix はアカウント作成から 30 日間は無料で利用することが出来、また有償以降後にもサービスに無料枠が設けられていて、無料または安価に利用することが可能です。

この IBM BLuemix にログインして、Watson の Natural Language Classifier (以下 NLC)サービスを作成します。このサービスを使ってデータの学習および問い合わせを行います:
2016081202


ちなみに NLC サービスの 2016/Aug/12 時点での料金は以下の様になっています。サービスインスタンスを1つだけ作成し、一ヶ月の中で学習機能を4回、問い合わせ機能を 1000 回以内使うぶんには(有償契約移行後であっても)無料枠に収まるので料金はかかりません。これらを越えて利用した場合の料金の目安にしてください:
2016081204


作成したサービスの「サービス資格情報」を確認し、このサービスを利用するためのユーザー名(username)とパスワード(password)を確認します。これらの情報は後で利用するので、このページを残しておくかメモするなりして入力できる状態にしておいてください:
2016081203


次に 2. データの入ったワードプレス環境ですが、ワードプレスの中にある文書とカテゴリを使って学習させるため、それなりの学習データを用意しようとすると、それなりの文書量が必要になります。またそのワードプレス環境にプラグインをインストールする等、管理者アカウントでログインできる権限も必要になります。


実際にプラグインを導入する手順を紹介します。プラグインは GitHub 上に用意しました:
https://github.com/dotnsf/wordpress_watson_nlc

2016081301


上記ページの "clone or download" と書かれた緑のボタンをクリックし、メニューから "Download ZIP" を選択してプラグインの ZIP ファイル(wordpress_watson_nlc-master.zip)をダウンロードします:
2016081302


ダウンロードした ZIP ファイル(wordpress_watson_nlc-master.zip)は、ワードプレスの管理画面の プラグイン - 新規追加 から「プラグインのアップロード」をクリックしてインストールできます:
2016081303


追加するプラグインファイルを指定する画面が表示されたら、ダウンロードした ZIP ファイル(wordpress_watson_nlc-master.zip)を指定して「今すぐインストール」ボタンをクリックします:
2016081304


インストールが成功したら「プラグインを有効化」をクリックして、このプラグインを有効な状態にします:
2016081305


プラグインが有効になると管理メニューの中に「NLC 設定」という項目が追加されます。このページをクリックして表示し、Username と Password に上記の NLC サービス設定時のサービス資格情報ページで取得したユーザー ID とパスワードを入力し、「変更を保存」ボタンをクリックします:
2016081306


Username と Password が設定されました。これで NLC プラグインのインストールと設定が完了です:
2016081307


では実際にこのプラグインを使ってみましょう。このプラグインで出来ることは2つあります:
(1) この(プラグインを導入した)ワードプレス環境内に格納されたデータを IBM Watson に学習させる
(2) (1) で用意した学習データを使って、問い合わせを行い、その返答内容を確認する


それぞれ順に説明します。(1) の学習機能ですが、ワードプレスに格納された投稿データの本文及びタイトルとカテゴリーの情報をもとに学習します。例えば以下の様な内容の投稿データがあったと仮定します:
 
タイトルBLUEMIX 上の SPARK を利用して、ブラウザー内で気象データを分析する
本文Apache Spark は、まったく新しい機能の数々をデータ・サイエンティスト、ビジネス・アナリスト、アプリケーション開発者に初めて利用できるようにする、次世代の分散データ処理エンジンです。Analytics for Apache Spark は IBM Bluemix に用意されている一般的なツールと連動することから、この Analytics for Apache Spark を使用することで、瞬く間にこの Apache Spark の能力をフル活用できるようになります。このチュートリアルでは、Spark API を使用する IPython Notebook を利用して、実際の気象に関するロー・データを分析する方法を紹介します。この例をベースとして使用すれば、Bluemix 上の他のアナリティクスも簡単に利用することができます。
カテゴリーcloud


Watson は初期状態では何も学習していません。そこにこの投稿データのカテゴリーである cloud について学習させたいとします。初期状態では cloud が何なのかを理解していませんが、cloud の例としてこのデータのタイトルと本文の内容を与えて「これが cloud の例だ」という形で学習させます。

これだけですとまだ1データだけですが、実際には cloud カテゴリーに属している投稿データ(のタイトルと本文の内容)を全て「cloud の例」として与えます。すると Watson は与えられた全データから cloud というものによく出てくる単語や言い回しの傾向などを自分で見つけて、「cloud にはどういった特徴があるか」を学習します。

対象のワードプレスデータには他にも色々なカテゴリーのデータが存在していることを想定しています。そして全てのカテゴリーと、そのカテゴリーに属している全レコードを使って、それぞれのカテゴリー内容を学習させます。例えばデータベース内に6つのカテゴリーが設定されている場合は6つのカテゴリーを学習させることになります。

その学習を実行するにはプラグインページの「学習」ボタンをクリックします:
2016081301


このデータベース内の情報を使って学習データを更新する、という確認メッセージが表示されます。更新するとこれまでの学習データが存在している場合も一旦削除されて、新たに現在の全投稿データを使った学習が行われます。「OK」をクリックすると続行します:
2016081302


学習処理が成功すると「データは学習中です」というメッセージが表示されます。これでデータは学習状態になりました。この直後はまだ学習中で問い合わせができない状態になりますが、しばらくすると (2) の問い合わせが可能になります:
2016081303


この学習によって、ワードプレス内に用意された各カテゴリーのキーワードを、そのカテゴリーに紐付けられた投稿データ(のタイトルと本文の内容)を基に学習します。そして学習後の問い合わせでは、与えたテキストの内容が各カテゴリーのどの内容にどの程度近いのか、という分類結果を返してくれるようになります。


では (2) の学習データに対する問い合わせ処理を紹介します。管理画面の NLC 設定ページから Query と書かれたテキストフィールドに何かテキストを入力します。ここで入力する内容は上記で学習させたカテゴリーのいずれかに関する内容となるようにしてみてください。以下の例では「Bluemix は IBM の PaaS プラットフォームです」と入力しました。この内容を Watson に問い合わせてみます。「問い合わせ」ボタンをクリックしてください:
2016081301


先ほど実行した学習処理がまだ完了していない場合、"Training" と表示されます。この場合はもうしばらく(15分~1時間程度)お待ちいただいた上で再度実行してみてください:
2016081302


Watson の学習が完了していれば問い合わせに対する回答とその confidence (自信度)が表形式で以下のように表示されます(この例文に対しては "cloud" と返してほしかったけど、このワードプレス内のデータによると "web" なのだそうだ。まあ間違いではないけど・・・):
2016081401


問い合わせに使った「Bluemix は IBM の PaaS プラットフォームです」という文章には "Web" や "Cloud" という直接的なキーワードは含まれていません。にも関わらず、(学習させたデータを元に)この内容が "Web" や "Cloud" に関係している可能性が高い、と判断できたことになります。


以上がこのプラグインが実装している機能の紹介です。注意事項が2点あります:

このプラグイン内の実装では複数のワードプレスデータには対応していません。同じ Username と Password の組では1つの(最新の)学習データしか持てません。複数のデータを同時に学習させる場合は複数の NLC サービスインスタンスを作成し、それぞれ Username と Password を取得して学習させる必要があります(無料枠内ではなくなります)。

もう1点。この NLC プラグインが不要になった場合は管理画面の「インストール済みプラグイン」の一覧から "Watson NLC" プラグインを探して、停止してください(今後も不要であればプラグインを削除してください)。
2016081403


と、こんなことができるサンプルプラグインです。ワードプレス環境をお持ちで、投稿データにある程度のカテゴリー分類ができている方は是非その環境で試してみていただきたいです。


なお、このプラグインの中で実装している機能は全てここで紹介されている NLC API を使って実装しています。この API を使うと学習させたデータを使った別のカスタマイズを行ったり、(ワードプレス以外の)別のアプリケーションから呼び出したりすることも可能です。興味あるデベロッパーの方は参照して、併せてチャレンジしてみてください:
Natural Language Classifier - API


WordPress のデータベースから SQL でデータを取り出すシリーズ(?)の応用編。今回のテーマは
 ポストした本文とタイトルと、その文書に付与されたカテゴリの一覧だけを取り出す
というものです。

最初に結論を書いておきます。この SQL で目的を達成できるはず(公開データと未公開データの両方を取り出しています):
select wp_posts.post_content as content, wp_posts.post_title, wp_terms.name as category
 from wp_posts, wp_terms, wp_term_relationships
 where wp_posts.post_type = 'post' 
 and ( wp_posts.post_status = 'publish' or wp_posts.post_status = 'draft' )
 and wp_posts.ID = wp_term_relationships.object_id
 and wp_term_relationships.term_taxonomy_id = wp_terms.term_id;

説明する上で、WordPress のテーブルの相関関係を理解しておく必要があります。関連図についてはこちらを参照ください:
データベース構造 - WordPress Codex 日本語版


まず WordPress にポストしたレコードデータは wp_posts テーブル内に格納されています。特に(固定ページなどではなく)ポストデータは
 post_type = 'post'
となっているものが該当します。

そして今回は公開済みレコードと未公開(ドラフト)レコードの両方を取り出すことにしました。公開状況は同テーブルの post_status に格納されており、
 post_status = 'publish' or post_status = 'draft'
のいずれかの条件を満たしているものを取り出し、そこから本文(post_content)とタイトル(post_title)を取りだせばよい、ということになります。もしもドラフトが不要な場合はこの行の or 以降は不要です。

取り出すレコードの選別はこれだけです。次に各レコードに紐付けられたカテゴリ名称を取り出す必要があります。

カテゴリーのデータは wp_terms テーブルに(カテゴリ名は name 列に)含まれています。そしてどの文書がどのカテゴリに属しているのか、というリレーションは wp_term_relationships テーブルに格納されており、同テーブル内の object_id が wp_posts.ID 、term_taxonomy_id が wp_terms.term_id に該当しています。

例えば、wp_term_relationships テーブルに以下のようなレコードが存在していた場合、
object_idterm_taxonomy_id
41
61
82

wp_posts テーブルの ID が 4 の文書と 6 の文書は、wp_terms テーブルの term_id = 1 のカテゴリに属していて、ID が 8 の文書は term_id = 2 のカテゴリに属している、ということになります。

これらの関係を1つの SQL に書き直すと上記の SQL になります。
2016070701


WordPress に使っているデータベース(一般的には MySQL のデータベースだと思います)から、SQL を使って、ブログの名称や説明文を取り出す方法です:

2016070501
↑この図の赤枠部分がブログの名称、青枠部分が説明文です。


前提として、データベース作成時のテーブルのプレフィックスはデフォルトの 'wp_' をそのまま使っているものとします。つまりデータベース内には wp_posts とか wp_terms といったテーブルが存在している状態で利用中のものとします:
2016070502


で、ブログの名称は wp_options テーブル内に option_name の値が 'blogname' であるレコードの option_value 値として格納されています。したがってブログ名称を取り出す際の SQL は以下になります:
select wp_options.option_value as name from wp_options where wp_options.option_name = 'blogname';

2016070503
↑取り出せました


同様に、説明文は option_name の値が 'blogdescription' であるレコードの option_value 値です。したがって SQL だと以下になります:
select wp_options.option_value as name from wp_options where wp_options.option_name = 'blogdescription';
2016070504


この辺りがわかっていると、SQL でブログタイトルや説明を無理やり書き換える、ということも可能になります。


このページのトップヘ