PGroonga on Travis CI

2015年2月13日追記: 公式な使い方が発表されました。以下の手順は用済みです。

今回はTravis CIを使うので、無理矢理ですがPGroongaを使えるようにしてみました。
最初は.travis.ymlのbefore_installでpgroongaのドキュメントにあるようにソースからのインストールをやろうとしたんですが、makeに必要なpostgresql-server-dev-9.4をaddonsに書いて入れてやろうとしても、
Disallowing packages: postgresql-server-dev-9.4
と言われてmake出来ないので、checkinstallで.debを作ってやることにしました。


Travis CIのワーカはUbuntu 12.04 LTS 64bitなので、同じ環境でVMを作り、それにPostgreSQL 9.4をインストール。その上でPGroongaをソースからインストールする手順を流し、

$ sudo make install

の代わりに

$ sudo checkinstall

をやってpgroonga_0.3.0-1_amd64.debを作ります。
作ったら、それを適当な場所に置き、.travis.ymlのbefore_installに

  - wget http://path/to/pgroonga_0.3.0-1_amd64.deb
  - sudo dpkg -i pgroonga_0.3.0-1_amd64.deb

と記述してやります。これでPGroongaのインストールができるので、あとはbefore_scriptで

  - psql -d データベース名 --command 'CREATE EXTENSION pgroonga;' -U postgres

と書いてやれば準備完了。あとはマイグレーション定義中でusing pgroongaでcreate indexしてやれば使えるはずです。

PGroongaを使うための調査。

こないだリニューアルした読書びよりでは全文検索エンジンGroongaを使用していて、Rroonga gemを使って全文検索用の処理を実装してあります。ただ、この実装だとPostgresに格納されている商品情報と、Groongaが使う検索用のインデックスが別管理になるので扱いが煩雑なんですよね。そこで、現在開発中の次期カケラの樹 "Sone"ではPGroongaを使おうかなと考えてます。これならActiveRecordから%%演算子を使ったクエリを投げてやれば全文検索できて、実装も管理も簡単になりそうなので。
使うにあたって、レプリケーションに非対応という点が検証必要だったので、試してみました。

前提

  • PostgreSQLで、streaming replicationを使ってアクティブ/スタンバイ構成を組む
  • 障害発生時、インデックスの再生成が必要なのは許容する

小さな個人サービスで、アップタイムを追わないぬるい環境なのでこの程度で大丈夫です。

結果

active側
test=# select * from memos;
-[ RECORD 1 ]----------------------------------------------------------------------
id      | 1
content | PostgreSQLはリレーショナル・データベース管理システムです。
-[ RECORD 2 ]----------------------------------------------------------------------
id      | 2
content | Groongaは日本語対応の高速な全文検索エンジンです。
-[ RECORD 3 ]----------------------------------------------------------------------
id      | 3
content | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。

test=# explain analyze SELECT * FROM memos WHERE content %% '全文検索';
-[ RECORD 1 ]-------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | Bitmap Heap Scan on memos  (cost=8.91..26.60 rows=615 width=36) (actual time=1.332..1.333 rows=1 loops=1)
-[ RECORD 2 ]-------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN |   Recheck Cond: (content %% '全文検索'::text)
-[ RECORD 3 ]-------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN |   Heap Blocks: exact=1
-[ RECORD 4 ]-------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN |   ->  Bitmap Index Scan on pgroonga_content_index  (cost=0.00..8.76 rows=615 width=0) (actual time=1.318..1.318 rows=1 loops=1)
-[ RECORD 5 ]-------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN |         Index Cond: (content %% '全文検索'::text)
-[ RECORD 6 ]-------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | Planning time: 0.428 ms
-[ RECORD 7 ]-------------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | Execution time: 1.740 ms

test=# SELECT * FROM memos WHERE content %% '全文検索';
-[ RECORD 1 ]----------------------------------------------
id      | 2
content | Groongaは日本語対応の高速な全文検索エンジンです。

当然ながら、全文検索可能。

standby側
test=# select * from memos;
-[ RECORD 1 ]----------------------------------------------------------------------
id      | 1
content | PostgreSQLはリレーショナル・データベース管理システムです。
-[ RECORD 2 ]----------------------------------------------------------------------
id      | 2
content | Groongaは日本語対応の高速な全文検索エンジンです。
-[ RECORD 3 ]----------------------------------------------------------------------
id      | 3
content | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。

test=# explain analyze SELECT * FROM memos WHERE content %% '全文検索';
ERROR:  pgroonga: object isn't found: <IDs16537>

test=# SELECT * FROM memos WHERE content %% '全文検索';
ERROR:  pgroonga: object isn't found: <IDs16537>

レコード自体はレプリケートされている。全文検索は出来ない。

pg_ctl promote後のstandby
test=# SELECT * FROM memos WHERE content %% '全文検索';
ERROR:  pgroonga: object isn't found: <IDs16537>

test=# drop index pgroonga_content_index;
DROP INDEX

test=# CREATE INDEX pgroonga_content_index ON memos USING pgroonga (content);
CREATE INDEX

test=# explain analyze SELECT * FROM memos WHERE content %% '全文検索';
-[ RECORD 1 ]-----------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | Index Scan using pgroonga_content_index on memos  (cost=0.13..8.17 rows=2 width=36) (actual time=0.390..0.391 rows=1 loops=1)
-[ RECORD 2 ]-----------------------------------------------------------------------------------------------------------------------------
QUERY PLAN |   Index Cond: (content %% '全文検索'::text)
-[ RECORD 3 ]-----------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | Planning time: 0.175 ms
-[ RECORD 4 ]-----------------------------------------------------------------------------------------------------------------------------
QUERY PLAN | Execution time: 0.546 ms

test=# SELECT * FROM memos WHERE content %% '全文検索';
-[ RECORD 1 ]----------------------------------------------
id      | 2
content | Groongaは日本語対応の高速な全文検索エンジンです。

障害発生時にstandbyを昇格させ、インデックスを張り直せば全文検索が可能になる。


ウチの環境では問題なさそうなので、使ってみることにします。

長い旅の終わりと、「はじまりのそらから」の、新しい旅――天体のメソッド13話。

天体のメソッド 1(特装限定版) [Blu-ray]
天体のメソッド 2(特装限定版) [Blu-ray]
天体のメソッド 3(特装限定版) [Blu-ray]
天体のメソッド 4(特装限定版) [Blu-ray]
天体のメソッド 5(特装限定版) [Blu-ray]
天体のメソッド 6(特装限定版) [Blu-ray]

乃々香は強くあれたのは、友達があってこそのこと。乃々香は汐音を寂しがり屋と評していたけど、乃々香も一人では立っていられない。冒頭、汐音が来てくれたからこそ乃々香は立ち直れたし、汐音が言葉を重ねて背中を押してくれなければ、乃々香はノエルの存在を信じ直すだけで立ち止まってしまったはず。そんな乃々香が、とうとう汐音とかつてのように、分かつことの出来ない二人で一つに戻れたあの湖畔のシーン、本当に良かった。7年越しの再会、いや、ひょっとすると円盤の町と円盤のない町での合計、14年分の旅の終着点かもしれない。語らう二人の姿が暖かくて、甘くて、もうこの二人が道を分かつことは永遠にないんだって分かって、長い長い旅の終わりにふさわしい光景だと感じた。
また、桟橋のシーン。今まではみんなが動き出すのは、乃々香の言葉が決め手だった。けど今回は違った。「みんなで、円盤を呼ぼう」という乃々香の台詞はあれども、今回はそれが決め手ではない。乃々香がいつもやっていた、皆の背中を押す役割を、今度は汐音が果たす。雄弁に、皆が思っていること、けれど一歩踏み出せないことを、語り、背中を押す。引っ込み思案だった汐音が、乃々香にもらったもので大きく変われたことを象徴しているよう。乃々香にとっても、ただ単に助けられたよりもずっとほっと出来たんじゃないかな、と思う。
4話冒頭、身も心もボロボロになった乃々香にとどめを刺すような捨て台詞を投げつけていた汐音が、こうまで乃々香をひたすら信じ支える唯一無二の親友に戻れたのだから、乃々香、本当によく頑張ったよね。もちろん汐音が乃々香を信じていたのも大きいのだけど、乃々香が折れてしまわずに頑張ったから汐音も救われることができた。本当に良かった。


12話の記事で書いたとおり、円盤の町の記憶は乃々香の夢という疑惑があった。汐音に助けられる直前、乃々香の心が折れてしまいそうだったのはその疑念がやたらと説得力を持って彼女を苛んでいたからだろうけど、それは汐音が同じ記憶を持っていたことによって払拭された。冒頭、「夢じゃ、なかった」と一言つぶやいてへたりこむ乃々香の姿、それまで彼女が抱えていた重荷、辛さが感じられてズキッと心が痛んだと同時に、それらからやっと解放されたんだって安堵が広がって、安心した。
そして、たちの悪い疑念はその時点で払拭されたのだから、それ以上に否定材料は必要ではないのだけど、今回乃々香が連れ帰った汐音への父の行動も、あの町の実在の裏付けになっていてうれしかった。
円盤の町での出来事、つまり、"最初の"町への帰還後、父が料理をしようとしたのはオリエンテーリングの次の日。しかも目玉焼きという単純なもの。それが今回は、始業式の日。内容も、ずっと複雑。次にはオムライスまで。焦がしたりとロクな事してないとはいえ、円盤の町での父よりは料理の上達が早いように思える。これは、意識には上らずとも円盤の町での経験が残っていて、それが円盤のない町でも影響していたんじゃないか。つまりこれも、円盤の町が実在した、乃々香の夢なんかじゃなかったっていう裏付けだと思う。
乃々香はそれに気づいていたのかな。父にあきれつつ、汐音との幸せな時間を過ごしているのだから、そんなことまで気は回らなかったかもしれない。別に、そこに気づかなくとも汐音の記憶の存在だけで十分だろうから、良いのだけど。


円盤の町では柚季の行動を苦々しく思ったり諫めたりしていた湊太が、円盤のない町では乃々香の行動にいらだって諫めようとするとか、前回に引き続き以前の柚季の立場と今の乃々香の立場が重なるんですよね。突っ走る柚季を助けようとする乃々香の関係が、ノエルと会いたい一心の乃々香を支える汐音と重なる。
柚希は乃々香が諦めなかったからこそ救われた。じゃあ、今度も大丈夫。汐音はもう二度と乃々香から離れていくはずないのだから。
12話はホントどうしようかと思ったけれど、今回は安心して見られた。本当に、乃々香はいい人に巡り会えたと思う。本人も言っていたけれど、汐音にもし出会えなければ後悔どころの騒ぎではなかったよね、と思う。しかもその場合は何かを失ったことにすら気づかなかっただろうから、尚更。
自分が失ったものにも気づけず、おぼろげな、母への負い目、自責の念だけを抱え、どことなく薄っぺらい人生を送る羽目になったのだろうとしか想像できず、ぞっとする。
円盤の町で乃々香が汐音を救った時、汐音もまた乃々香を救ったんだ。そしてそれは、円盤のない町でも繰り返された。


特殊エンディングに突入した時は少し驚いたけど、よく考えたらなぜ通常じゃなかったのかわかったように思う。
通常エンディングで描かれているのは、幼き頃の願いに導かれて5人が湖畔に集まり、再び再会できるということ。
これは11話で達成され、12話で一度壊れるも、再び13話で達成された話。
だからこそ13話では、それを繰り返すことはしなかった。代わりに、再び一つになった5人が、最後のピースになるノエルを探すこととなる。これは、新しい旅の始まりにふさわしいな、と思った。

この物語は、徹底して"奇跡"だの"不思議なこと"が排除された物語で、唯一のそれは円盤の出現だとずっと思ってた。しかしそれすらも本当はなかった。いや、円盤は来たしノエルも本当にいるのだけど、それは円盤がある世界のことで、円盤のない世界では何も奇跡は起こらなかった。
そんな中で、最後に、唯一起こった奇跡。 一面のひまわりの中で、ひまわりみたいな女の子が、最後になくしたものを再びみつける。それは、奇跡が一つだけ起こるならこれしかない、という感じで、これ以上の結末はないだろうな、と思った。


この作品を観られて、本当に良かったと思う。ここまで好きになれる作品は、最初で最後じゃないかな、とさえ思った。

新年のご挨拶。

皆様、あけましておめでとうございます。
ここ数年は特に大きなリリースもなくぱっとしない活動内容が続いていますが、今年は読書びより、カケラの樹の大規模リニューアルを予定しています。
背伸びは控えつつ、この二つのサービスを末永く続けられるように活動していきたいと思います。


それはともかく。
去年は天体のメソッドが放送されたのでいい年でした。そして今年は天体のメソッドのBDシリーズが発売されるのでいい年ですね!


本年もよろしくお願いいたします。

どうして、こんなことに――天体のメソッド第12話。

天体のメソッド 1(特装限定版) [Blu-ray]
天体のメソッド 2(特装限定版) [Blu-ray]
天体のメソッド 3(特装限定版) [Blu-ray]
天体のメソッド 4(特装限定版) [Blu-ray]
天体のメソッド 5(特装限定版) [Blu-ray]

あのあと、何が起こったか。冒頭で明かされた事実に衝撃を受けて、その後は絶望のどん底に突き落とされて、ラストシーンまで立ち直れなかった。過去回で、見返すのを躊躇するくらいでつらいなんて言っていたのが、だだ甘すぎだったって、思い知らされた。
切なくてつらい話が好きなんて、ことあるごとに言っていたけど、今回はもう、つらすぎて見ていられなくて、途中で何度も止めては落ち着いてからまた続きを見て、また止めて、の繰り返し。
乃々香の言葉通り、どうしてこんなことに……。


ノエルが言っていたこと。円盤は、「次の願いに呼ばれて(どこか別のところに)いく」。乃々香たちに呼ばれた時も同じ、つまり、円盤には前の滞在地が存在したってことなのに、乃々香たちに呼ばれて霧弥湖上空に現れた際に、「世界中を大混乱に陥れた」。あたかも、それが初めてかのように。
その理由が今なら分かる。円盤は、願いを成就させた後、その存在全てをなかったことにしていたのだから。だから霧弥湖町に現れた時に初めて出現したかのような扱いを受けたし、乃々香たちの願いの成就を見届けた後、全てがなかったことになった。

乃々香が校庭で必死に問いかけた時の、「今は思い出さないかもしれないけど」って台詞。既視感があるなあと思いだしてみると、4話での柚季の、「住んでる町は違うけど、クラスのみんなが協力してくれたら」という台詞と似ていた。あの時柚季本人は一生懸命でも、理解はされなかった。今度は、乃々香が必死に問いかけるも、3人はただ戸惑うばかりで、理解はされず、あの場面との類似性が感じられる。

そして、ただ、円盤がないだけで同じ過去を繰り返しているように見えて、そこかしこが違う世界。引っ越してしまった汐音や、柚季・こはる・湊太と同じではなかったクラス分け、そして、遥かに荒廃が進んだ天文台。改変された部分はすべて、乃々香を苦しめる変化ばかりなのが、やはり残酷だなあと感じた。

望遠鏡が崩壊していたのもきつかった。
乃々香にとってあの望遠鏡は、皆で過ごした日々の傍らにあった存在であると同時に、ノエルとの出会いを呼び起こす象徴のようなものだし、天体望遠鏡一般が母を思い起こさせる存在でもあるのだから、それが無残に崩れた姿を晒している、しかもそれがノエルとの再会の望みを抱えて登った先にあった、っていうのは、どれほどの衝撃と悲しみを乃々香が受けたのか、想像もできない。

考えなおしてみると、改変された部分のオリジナルは全て、乃々香にとって都合が良すぎたと考えられなくもない。幼少の頃の思い出深い天文台がかつてとさほど変わらない姿でそこにあったり、あの頃の友達が全員同じクラスに居たり、汐音に至っては親元から離れて一人で暮らしながら乃々香を待っていた、なんて、円盤のない町での出来事のほうが自然に見えてしまう。自分にとって都合が良すぎた世界、つまりあれは現実ではなく夢の話……、ふと、そう思ってしまっても無理はないと思う。けれどこれは、一度そう思ってしまったら際限なく疑いが膨らんでしまうという、危険な想像。


そして心折れそうになった乃々香を救った汐音が、とても神々しく見えた。かつて孤独から汐音を救い出し、道を分とうとする彼女を必死につなぎとめた乃々香が、今度は汐音に絶望から救い出されるなんて、もうなんと言えばいいのかわからないほど良い場面だった。


乃々香と汐音は二人でひとつ。やはり、分かつことなど出来やしない。願わくば、二人の未来に幸あらんことを……。

繋いだ手、繋げなかった手――天体のメソッド第11話。

天体のメソッド 1(特装限定版) [Blu-ray]
天体のメソッド 2(特装限定版) [Blu-ray]
天体のメソッド 3(特装限定版) [Blu-ray]
天体のメソッド 4(特装限定版) [Blu-ray]
天体のメソッド 5(特装限定版) [Blu-ray]

乃々香は、やっぱり強くて、優しい子だなぁと、改めてそう感じられたこの回。

乃々香にとって、ノエルを失うことは耐えがたく悲しいことだっていうのはわかっているのに、乃々香は自分が悲しい思いをすることになっても、ノエルの願いを大切にしたいと願ったんですよね。大切な人を失うのはこれで2度め、前は悲しみに押しつぶされて全てを失ってしまったのだから、また同じような悲しみを背負うのは凄く怖いはずなのに、それでもノエルの願いを叶えたいと願った。それは、皆を再び一つにしたいという思いもあったにせよ、乃々香のノエルへの優しさが大部分なんだと思う。
その決意は、またみんなを動かしてゆくんですよね。

けれど、何度言ったかわからないけどやっぱり残酷だなあと、今回も思った。そう思ったのは、最後の最後でノエルが別れの悲しさに気づいてしまったところ。乃々香が、ノエルのにっこりを叶えたいと言っていたように、あのまま笑顔で別れられるならってお別れを決意した面も多分にあったのだと思うから、あの時ああなってしまったことは、残された5人に深い後悔を植え付けてしまったんじゃないかなぁと感じた。
中でもやっぱり乃々香がかわいそう。乃々香が一番好きだから一番気になるって言うのもあるんだろうけど、それを割り引いてもやっぱり。
最後の最後で、乃々香が伸ばした手は届かなかった。あの時手を取れていたら、ひょっとしたら別れずに済んだとか、そうじゃなくてももうしばらく一緒に居られたのでは、とか、後悔してしまうと思う。ノエルが去ってしまったのだって、自分の決意が引き起こしたことだっていうのも相まって、人一倍後悔してしまうんじゃないかなと思う。だから、「本当にこれで良かったの?」と言わずにはいられない。


これ以外には、誰もが不幸になる道しかなかった。そんなことはわかってる。だけど、だからこそ、避けようがないお別れが待ち構えていた運命が、残酷だなあと改めて思う。


あと、乃々香は自分が笑顔じゃないといけない、泣いちゃダメ、って言ってたけど、あの場面ではそりゃあ泣きたいだろうし、それを押さえつけて笑顔でいようとする彼女の姿は、やっぱり痛々しかった。泣くことは、母との約束を破ることで、だから泣いてしまうと罪悪感を感じるし、泣かずにいられれば嬉しい、乃々香はそう思っているのだろうけど、それじゃまるで母との約束が何かの呪縛のようで。母も、自分の言葉が娘の心を縛ってしまうなんて、望んではいなかっただろうと思うのだけれど。自分の気持ちにある意味素直ではいられないというのは、どこかしら汐音の自己犠牲と似通っているように感じて、見ていて辛かった。
乃々香は汐音が自分の気持に素直になれるように手を差し伸べたけど、乃々香自身がそうできるようになる時は、果たして来るのだろうか?