2011年 8月 の投稿一覧

全文検索エンジンgroongaを使ってみる(1) – インストール

休暇中に何らかの全文検索エンジンを入れて触ってみようと決めていたのでGroongaを入れてみた。

特徴

Groongaの特徴は以下の様なところがある。

  • 操作は複数のプロトコルが利用可能
    • 独自プロトコル or HTTP or memcached binaryプロトコル
    • HTTPの場合, GETリクエストで各種クエリを投げる形。結果はJSONで得られる。
  • データ更新が高速
    • 前身のSennaMySQLMyISAMに依存していたので更新時にテーブル全体にロックがかかってボトルネックになっていたのを独自ストレージを実装したので問題が解消
  • 集計系のクエリ処理が高速
    • ドリルダウン(検索結果をグループ分けする様な処理)を高速に行うことができる
  • 管理ツール利用可能
    • phpMyAdminの様なツールが標準で付いている (HTTPを利用する設定でGroongaサーバを起動させた場合)
  • サジェスト機能
    • 渡された検索クエリを元におすすめのクエリーをユーザに提案できる
      • Groongaサーバが検索クエリー入力時を含めログに回収し、それを元に提案する
  • 検索スコアの調整
    • Groongaが検索結果として返却したスコアに対して検索スコアを調整することができる。(独自のパラメータを重みとして検索結果に反映させられる)

といった具合。
簡単に触ってみたところ、検索スコアの調整が非常にしやすい印象を持ったし、HTTPで制御できるのが非常に便利といった実感を持った。

インストール

インストールは、このページを参照するとそれぞれの環境にあわせたインストール方法が紹介されているので参照しながら導入する。
Macの場合、Macports or Homebrew が選択できるので、ここではHomebrewを使ってみる。
brewコマンドですぐにインストールが可能。

% brew install groonga
Warning: It appears you have Macports or Fink installed
Software installed with other package managers causes known problems for
Homebrew. If formula fail to build uninstall Macports/Fink and reinstall any
affected formula.
==> Downloading http://packages.groonga.org/source/groonga/groonga-1.2.4.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/groonga/1.2.4 --with-zlib
==> make install
/usr/local/Cellar/groonga/1.2.4: 590 files, 12M, built in 7.1 minutes

インストール完了後、groongaコマンドでインストールを確認できる。

% groonga --version
groonga 1.2.4 [darwin9.8.0,i386,utf8,match-escalation-threshold=0,nfkc,mecab,zlib,kqueue]

configure options: < '--prefix=/usr/local/Cellar/groonga/1.2.4' '--with-zlib' 'CC=/usr/bin/cc' 'CFLAGS=-O3 -march=nocona -mfpmath=sse -w -pipe' 'CXX=/usr/bin/c++' 'CXXFLAGS=-O3 -march=nocona -mfpmath=sse -w -pipe'>

これでインストール完了。
もう少しいろいろ触ったのだけど、激しくお腹が痛いので今日はここまで。

homebrew導入

f:id:hideack:20110816143245p:image

Macにhomebrew入れた。
homebrewMacPortsと同じくパッケージ管理ツールでRubyで記述されている。
たまたま試したいと思っていたプログラムの配布パッケージにhomebrewが用意されていたので使ってみた。

% /usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)"

但し、環境によっては以下の様な表示が出て利用するcurlコマンドのSSL証明書の問題でインストールができない場合がある。
(GithubにHTTPS接続しなければならないのだけど、手元にあるcurl用の証明書ではSSL証明できない場合)

error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

curlのオプションで -k を指定すれば、SSL証明書の確認をスキップ*1できるのだが、更にインストールのステップを踏んでいくと、その中でcurlコマンドが更に呼ばれることが生じるので、根本的に証明書の問題を解決しておく必要がある。

お手軽な解決策がQAに出ていたので、それを参考して解決した。
以下の手順で証明書をcurlに設定しておけばSSL証明書の確認時のエラーは回避される。*2

% wget --no-check-certificate https://www.digicert.com/testroot/DigiCertHighAssuranceEVRootCA.crt;
% cat /usr/share/curl/curl-ca-bundle.crt DigiCertHighAssuranceEVRootCA.crt > new-ca-bundle.crt;
% sudo mv /usr/share/curl/curl-ca-bundle.crt /usr/share/curl/curl-ca-bundle.crt.old;
% sudo mv new-ca-bundle.crt /usr/share/curl/curl-ca-bundle.crt

これでbrewのインストールが行えるはずなので、インストールを行えばbrewコマンドが利用できる様になる。
お約束的なのは、brewコマンドを単独で実行するとusageが出力されるので参照。
以下、利用例、

% brew info ruby
ruby 1.9.2-p290
http://www.ruby-lang.org/en/
Depends on: readline, libyaml
Not installed

Consider using RVM or Cinderella to manage Ruby environments:
* RVM: http://rvm.beginrescueend.com/
* Cinderella: http://www.atmos.org/cinderella/

NOTE: By default, gem installed binaries will be placed into:
/usr/local/Cellar/ruby/1.9.2-p290/bin

You may want to add this to your PATH.

参照: Brew Install results in Curl SSL certificate problem on Formula with GitHub HTTPS tarball URL

*1:結果は自己責任。本来は行うべきではない。

*2:あくまでも自己責任。本来は信頼できるブラウザからルート証明書をエクスポートして設定するのが本筋か。

PHPでクローラを書く

PHPでクローラを書くときのライブラリないかな?と探したところ、sourceforgeで見つけたので使ってみた。結構、出来が良くて少し触ってみた感じ便利そうな雰囲気。

PHPCrawl
PHPCrawl is a webcrawler/webspider-library written in PHP. It supports filters, limiters, cookie-handling, robots.txt-handling and other features.

ダウンロードして展開した際に含まれているexample.phpを見ると、それが全てだったりするのだけど、一応以下にサンプルファイルを一部抜粋して掲載。
どの様な形で実装できるかがわかると思う。

<?php
// Inculde the phpcrawl-mainclass
include("classes/phpcrawler.class.php");
// Extend the class and override the handlePageData()-method
class MyCrawler extends PHPCrawler
{
function handlePageData(&$page_data)
{
// --- ここにコンテンツがクロールされた際の挙動を実装する
// Print the URL of the actual requested page or file
echo "Page requested: ".$page_data["url"]."\n";
// Print the first line of the header the server sent (HTTP-status)
echo "Status: ".strtok($page_data["header"], "\n")."\n";
// Print the referer
echo "Referer-page: ".$page_data["referer_url"]."\n";
// Print if the content was be recieved or not
if ($page_data["received"]==true)
echo "Content received: ".$page_data["bytes_received"]." bytes";
else
echo "Content not received";
echo "\n\n";
flush();
}
}
$crawler = &new MyCrawler();
$crawler->setURL("www.yahoo.com");  // クロール対象のWebサイト
$crawler->addReceiveContentType("/text\/html/");    // クローラで取り込む対象のContentType
$crawler->addNonFollowMatch("/.(jpg|gif|png)$/ i");  // 探索除外のファイル拡張子
$crawler->setTrafficLimit(1000 * 1024);
$crawler->go();
?>

いろいろ楽しいことできそうだな。