OpenSearchのxmlファイルにはGoogleやAmazonのようにsuggestをするための記述を書くことができる。そのURLにアクセスするとJSON形式で結果が返り、サジェストされるというもの。FirefoxでURLの右側にある検索窓に何か打ち込んでいると候補が出てくるアレです。
こんにちでは、いろいろなサイトがsuggestの機能に対応している。代表的なものは以下の通り。
http://suggestqueries.google.com/complete/search?client=firefox&hl=ja&qu={searchTerms} | |
Goo | http://search.goo.ne.jp/suggest.jsp?fm=json&ie={inputEncoding}&MT={searchTerms} |
Wikipedia(ja) | http://ja.wikipedia.org/w/api.php?action=opensearch&search={searchTerms} |
Amazon | http://completion.amazon.co.jp/search/complete?method=completion&search-alias=aps&mkt=6&q={searchTerms} |
Yahoo(JP) | http://api.search.yahoo.co.jp/AssistSearchService/V2/webassistSearch?output=fxjson&ei={inputEncoding}&p={searchTerms} |
NAVER | http://ac.naver.jp/ac?r_format=opensearch&q_enc={inputEncoding}&r_enc={outputEncoding}&q={searchTerms} |
Yahoo! Transit(駅名) | http://transit.map.yahoo.co.jp/suggest/search.php?q={searchTerms} |
Yahoo! Transitの駅名はJSONではなくてSpace-separeted textですね。
GoogleやAmazonのAPIにアクセスするようにOpenSearchのXMLファイルを書いてもいいけど、自前で用意するにはどうしたらいいのか。
自分のエントリを形態素解析して単語を抜き出し、検索すればいいんじゃないかな。あんまり高度なアルゴリズムは必要ないだろう。
というわけで、やってみた。
うちのサーバはCentOS5系なので、まずは関連するファイルのインストール。
HTMLのパースに使うlxml、DBの操作に使うSQLObjectはEPELから入る。
- yum install python-lxml python-sqlobject
形態素解析のMeCabはEPELに入っていないので、Fedoraのsrc.rpmをコンパイルし直す。Fedoraのrpmはチェックサムのアルゴリズムが変わったので、rpmコマンドでは不正とみなされてしまう。そのためrpm2cpio|cpioでファイルを取り出す。
- cd /path/to/rpmdir/SOURCES/
- rpm2cpio mecab-0.98-1.fc11.src.rpm| cpio –i
- rpmbuild –bb mecab.spec
- sudo rpm –ivh ../RPMS/i386/mecab*
IPAの辞書とjumanの辞書、python-mecabも同様に入れておく。
- rpm2cpio mecab-ipadic-2.7.0.20070801-2.fc11.src.rpm | cpio –i
- rpmbuild –bb mecab-ipadic.spec
- sudo rpm –ivh ../RPMS/i386/mecab-ipadic*
- rpm2cpio mecab-jumandic-5.1.20070304-3.fc11.src.rpm | cpio –i
- rpmbuild –bb mecab-jumandic.spec
- sudo rpm –ivh ../RPMS/i386/mecab-jumandic*
- rpm2cpio python-mecab-0.98-1.fc11.src.rpm | cpio –i
- rpmbuild –bb python-mecab.spec
- sudo rpm –ivh ../RPMS/i386/python-mecab*
suggestはJSONで返す必要がある。最近のPythonにはjsonは標準ライブラリに同梱だが、CentOS5のPython 2.4.3には入ってない。そこで、いくつかEPELにあるpython用のjsonライブラリの中から、Unicodeへの対応がまともそうなpython-simplejsonを選択。
- yum install python-simplejson
簡単なテスト。
Python 2.4.3 (#1, Sep 3 2009, 15:37:12) [GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import json >>> json.write([1,2,3,'あa']) '[1,2,3,"\xe3\x81\x82a"]' >>> import cjson >>> cjson.encode([1,2,3,'あa']) '[1, 2, 3, "\\u00e3\\u0081\\u0082a"]' >>> import simplejson >>> simplejson.dumps([1,2,3,'あa']) '[1, 2, 3, "\\u3042a"]'
ここまでが前準備。
適当にPythonのスクリプトを書く。文書のソースはMovableType、Wordpress、IMAP、trac(wiki/ticket)、生のファイルあたりに対応。サービスはCGI、WSGIあたりに対応させた。
関連する単語は「隣りの名詞」同士にスコアをつけて算出している。2語まで。
DBの使い方は、「リレーショナル」DBなんだから、リレーションを(MultipleJoinとかで?)書いた方がいいとも思ったんだけど、単語IDの関連をスコアにしてみた。
あとはOpenSearchのXMLに追加して…試しにこのブログのエントリでsuggest用のDBを作ってWSGIで実行するようにしてみてます。ページ内の検索ボックスは非対応。