株式会社クリアコード > ククログ

ククログ

タグ:

「クリアコードをいい感じにする人」の採用を開始

代表取締役の須藤です。コードを書いたり、社外向けの活動をしたり、クリアコードをいい感じにしたりしています。このうち、「クリアコードをいい感じにする」活動を主な業務とする人の採用活動を始めました。職種は「クリアコードをいい感じにする人」です。世間でこのような活動をする人がどのような職種なのかわかっていないのでこんな職種名になっています。

クリアコードは以下の2つの両立を大事にしています。

  • お金を稼ぐこと(フリーソフトウェアを「継続的に」推進していくために必要だから)
  • フリーソフトウェアの推進

これを「継続的に」今よりももっとうまくやれる私たちになりたいと思っています。「クリアコードをいい感じにする」というのはこれを実現するための活動です。

たとえば、今は次のような活動をしています。

  • 1ヶ月に1度クリアコードメンバー全員から個別に最近の話を聞く
    • どうやったら「もっといい感じ」になりそうかの情報集め
    • 困っていることがあったら解決に協力
  • クリアコードメンバーから集めた情報を元に「もっといい感じ」になることにつながりそうな活動の考案
  • 問題解決を練習する場の用意
    • 問題を1つ設定し、決められた期間内に解決案を出し、実際にそれを実施し、問題を解決する
    • 「お金を稼ぐこと」と「フリーソフトウェアの推進」をいい感じに両立するための練習
    • お客さんはこれらの両立が大事ではないことが多いので、お客さんの要望をそのまま実現するだけでは両立が難しい。そのため、お客さんの本当の問題を理解し、クリアコードが大事なことも両立もするしお客さんもいい感じになる解決案を提案し、それを実施することで両立をがんばっている。それをよりいい感じにできるようになるための練習。
  • 他にもいろいろ…

今抱えている課題は、これらの「クリアコードをいい感じにする」活動に継続的に十分な時間を確保できていないことです。今はこのような活動をしていますが、今後も同じことをやっていればよいというものではありません。私たち自身が変わっていくからです。私たちに合わせて活動内容も変わっていくはずです。そのようなことに必要な時間を確保できていません。

そこで「クリアコードをいい感じにする」活動を主な業務とする人の採用を始めました。「クリアコードをいい感じにする」活動は継続的に取り組むべき重要な活動だと考えているからです。

採用情報は「クリアコードをいい感じにする人」の採用情報にまとめました。私たちはどういう人が「クリアコードをいい感じにする」活動をするのに向いている人なのかまだわかっていません。採用情報にも「わかっていないことがいろいろあるので一緒に考えながらうまくできるようになりましょう」と書いてあります。

そのような職種ですが、興味のある方はぜひ以下のような内容のメールを私に送ってください。一度お話しましょう!

To: kou@clear-code.com
Subject: 会社説明会参加希望

名前: ○○××
職種:「クリアコードをいい感じにする人」
備考: (希望日時などがあれば)
タグ: 会社
2017-08-18

MySQL・PostgreSQL上で動かす全文検索エンジン「Groonga」セミナー - Mroonga・PGroongaを使った全文検索システムの実装方法 #groonga #mysql #mariadb #postgresql

cairo色付きフォントサポートが入ったので、今回のスライドではNoto Color Emojiを使ってRabbitで色付きの絵文字を表示した須藤です。

2017年8月1日にMySQL・PostgreSQL上で動かす全文検索エンジン「Groonga」セミナーを開催しました。今回は業務でGroonga(Mroonga・PGroonga)を使いたい人向けのイベントだったので平日の午後に開催しました。

関連リンク:

内容

これまでのMroonga・PGroongaの紹介資料では、速さや機能を紹介するまとめ方が多かったのですが、今回の資料は「イマドキの全文検索システムを作るにはこんなSQLを使えばよい」というまとめ方にしました。逆引きレシピのようなまとめ方です。

話の流れは次のようになっています。全文検索システムを作る機会がある人は参考になるはずです。

  • イマドキの全文検索システムとは?
  • ミドルウェアの選び方は?判断基準は?
    • 全文検索サーバーを使う?
    • RDBMSだけでがんばる?
    • RDBMSに全文検索エンジンを組み込む?
  • イマドキの全文検索システムに必要な以下の機能をMroonga・PGroongaで実装するには?
    • 全文検索機能
    • キーワードハイライト機能
    • 周辺テキスト表示機能
    • 入力補完機能(今回はPGroongaのみ)
    • 同義語展開機能(今回はPGroongaのみ)
    • 関連文書の表示機能
  • 構造化された文書を検索対象にするには?
    • 構造化された文書の例:オフィス文書(Word・Excel・PowerPoint・LibreOfficeなどで作成した文書)
    • 構造化された文書の例:HTML(ヘッダー・フッター・サイドバーのテキストを取り除くなど、単にbody.innertTextの値を取得するだけではノイズが増えるので、いろいろケアが必要)
    • 構造化された文書の例:PDF
    • HTTPでテキスト抽出・スクリーンショット作成できるChupaTextの紹介
    • Dockerで使う:chupa-text-docker
    • Vagrantで使う:chupa-text-vagrant

まとめ

Mroonga・PGroongaでイマドキの全文検索システムを作る方法を紹介するセミナーを開催しました。クリアコードは全文検索システムの受託開発・設計支援・開発支援・障害調査支援など全文検索関係のもろもろをサポートするサービスを提供しています。とりあえず話を聞いて欲しいというレベルからでも結構ですので困っていることがあればお問い合わせください。

タグ: Groonga
2017-08-02

OSS Gate東京ワークショップ2017-07-29を開催 #oss_gate

東京のワークショップでは久しぶりに進行役をした須藤です。

2017年07月29日にクラウドワークスさんOSS Gate東京ワークショップを開催しました。そういえば、今回は集合写真を撮り忘れましたね。。。

数回前からYassLab安川さんさんが進行の録画にチャレンジしていましたが、今回はかなり完成度の高いものができました!YouTubeでOSS Gate ワークショップ (完全収録版)というプレイリストを公開しているので、どんな様子か知りたい方は見てみてください。

また、今回から説明用の資料を1つのスライドにまとめました。サポーター向けの説明が足りなそうという課題はありますが、これまでより進行がしやすくなりました。

あと、今回は作業時間を1時間+1時間に短くしてみました。(これまでは1時間+2時間30分とか。)同じ日に開催していたOSS Gate京都ワークショップでも同じような時間配分だったりします。やってみて、アンケートで参加者に感触を聞いた感じでは、進め方次第では1時間でもいけそうな感触を得ました。

今月は大阪でワークショップ東京でミートアップが開催されます。

来月は高専生向けのワークショップが東京で開催されます。(メインターゲットが高専生なだけで高専生以外も参加できます。)

OSS Gateワークショップに興味がある方は一度どこかのイベントに参加して、参加者の人と話をしてみるとよいと思います。実際に自分で体験することで理解が深まりますし、まわりの人と話すことで協力しやすくなります。

企業で開催したい(社員がOSSの開発に参加することを支援したい)場合はクリアコードにお問い合わせください。有償で平日日中での開催を支援しています。

2017-08-01

TravisCI上で複数のLinuxディストリビューションのテストをする方法

クリアコードでは、独立行政法人情報処理推進機構(IPA)平成20年度オープンソフトウェア利用促進事業迷惑メール対策を柔軟に実現するためのmilterの開発」の一環としてmilter managerの開発を行なって以来、milter managerの開発を継続しています。 最初のコミットを見ると2008年9月1日なので、約9年開発を続けています。

milter managerは、記事執筆時点では以下のLinuxディストリビューション向けにパッケージを作成しています。

  • CentOS 6
  • CentOS 7
  • Debian Jessie *1
  • Debian Stretch
  • Debian Buster
  • Debian Sid
  • Ubuntu 14.04 LTS
  • Ubuntu 16.04 LTS
  • Ubuntu 16.10
  • Ubuntu 17.04

CentOS 7以外はi386とx86_64(amd64)向けのパッケージをビルドして提供しています。*2 以前はTravisCIのrvmを使ってRubyのバージョンだけを切り替えてテストしていましたが、パッケージを提供するという観点で考えるとTravisCIの動かしているUbuntu 14.04やUbuntu 12.04だとRubyだけ切り替えてもmilter managerが依存しているGLib等のライブラリのバージョンの違いについてはテストできていおらず不十分でした。開発を続けていくためには、サポートしているディストリビューションできちんと動作することを確認することが重要です。提供しているパッケージでは、それぞれのディストリビューションごとに1つのRubyバージョンをサポートしているので、CIでもそのようなテストを実行するべきです。

そのようなテストを実行するためには、TravisCI上で複数のディストリビューションを切り替えてテストを実行する必要があります。調べてみたところ、TravisCI上ではDocker Compose | Docker Documentationを使えることがわかりました。またDocker Hubを確認すると、それぞれのディストリビューションのOfficialイメージがありました。

これで材料は揃ったので、あとはどうやって.travis.ymldocker-compose.ymlDockerfileを書いていくか考えるだけです。

Dockerfileはビルド環境を整えるところまでやることにしました。実際のビルドまでDockerfileでやってしまうと、ビルド環境が整っていなかった場合の修正に時間がかかるためです。 また、milter managerのソースコードはTravisCIのホスト上にあるのでそれをそのまま使うことにしました。 ローカル環境でイメージを作るときは、カレントディレクトリ以下のファイルを全てCOPYするので新規にgit cloneしてやった方がよいです。

FROM debian:sid

ENV CODE_NAME=unstable

RUN apt-get update && \
    apt-get install -qq -y \
      debhelper dh-systemd autotools-dev \
      libglib2.0-dev libev-dev ruby ruby-dev ruby-gnome2-dev ruby-test-unit-rr \
      intltool lcov git libtool sudo lsb-release apt-transport-https \
      rrdtool rsyslog && \
    curl -L https://raw.github.com/clear-code/cutter/master/data/travis/setup.sh | env CUTTER_MASTER=yes sh && \
    gem install --no-rdoc --no-ri coveralls-lcov && \
    gem install --no-rdoc --no-ri pkg-config && \
    useradd -m --user-group --shell /bin/bash milter-manager

WORKDIR /home/milter-manager/milter-manager
COPY . .
RUN chown -R milter-manager:milter-manager .
USER milter-manager

docker-compose.ymlは特に工夫したところはありません。無限に待ち続けるためにコマンドをtail -f /dev/nullにしたくらいです。 Dockerfile-*と連携してビルド環境を整えるところまでを意識しています。また、対応するディストリビューションが増えたときもコピペで簡単に増やせるようにしました。

version: "2"
services:
  ubuntu-trusty:
    build:
      context: .
      dockerfile: dockerfiles/Dockerfile-ubuntu-trusty
    command: tail -f /dev/null

  ubuntu-xenial:
    build:
      context: .
      dockerfile: dockerfiles/Dockerfile-ubuntu-xenial
    command: tail -f /dev/null
# ... 以下同じような内容が続くので略

.travis.yamlではmatrixを使って環境変数でテストを実行するコンテナを制御しました。 matrixのTARGET_DISTRIBUTIONの行を増やせば、対応するディストリビューションを増やせるようにbefore_script:以降を調整しました。 ディストリビューションごとのパッケージの依存関係はDockerfileで解決し、Rubyのバージョンの違いや依存ライブラリのバージョン違いはautotoolsなどを使って解決しています。 そのため.travis.ymlの内容はとてもシンプルになっています。

ただし、CentOS6だけは利用しているRubyも自分でビルドしたsuffix付きのものを使っているのでconfigureのオプションが異なっています。*3

dist: trusty
sudo: required
notifications:
  email:
    recipients:
      - milter-manager@ml.commit-email.info

services:
  - docker

env:
  global:
    DOCKER_COMPOSE_VERSION: 1.8.1
  matrix:
    - TARGET_DISTRIBUTION=ubuntu-trusty
    - TARGET_DISTRIBUTION=ubuntu-xenial
    - TARGET_DISTRIBUTION=ubuntu-zesty
    - TARGET_DISTRIBUTION=debian-stretch
    - TARGET_DISTRIBUTION=debian-buster
    - TARGET_DISTRIBUTION=debian-sid
    - TARGET_DISTRIBUTION=centos6 EXTRA_CONFIGURE_OPTIONS="--with-ruby=/usr/bin/ruby2.2 --with-bundled-ruby-glib2"
    - TARGET_DISTRIBUTION=centos7

before_install:
  - sudo rm /usr/local/bin/docker-compose
  - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m) > docker-compose
  - chmod +x docker-compose
  - sudo mv docker-compose /usr/local/bin/

before_script:
  - docker-compose build ${TARGET_DISTRIBUTION}
  - docker-compose ps
  - docker-compose up -d ${TARGET_DISTRIBUTION}
  - docker-compose exec --user root ${TARGET_DISTRIBUTION} rsyslogd -f /etc/rsyslog.conf
  - docker-compose exec ${TARGET_DISTRIBUTION} ./autogen.sh
  - docker-compose exec ${TARGET_DISTRIBUTION} ./configure --enable-coverage --with-default-connection-spec="inet:10025@[127.0.0.1]" ${EXTRA_CONFIGURE_OPTIONS}
  - docker-compose exec ${TARGET_DISTRIBUTION} make

script:
  - docker-compose exec ${TARGET_DISTRIBUTION} ./binding/ruby/test/run-test.sh
  - docker-compose exec ${TARGET_DISTRIBUTION} ./test/run-test.sh

after_success:
  - docker-compose exec ${TARGET_DISTRIBUTION} lcov --compat-libtool --directory . --capture --output-file coverage.info
  - docker-compose exec ${TARGET_DISTRIBUTION} coveralls-lcov -v coverage.info

これでTravisCI上では一つのディストリビューションあたり7分から10分程度でテストが実行できるようになりました。トータルでは40分から60分程度かかります。 TravisCI上の実行時間の制限は、1ジョブあたり*450分なので特に問題ありませんでした。

導入してよかったこと

実際に、UbuntuやCentOSの新しいバージョンをサポートするときに、依存するライブラリのバージョンが開発環境であるDebian Sidと異なっていることが原因で修正が必要になることがありました。 直近では、Ubuntu 17.04に対応するためにGLib2.52.0以降に対応しました。この対応をした時点では、Debian SidのGLibは2.50.xでした*5

Ubuntu 17.04対応をしようとして、CIに新しいディストリビューションを追加したところ、Ubuntu 17.04だけCIに失敗したので対応が必要なことにすぐに気付くことができてとても便利でした。 デバッグするときも、ローカルでdocker-compose up -d ubuntu-zesty && docker-compose exec ubuntu-zesty bash -iとしてほぼコンテナ内で作業を完結させることができました。

まとめ

実際にパッケージを配布する環境でCIを実行することで、パッケージ作成を始める前に問題に気付くことができる可能性が上がります。これによって、パッケージ作成及びリリース作業にかかる時間を抑えることができそうです。

またUbuntuなどの新しいバージョンに対応するための最初の一手がとても簡単になりました。

*1 old stableになったのでmilter managerの次回リリースではパッケージの作成をやめます

*2 CentOS 7はi386をサポートしていないため

*3 milter managerのビルド環境を整えるという観点から、CentOS6用のDockerfileではRubyをビルドしています。

*4 matrixの1行あたり

*5 記事執筆時点で確認するとGLibは2.52.3-1に上がっていました

2017-07-27

第115回 PHP勉強会@東京:PHPでPostgreSQLとPGroongaを使って高速日本語全文検索! #phpstudy

はじめてまともにPHPを書いた須藤です。

第115回 PHP勉強会@東京で「PHPでPostgreSQLとPGroongaを使って高速全文検索!」という話をしました。

関連リンク:

内容

PGroongaを使えばPHPで簡単にリッチで高速な全文検索システムを作れるよ!ということを伝えたかったので、実際にPHPで「PHPのドキュメントを全文検索するシステム」を作ってそれを紹介しました。詳細はスライドで説明していますが、次のような機能があります。

  • 探したいものが見つかる高速全文検索機能(基本機能)
  • キーワード周辺のテキストをハイライト(基本機能)
  • 入力補完(基本機能)
    • ローマ字でも入力補完可能(リッチな機能)
      • 例:「seiki」→「正規表現」

サービスとしては動かしていないのですぐに試せませんが、ソースコードはフリーソフトウェアとして公開しているのでローカルで動かすことができます。動かし方のドキュメントは書いていませんが、標準的なLarabelの使い方だと思っているので、Larabelを使ったことがある人なら動かせるのではないかと思います。

私はこれまでまともにPHPを書いたことがありませんでしたが、3日で実装できました。簡単にリッチで高速な全文検索システムを作れることが示せたのではないかと思います。

おねがい

このイベントのために作ったPHP document searchですが、PHPユーザーにとって有用なサービスになるのではないかと思うので、だれかサービスとして運用したり、メンテナンスしたりしませんか!?私は日常的にPHPを書くことはないのでサービスとして運用する予定はないのですが、技術的なサポートはするつもりです。

興味がある方はissueで連絡してください。

まとめ

PHPユーザーにPGroongaを紹介する機会があったのでPHPのドキュメントを検索するPHP document searchを作ってそれを元にPGroongaを紹介しました。PHP document searchの運営者・メンテナーを募集しているので、ぜひご連絡ください!

おしらせ

8月1日(火)14:00-16:00にMySQL・PostgreSQL上で動かす全文検索エンジン「Groonga」セミナーを開催します。PGroongaを使いたくなった人はぜひこの機会をご活用ください!

タグ: Groonga
2017-07-20

OSS on Azure 非公式コミュニティ #5 『Azure Database』勉強会:MySQLとPostgreSQLと日本語全文検索 - Azure DatabaseでMroonga・PGroongaを使いたいですよね!? #AzureDB

品川のマイクロソフトさんのオフィスに行ったのはRubyHiroba 2013以来な気がする須藤です。

db tech showcase OSS 2017の懇親会でAzure Database for MySQL / PostgreSQLというセッションがありました。Azure DatabaseでMroongaPGroongaを使えるようになったりしませんか!?と聞いてみたところ、「月末にAzure Databaseを開発している人がくるAzure DatabaseのイベントOSS on Azure 非公式コミュニティ #5 『Azure Database』勉強会があるので、そこでMroonga・PGroongaを紹介すると話が進むかも!?」ということだったので紹介してきました。

関連リンク:

内容

この発表では次のことを紹介しました。

  • Mroonga・PGroongaが高速なこと
  • Mroonga・PGroongaはMySQL・PostgreSQLユーザーなら簡単に使えること
  • Mroonga・PGroongaはWindowsでも動くこと
  • PGroongaではJSON内のテキスト全部を全文検索できること
  • PGroongaでは簡単に入力補完を実現できること

話の最初と最後でAzure DatabaseでMroonga・PGroongaを使いたい人はどのくらいいるか聞いてみました。最初は1割くらいでしたが最後は半分くらいの人が使いたい気持ちになっていました。Azure Databaseの開発をしている方は持ち帰ってチームで検討すると言っていました。Azure Database for MySQL/PostgreSQLは今はまだプレビュー期間中ですが、一般公開時にはMroonga・PGroongaをサポートしているかもしれません。Azure Database for MySQL/PostgreSQLでMroonga・PGroongaを使いたい方はぜひAzure Databaseのサポートに「Mroonga・PGroongaを使いたい!」とフィードバックしてください。

まとめ

Azure DatabaseがMySQLPostgreSQLをサポートしようとしています。どちらも現状では日本語全文検索が苦手ですが、Azure DatabaseがMroonga・PGroongaをサポートすれば日本語全文検索が得意なDBaaSになります。まだMroonga・PGroongaをサポートすることになったわけではないので、Azure DatabaseでMroonga・PGroongaを使いたい方はサポートにフィードバックしてください。

おしらせ

8月1日(火)14:00-16:00にMySQL・PostgreSQL上で動かす全文検索エンジン「Groonga」セミナーを開催します。Mroonga・PGroongaを検討しているという方はぜひこの機会をご活用ください!

タグ: Groonga
2017-07-19

Gecko Embeddedプロジェクト

はじめに

クリアコードは、組み込みLinux向けにMozilla Firefoxのブラウザエンジンを移植するプロジェクトGecko EmbeddedWebDINO Japan(旧Mozilla Japan)様と共同で立ち上げ、開発を進めております。Yoctoを使用してFirefoxをビルドしたりハードウェアアクセラレーションを有効化する際のノウハウを蓄積して公開することで、同じ問題に悩む開発者の助けになることを目指しています。

ターゲット

組み込みLinuxと一口に言っても、対象となるハードウェア及びソフトウェア環境は多岐にわたります。 しかし投入できる開発リソースには限りがあるため、当面のターゲットは以下の環境に絞っています。

GTK+を使用せずに直接WaylandあるいはDRMで描画するバックエンドを作成した方がより組み込み向けらしいとは言えます。しかし過去の事例から考えても、Mozillaが正式にサポートするプラットフォームから大きくかけ離れたバックエンドを作成すると、その後のバージョンアップに追従するコストが高くなり、やがてはメンテナンスされなくなっていく未来が見えてしまいます。このため本プロジェクトでは、少なくとも現段階ではGTK+を使用し、成果を本体へフィードバックしていくことで、バージョンアップに追従していくコストを抑えることを目指しています。

現在のステータス

Wayland対応

Firefoxは正式にはWaylandをサポートしていませんが、Red Hat社のMartin Stransky氏がWaylandへの移植作業を行っています。 Stransky氏のパッチはFirefoxの最新バージョンを対象としていますが、Gecko Embeddedプロジェクトではこのパッチを52ESRに移植した上で、安定化作業を進めています。 本プロジェクトで発見した問題や、作成したパッチはStransky氏に随時フィードバックしています。Stransky氏のWayland対応パッチは、徐々にmozilla-centralに取り込まれていっています。

EGL対応

暫定パッチを当てることにより、EGL/OpenGL ESを使用して以下のアクセラレーションを有効化できることを確認済みです。

  • Compositor
  • Canvas
  • WebGL1

ただし上記パッチは必ずしもWaylandやGTK+の描画機構に即した形にはなっておらず、いくつかの問題を抱えているため、本体へフィードバックする際には抜本的な見直しが必要です。また、CanvasやWebGLについては安定性の面でさらなる対応が必要です。

OpenMAX IL対応

H.264の動画再生については、OpenMAX IL対応コードを追加することで動作を確認済みです。現在はまだ画像データのゼロコピーを実現できていませんが、これを実装することにより今後の性能改善が期待できます。

なお、一般的に、組み込みLinuxでの動画再生はGStreamerによって実装されますが、現在のFirefoxでは諸般の理由からGStreamer対応コードが削除されています。このため本体にコードを取り込んでもらえる可能性は低いですし、独自にGStreamer対応コードを保守するのもコストが嵩みます。一方でOpenMAX ILについてはFirefox OS用の類似のコードが残されており、保守が容易で本体へフィードバックできる可能性も高いため、現時点ではOpenMAX ILを使用する方法を選択しています。

ただし、将来的に他のボードへの対応を行う際には、OpenMAX ILコンポーネントを提供されていないボードもありますので、いずれにしてもGStreamerやその他の方法での対応が必要となるかもしれません。

ビルド方法

前述のリファレンス環境におけるビルド方法については、以下のページにまとめてあります。

CanvasやWebGLの有効化については、それぞれ以下の設定を追加する必要があります。

~/.mozilla/firefox/xxxxxxxx.default/user.js:

user_pref("gfx.canvas.azure.accelerated", true);
user_pref("webgl.force-enabled", true);

他のボードでも類似の方法でビルドできるかもしれませんが、相応の対応が必要と思われます。

デモ動画

ミラクル・リナックス社がYouTubeでデモ動画を公開して下さっています。

まとめ

Gecko Embeddedプロジェクトと現在のステータスについて紹介しました。 組み込みLinux上のFirefoxでもハードウェアアクセラレーションを有効化して、実用的なパフォーマンスを発揮できることは確認できていますが、 安定化や、さらなるパフォーマンス改善、他のSoCのサポートなど、やるべきことはまだまだ残されていますので、 興味がある方は協力して頂けるとありがたいです。問題を発見した場合はGecko EmbeddedプロジェクトのIssueページに報告して下さい。

2017-07-06

Fluentdで古くなったプラグインを検出する試み

Fluentd v0.14.xはFluentd v0.10.xのAPIがいくつか廃止されていて古いAPIを使っているプラグインが動作しなくなっています。また、他にも以下の観点でFluentd v0.14では使わない方がよい3rd party製プラグインが見つかっています。

  • 古くなっていてメンテナンスされていないもの
  • 最新のFluentdに添付されているプラグインでは、その機能が取り込まれているため使う意味がないもの
  • 対象のミドルウェアがメンテナンスされなくなっているもの
  • 対象のウェブサービスがサービス提供を終了しているもの
  • 旧バージョンのRubyでのみ意味があったもの
  • ある問題を解決するためにrubygems.orgで公開されていたが、アップストリームで対応されるなどして問題が解決されたため不要になったもの

Fluentdを使いたいユーザーがプラグインを探すときはプラグイン一覧を見ると思いますが、ここのリストは機械的に更新されています。ユーザーが使いたいプラグインをより見つけやすくするために、もう使わない方がよいプラグインをリスト化してメンテナンスしています

このリストは手動でメンテナンスされていてfluent/fluentd-websiteにPull requestを送ると取り込まれて、翌日にはウェブサイト上に反映されるはずです。

記事執筆時点では約40個のプラグインがこのリストに載っています。このリストを見れば、使わない方がよいプラグインを確認することができます。 新しく使用するプラグインを検討するときは、このリストを目視で確認していくとよいのですが、既にインストール済みのプラグインがたくさんある場合は、目視で確認するのはとても大変です。

そこでFluentd起動時に確認できるfluent-plugin-obsolete-pluginsというプラグインを作ってみました。

このプラグインは、Fluentd起動時に非推奨プラグインのリストを読み込んでその環境で利用可能なgemのリストと比較し、非推奨なプラグインがインストールされていたら警告します。このプラグイン自体はFluentd v0.14 APIを使用して実装したレコードを素通しするFilterプラグインです。v0.14 APIを使用して実装したので、Fluentd v0.12以前のバージョンでは利用できません。

Fluentd v0.14の検証のついでに、非推奨なプラグインのチェックも一緒にしてみてはいかがでしょうか。

タグ: Fluentd
2017-07-03

lessの既定のオプションを変えて快適なCLI生活を手に入れる

その時表示している内容を消さずにlessを終了するには?

何かのコマンドの実行結果が長くなって画面外に溢れてしまう場合でも、grep ... | less という風にパイプライン経由でlessコマンドに結果を渡すと、結果を自由にスクロールしながら落ち着いてゆっくり読むことができます。

しかし、「q」でlessを終了すると、その時表示されていた内容は画面から消えてしまいます。コマンドの出力結果を見ながら次の作業をしようと思うと、以下のような工夫をしないといけません。

  • Ctrl-Zでlessをバックグラウンドに切り替えて、また参照したくなったらその都度fgコマンドで復帰させる。
  • tmuxなどのターミナルマルチプレクサを使い、画面を分割して片方の画面でlessの結果を表示しながら、もう片方の画面で操作を行う。
  • コマンドの出力を直接lessに渡して表示するのではなく、一旦リダイレクトでファイルに保存して、改めて必要に応じlessでファイルを開く。

ただ、毎度こういった工夫をするのは面倒です。

そこで便利なのが、lessの起動オプションの1つである--no-init(または-X)です。このオプションを指定してlessを起動すると、topを終了したときのようにその時の表示内容が画面上に残ったままになるため、それを参照しながら次の操作を行うことができます。

常に--no-initが指定された状態でlessを起動するには?

このように便利な--no-initオプションですが、毎回このオプションを指定するというのはあまり現実的ではないでしょう。そこで便利なのが環境変数LESSです。lessLESSという名前の環境変数に指定されている内容を規定のオプションとして自動的に使用するため、~/.bashrc~/.profileなどに以下のように書いておけば、単にコマンド名をlessと入力するだけで、lessを常に--no-initオプションありの状態で起動できるようになります。

~/.bashrc
export LESS='--no-init'

察しの良い方はもうお気づきかもしれませんが、ここには--no-init意外にも様々なオプションを併せて指定しておけます。他にも便利なオプションとしてお薦めなのは--shift-#)でしょう。これは左右カーソルによる横スクロールの速度を変えるもので、既定の状態では画面半分ずつ一気に横スクロールするのに対し、--shift 4のように小さめの値を明示しておけば、スクロール速度がなだらかになるため、見ていた箇所を見失う事もなくなります。

~/.bashrc
export LESS='--no-init --shift 4'

また、--LONG-PROMPT(または-M)というオプションを使うと、現在表示されているのが何行目から何行目までの範囲なのかが画面の下端に表示されるようになります。何行目あたりを見ているかが分かると、lessで内容を大雑把に確認してからvimなどで編集するということもやりやすくなりますので、これもお薦めのオプションです。

~/.bashrc
export LESS='--no-init --shift 4 --LONG-PROMPT'

git diffgit logで起動される時のlessの挙動を元に戻す

ここまでの話で終わらせても良いのですが、これをそのまま実施すると、ソフトウェア開発者の方などでgitコマンドを多用する場合に困ったことが起こります。それは、git loggit diffgit grepといった操作で自動的に起動されるlessの挙動が変わってしまうということです。具体的には、以下のような問題が起こります。

  • 結果が1画面内に収まるような場合(git diffの差分が小さかった場合や、git grepで見つかった件数が少なかった場合など)でもlessが起動してしまって、いちいち手動操作で「q」キーでlessを終了しなくてはならなくなる。
  • 結果の中にESC[33mのようなゴミが混ざるようになる。

これは何故なのでしょうか。

gitlessを起動する時の既定のオプション

実は、gitコマンドには自動的にlessを起動する場面用の既定のオプションが埋め込まれています。これはMakefileの中で以下のように定義されています。

ifndef PAGER_ENV
PAGER_ENV = LESS=FRX LV=-c
endif

ここでのLESS=FRXというのがそうで、これがgitコマンドの起動時に実行されるスクリプトの中

for vardef in @@PAGER_ENV@@
do
	var=${vardef%%=*}
	eval ": \"\${$vardef}\" && export $var"
done

という箇所に埋め込まれて、最終的に: "${LESS=FRX}" && export LESSというコマンドが実行されることで、「環境変数LESSで何かオプションが指定されていればそれをそのまま使い、無ければ既定のオプションとしてFRXを使う」という事が行われています。

FRX-F -R -Xの短縮表記で、それぞれロングオプションで書き表すと--quit-if-one-screen --RAW-CONTROL-CHARS --no-initとなります。

--quit-if-one-screen-F)は、前述の1つ目の問題(結果が1画面内に収まるような場合でもlessが起動してしまう)を解消するための指定です。このオプションが指定されていると、lessは表示した内容が1画面内に収まる場合にそのまま自動終了するようになります。これと--no-init-X)の併用により、あたかも「結果が長い時だけlessが起動され、結果が短い時はlessを使わずそのまま出力される」かのような挙動になっていたというわけです。

--RAW-CONTROL-CHARS-R)は、2つ目の問題(ESC[33mのようなゴミが混ざる)を解消する指定です。実はESC[33mなどのゴミのように見える文字列は文字の表示色を変えるための制御コードで、--RAW-CONTROL-CHARSオプションが指定された場合、lessはこの制御コードに基づいて文字の色変えや強調表示を行うようになります。

gitから起動されるlessの挙動を戻す2つの方法

以上の事を踏まえて、git diffgit grepの時のlessの挙動を元に戻す方法は2通り考えられます。

1つは、不足していたオプションを環境変数LESSで指定するようにする方法です。

~/.bashrc
export LESS='--no-init --shift 4 --LONG-PROMPT --RAW-CONTROL-CHARS --quit-if-one-screen'

lessの既定の挙動が全般的に変わってしまっても問題なければ、これが一番簡単でしょう。

全般的な既定の挙動を変えずにgitから起動された時の挙動だけを変えたい場合は、git configでこれらのオプションを加えた状態のlessをページャとして明示的に設定するという方法があります。

$ git config --global core.pager 'less --RAW-CONTROL-CHARS --quit-if-one-screen'

この場合、gitから起動されたlessはここで指定されたオプションと環境変数LESSで指定されたオプションの効果がマージされた挙動となります。

まとめ

以上、lessの既定のオプションの指定の仕方とお薦めの設定、そしてgitとの組み合わせでの注意点をご紹介しました。

lessにはここで登場した物以外にも様々なオプションがあります。man lessを見ながら必要なオプションを環境変数LESSに設定して、普段の作業効率の向上に繋げてください。

タグ: Git
2017-06-27

LaravelでPostgreSQLとPGroongaを使って日本語全文検索を実現する方法

はじめに

※この記事は、Laravelを使った開発の経験がある人を対象としています。Laravelの基本的な使い方自体の説明は含まれていませんので、ご注意下さい。

Webアプリケーションを開発していると、「検索窓に入力された語句を含むレコードを一覧表示する」といった機能を付けたくなる場面がよくあります。この時よく使われる手軽な方法としてSQLのLIKEがありますが、LIKEには検索対象のレコードの数が増えれば増えるほど処理に時間がかかるという欠点があります。そこで登場するのが全文検索という手法です。全文検索では事前に用意しておいたインデックス情報を使うことにより、レコード数が増加しても安定して高速な検索を行うことができます。サービスの利用者が増加して数万・数十万といった数のレコードを取り扱うような必要が生じてきた場合、全文検索の導入を検討する価値は十分にあるでしょう。

以前、Ruby on Railsで作ったアプリケーションからPGroongaを使って日本語全文検索機能を実現する方法を紹介しました。今回はそのPHP版として、Laravelで作ったブログ風のアプリケーションにPGroongaを使った日本語全文検索機能を組み込む方法をご紹介します。

この記事では、適当なLaravelアプリケーションが手元に無い場合を想定し、解説用に用意したLaravelアプリケーションとPostgreSQLとの組み合わせに対して、全文検索機能を組み込む手順を解説しています。すでに開発中・運用中のPostgreSQLを使用したアプリケーションがある場合には、そのアプリケーションに組み込む手順としてテーブル名等を適宜読み替えて下さい。

また、タイトルにも書いてある通りですが、この記事で紹介しているPGroongaは、PostgreSQLに対して全文検索機能を提供するソフトウェアです。開発・運用中のアプリケーションがPostgreSQL以外のデータベースを使用している場合にはPGroongaを使えませんので、くれぐれもご注意下さい。(他のデータベースを使っている場合、例えばMySQLやMariaDBであれば、PGroongaの代わりにMroongaを使うことになります。その場合の手順はここでは解説していませんので、あしからずご了承ください。)

開発環境の準備

それでは、開発環境を用意していきます。まず、以下の2つを用意します。

  • Homesteadを動作させるホストマシン(ここではUbuntu 16.04LTSと仮定します)
  • 動作確認用のWebブラウザが動作するクライアント

ホストマシンとしてLinuxのデスクトップ環境を用意して、ホストマシン自身をクライアントとして使うのが最も簡単です。別々のマシンを使う場合には、両者は同じネットワーク上に存在するか、もしくはホストマシンのネットワーク上の任意のコンピュータにクライアントから自由に接続できるものとします。

Laravelには開発環境を簡単に構築するためのHomesteadという枠組みがあり、今回はそれを使ってみることにします。Vagrantが必要なので、事前にホストマシンにVagrant 1.9以上VirtualBoxをインストールしておいて下さい。

VMの準備(ホストマシン上の操作)

開発環境のboxイメージが公開されているので、まずはそれを導入します。

% vagrant box add laravel/homestead
==> box: Loading metadata for box 'laravel/homestead'
box: URL: https://atlas.hashicorp.com/laravel/homestead
This box can work with multiple providers! The providers that it
can work with are listed below. Please review the list and choose
the provider you will be working with.

1) parallels
2) virtualbox
3) vmware_desktop

ここではVirtualboxのイメージを使うので2を選択します。

Enter your choice: 2
==> box: Adding box 'laravel/homestead' (v2.1.0) for provider: virtualbox
box: Downloading: https://atlas.hashicorp.com/laravel/boxes/homestead/versions/2.1.0/providers/virtualbox.box
==> box: Successfully added box 'laravel/homestead' (v2.1.0) for 'virtualbox'!
vagrant box add laravel/homestead 14.75s user 7.42s system 19% cpu 1:53.24 total

boxを正常にダウンロードできたので次に進みます。

Homesteadの準備(ホストマシン上の操作)

Homesteadのリポジトリを以下のようにホストの作業ディレクトリにcloneします。

% mkdir ~/work
% cd ~/work
% git clone https://github.com/laravel/homestead.git

masterブランチは不安定な場合があるため、今回はリリースブランチを使います。

% cd homestead
% git checkout v5.4.0
...
HEAD is now at f54a9f0... Tagging 5.4.0 (#595)
(END):
Homestead.yamlの準備(ホストマシン上の操作)

ホストにて init.sh を実行します。

% bash init.sh
Homestead initialized!

すると以下の3つのファイルが同じディレクトリに作成されます。

  • Homestead.yaml
  • after.sh
  • aliases

Homestead.yaml はVMの設定ファイルです。

今回は以下の項目を変更します。

  • ip: 異なるネットワークのIPアドレスを指定する。(ホストマシンが接続しているネットワークが192.168.10.0/24なら、192.168.20.0/24などのアドレスにする)
  • authorize: ホストマシンで作成したsshの公開鍵のパスを指定する。
  • keys: ホストマシンで作成したsshの秘密鍵のパスを指定する。
  • folders: ホストマシンのディレクトリーをゲスト上から見えるようにする指定だが、ホストマシン上にはLaravelアプリケーション用のファイルを設置しないため不要なので、コメントアウトする。
  • sites: ゲスト上にこれから作成するアプリケーションに合わせてパスを書き換える。
  • networks: ゲストがホストマシンが接続しているネットワークにブリッジ接続するための設定を追加する。

上記変更を反映した Homestead.yaml は次の通りです。

Homestead.yaml
---
ip: "192.168.20.10" # ホストマシンと異なるネットワークになるようにする。
memory: 2048
cpus: 1
provider: virtualbox

authorize: ~/id_homestead.pub #公開鍵のパス

keys:
    - ~/id_homestead #秘密鍵のパス

#folders:
#    - map: ~/work/Blog
#      to: /home/vagrant/Blog

sites:
    - map: homestead.app
      to: /home/vagrant/Blog/public # 後々、この位置にファイルが作られる。

databases:
    - homestead

networks:
    - type: "public_network"
      bridge: "eth0" # "wlan0"など、ホストマシンの主なインターフェースに合わせる。

IPアドレスやブリッジのインタフェース名、鍵の情報は環境に応じて適宜読み替えてください。

VMの起動(ホストマシン上の操作)

設定ファイルとコマンドの準備ができたので、ホストマシンからVMを起動します。

% vagrant up

設定に問題なければVMが正常起動します。 続けて、クライアントからゲスト上のLaravelアプリケーションに接続するために、起動したVMのブリッジ接続でのIPアドレスを調べます。

% host_if=eth0
% host_nw="$(ip addr | grep -o "inet.*$host_if" | cut -d ' ' -f 2 | cut -d '.' -f -3)."
% vagrant ssh -- ip addr | grep "$host_nw"
    inet 192.168.10.52/24 brd 192.168.10.255 scope global enp0s9

この例では192.168.10.52が割り当てられているので、クライアントからは http://192.168.10.52/ をブラウザで開けば動作を確認できることになります。

hostsファイルの編集(クライアント上の操作)

http://192.168.10.52/のようなIPアドレスの直接入力は煩雑なので、クライアントのhostsファイルを編集して、homestead.appというホスト名で参照できるようにしておきます。クライアントのhostsに以下の内容を書き足しましょう。

192.168.10.52 homestead.app

クライアントがUbuntuのデスクトップ環境の場合、hostsは /etc/hostsです。クライアントがWindowsの場合は、hostsは C:\windows\system32\drivers\etc\hosts の位置にあります。

以上で準備完了です。クライアント上のWebブラウザで http://homestead.app/ を開いてみて下さい。以下のようなエラーページが表示されるはずです。

(エラーページのスクリーンショット)

これはHomestead上のnginxが返しているエラーで、所定の位置にまだLaravelアプリケーションが存在していないという事を示しています。

Laravelアプリケーションのセットアップ

それではLaravelによるブログ風のアプリケーションを用意していきます。といっても、Laravelでのブログ風アプリケーションの開発の仕方そのものはここでは重要ではないので、あらかじめこちらで用意したサンプルのブログ風アプリケーションを使うことにしましょう。

まず、ホストマシンからゲストマシンへsshでログインします。

% vagrant ssh
vagrant@homestead:~$

そうしたら、サンプルアプリケーションのGitリポジトリをcloneします。この時、clone先のディレクトリ名をBlogと明示して、ファイルの設置先がホストマシン上のHomestead.yamlの内容と一致するようにする必要があることに気をつけて下さい。

vagrant@homestead:~$ git clone https://github.com/clear-code/pgroonga-example-laravel.git Blog

cloneし終えたら、アプリケーションを初期化します。

vagrant@homestead:~$ cd Blog
vagrant@homestead:~/Blog$ composer install
vagrant@homestead:~/Blog$ php artisan migrate
vagrant@homestead:~/Blog$ php artisan db:seed
サンプルアプリケーションの仕様

以上の手順をすべて実施したら、クライアントから http://homestead.app/posts を開いてみて下さい。以下のような記事一覧ページが表示されるはずです。

(サンプルアプリケーションのスクリーンショット)

Homestead.yamlの設定(例えば、Laravelのアプリケーションの設置先パス)を間違えていると、先のエラーページと同じ物が表示されるかもしれません。その場合、Homestead.yamlを修正してから vagrant provision を実行し、ゲスト上のnginx等を再起動する必要があります。

記事一覧ページの右上にある検索窓に「Groonga」のようなキーワードを入力すると、そのキーワードの検索結果として、postsテーブルのレコードのうちbodyカラムにキーワードを含むレコードの一覧が表示されます。ただ、コントローラの実装(app/Http/Controllers/PostController.php)を見ると分かりますが、これは以下のような単純なSQLのLIKEによる絞り込みの結果です。Groonga OR Mroongaのような凝った検索は行えません。

app/Http/Controllers/PostController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostController extends Controller
{
  public function index(Request $request)
  {
    $query = $request->get('query');
    if (!empty($query)) {
      $posts = \App\Post::where('body', 'like', "%{$query}%")->orderBy('id', 'desc')->get();
    }
    else {
      $posts = \App\Post::orderBy('id', 'desc')->get();
    }
    return \View::make('posts.index')
             ->with('posts', $posts)
             ->with('query', $query);
  }
}
注意点

Homesteadの環境で普通にlaravel new Blogすると、MySQLを使うように設定されたLaravelアプリケーションが作られます。しかし今回はPGroongaの使い方の解説なので、この例では以下のように.envを編集して、データベースにはPostgreSQLを使うよう設定してあります。

commit 5f48f346ccf36e07aefdf062b2f374d83dc6151d
Author: YUKI Hiroshi <yuki@clear-code.com>
Date:   Mon Jun 26 01:56:56 2017 +0000

    Use PostgreSQL by default

diff --git a/.env b/.env
index f41ce19..ceaa34d 100644
--- a/.env
+++ b/.env
@@ -5,9 +5,9 @@ APP_DEBUG=true
 APP_LOG_LEVEL=debug
 APP_URL=http://localhost
 
-DB_CONNECTION=mysql
+DB_CONNECTION=pgsql
 DB_HOST=127.0.0.1
-DB_PORT=3306
+DB_PORT=5432
 DB_DATABASE=homestead
 DB_USERNAME=homestead
 DB_PASSWORD=secret
diff --git a/config/database.php b/config/database.php
index cab5d06..abf3d43 100644
--- a/config/database.php
+++ b/config/database.php
@@ -13,7 +13,7 @@ return [
     |
     */
 
-    'default' => env('DB_CONNECTION', 'mysql'),
+    'default' => env('DB_CONNECTION', 'pgsql'),
 
     /*
     |--------------------------------------------------------------------------

冒頭にも述べていますが、PGroongaはPostgreSQLに対して全文検索機能を提供する物なので、それ以外のデータベースに対しては使えません。ご注意下さい。

PGronngaによる全文検索機能の組み込み(ゲスト上での作業)

お待たせしました! ようやくここからが本題です。

すでにあるLaravelアプリケーションでPGroongaを使って全文検索をするには、以下の4つのステップを踏みます。

  1. PGroongaのインストール
  2. PGroongaの有効化
  3. インデックスの作成
  4. PGroongaを使って検索するように問い合わせ部分を変更

それでは順番に見ていきましょう。

PGroongaのインストール

何はともあれPGroongaのインストールが必要です。Homesteadの環境はUbuntu 16.04ベースということで、今回はUbuntu用のインストール手順を参照しました。以下は実際に実行したコマンドです。

$ sudo add-apt-repository -y universe
$ sudo add-apt-repository -y ppa:groonga/ppa
$ sudo apt-get update
$ sudo apt-get install -y -V postgresql-9.5-pgroonga

PGroongaのインストール手順は実行環境によって異なります。Ubuntu 16.04以外の環境でのインストール手順については、PGroongaのプロジェクトサイトで公開されているインストール手順の説明を参照して下さい。

PGroongaの有効化

PGroongaは、サーバー上にパッケージをインストールしただけでは使えません。機能を利用するには、PostgreSQLのデータベースに対してCREATE EXTENSION pgroonga;というSQL文を明示的に実行する必要があります。

ということで、このSQL文を実行するためのマイグレーションを作成します。

$ php artisan make:migration install_pgroonga
Created Migration: 2017_06_23_091529_install_pgroonga
database/migrations/2017_06_23_091529_install_pgroonga.php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class InstallPgroonga extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
      // ここから追記
      DB::statement('CREATE EXTENSION pgroonga');
      // ここまで追記
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
      // ここから追記
      DB::statement('DROP EXTENSION pgroonga CASCADE;');
      DB::statement('DELETE FROM pg_catalog.pg_am WHERE amname = \'pgroonga\';');
      // ここまで追記
    }
}

upに書かれている内容はPGroongaのインストール手順にあるもので、downに書かれている内容はアンインストール手順にあるものです。

用意ができたら、このマイグレーションを実行します。

$ php artisan migrate

これでPGroongaを使う準備ができました。

検索対象のカラムに全文検索用のインデックスを作成する

次に、PGroongaで全文検索するためのインデックスを作ります。

Laravelのマイグレーションではindexメソッドでインデックスを定義します。

$ php artisan make:migration add_posts_body_index
Created Migration: 2017_06_23_091530_add_posts_body_index
database/migrations/2017_06_23_091530_add_posts_body_index.php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddPostsBodyIndex extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
      // ここから追記
      Schema::table('posts', function($table) {
        $table->index(['id', 'body'], 'pgroonga_body_index', 'pgroonga');
      });
      // ここまで追記
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
      // ここから追記
      Schema::table('posts', function($table) {
        $table->dropIndex('pgroonga_body_index');
      });
      // ここまで追記
    }
}

PGroongaを正しく使えているという事を説明するために、PGroongaのチュートリアルで説明されている内容との対応関係を見ていきます。 このチュートリアルでの説明に倣うと、インデックス作成用のSQL文は以下のようになります。

CREATE INDEX pgroonga_body_index ON posts USING pgroonga (id, body);

ここで、pgroonga_body_indexはPGroongaでの慣習に倣って付けた任意のインデックス名、postsはテーブル名です。USING pgroonga (id, body)は、インデックスの種類としてHashやB-treeなどと同列の物としてPGroongaを選択し、インデックスにはid(主キー)とbodyの両方を含めるという意味になっています。

database/migrations/2017_06_23_091530_add_posts_body_index.php
  Schema::table('posts', function($table) {
    $table->index(['id', 'body'], 'pgroonga_body_index', 'pgroonga');
  });

Laravelのマイグレーションでは、テーブル名はSchema::table('posts'...の部分で示されています。indexメソッドでインデックスを作成しており、この第1引数の['id', 'body']がインデックスに含めるカラム名の配列、第2引数がインデックス名、第3引数がインデックスの種類を示しています。PGroongaのチュートリアルで説明されている情報が過不足無く指定できていることが分かるでしょう。

なお、インデックス名を省略してnullにするとインデックス名を自動的に決定させることもできますが、downのマイグレーションでインデックス名を指定してdropIndexメソッドを呼ぶ都合上、ここではインデックス作成時にも明示的にインデックス名を指定しています。

そして、マイグレーションを実行します。

$ php artisan migrate

これによって、postsテーブルのbodyカラムを対象とした全文検索用のインデックスが作成されます。既存のレコードに対するインデックスもこの時一緒に作成されますし、この後で作成されたレコードに対しても自動的にインデックスが作成されるようになります。

以上で、全文検索の準備が整いました。

PGroongaを使って検索するように問い合わせ部分を変更

最後に仕上げとして、全文検索にPGroongaを使うように検索処理を書き換えます。

app/Http/Controllers/PostsController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostsController extends Controller
{
  public function index(Request $request)
  {
    $query = $request->get('query');
    if (!empty($query)) {
      // 変更前
      // $posts = \App\Models\Post::where('body', 'like', "%{$query}%")->orderBy('id', 'desc')->get();
      // 変更後
      $posts = \App\Models\Post::whereRaw('body @@ ?', $query)->orderBy('id', 'desc')->get();
    }
    else {
      $posts = \App\Models\Post::orderBy('id', 'desc')->get();
    }
    return \View::make('posts.index')
             ->with('posts', $posts)
             ->with('query', $query);
  }
}

PGroongaで全文検索をするためには、PGroonga専用の演算子を使います。whereメソッドではそれらの演算子を取り扱えないので、ここではwhereRawメソッドを使ってSQLの式を直接書いています。

今回使った@@という演算子(この演算子はPGroongaの現在のドキュメントでは&?で置き換えられていることになっていますが、&?PHPの実装上の都合で使えないため、非推奨のこちらを使用しています)は、与えられた検索クエリを一般的なWebの検索エンジンの検索クエリのように取り扱う物です。よって、Groonga リリース(Groongaとリリースの両方の語を含む)やGroonga OR PGroonga(GroongatoPGroongaのどちらか片方だけでも含む)や( Mroonga OR PGroonga ) リリース(MroongaかPGroongaのどちらか片方に加えて、リリースという語句を含む)のような複雑なクエリも、検索窓に入力するだけでそのまま使うことができます。

(複雑なクエリで検索した状態のスクリーンショット)

以上で、PGroongaによる全文検索への乗り換えが完了しました。実際に検索を実行して、期待通りの結果が返ってくるか確かめてみて下さい。

まとめ

以上、LaravelアプリケーションでPGroongaを使って全文検索を行う手順の語句最初のステップをご紹介しました。

この解説を見ると分かる通り、すでにPostgreSQLを使っている環境であれば、PGroongaを使い始めるのは非常に簡単です。また、アプリケーション内の変更はごく一部だけで済むため、LIKE検索との性能比較もやりやすいでしょう。全文検索を使ったことがない人は、これを機にぜひ一度試してみて下さい。

タグ: Groonga
2017-06-26

2008|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|
タグ:
RubyKaigi 2015 sponsor RubyKaigi 2015 speaker RubyKaigi 2015 committer RubyKaigi 2014 official-sponsor RubyKaigi 2014 speaker RubyKaigi 2014 committer RubyKaigi 2013 OfficialSponsor RubyKaigi 2013 Speaker RubyKaigi 2013 Committer SapporoRubyKaigi 2012 OfficialSponsor SapporoRubyKaigi 2012 Speaker RubyKaigi2010 Sponsor RubyKaigi2010 Speaker RubyKaigi2010 Committer badge_speaker.gif RubyKaigi2010 Sponsor RubyKaigi2010 Speaker RubyKaigi2010 Committer
SapporoRubyKaigi02Sponsor
SapporoRubyKaigi02Speaker
RubyKaigi2009Sponsor
RubyKaigi2009Speaker
RubyKaigi2008Speaker