Help us understand the problem. What is going on with this article?

GroongaのUTF-8なDBに対してShift_JIS(cmd.exe)で全文検索する3つの方法

More than 3 years have passed since last update.

Groonga Advent Calendar 20152日目の記事です。1日目はyoku0825さんのMySQLで日本語全文検索ができるMroongaのDockerリポジトリーをメンテナンスしていますでした。いつもお世話になっています!

はじめに

groonga-devというメーリングリストで、GroongaのUTF-8のデータベースに対して
コマンドプロンプト(cmd.exe)から日本語を使うにはどうしたらよいか、という話題がありました。

普通にやると、UTF-8のデータベースに対してShift_JISで検索に行ってしまうので、
文字コードの違いのせいでうまく検索できません。

まず思いつくのはコマンドプロンプトの文字コードをUTF-8に設定することですが、
期待する結果は得られませんでした。詳しいことはわかりませんが、以下の原因が考えられます。

  • データベースにはShift_JISで渡ってしまうので、検索にヒットしない
  • フォントがなくて文字が消えてしまう
  • 出力時に文字化けしてしまう

Groongaに限らず、いろいろなソフトウェアで起こりうる問題ではないでしょうか。

最近はLinuxを使っている私ですが、昔はWindowsで生活していたので、昔の記憶を掘り起こしながら
考えてみました。みなさんも考えてみてください。

A. 日本語を使わない

いくらShift_JISとはいえ、日本語を使わなければ文字化けする心配はありません。
余談ですが、来年からTOEICの出題形式が変わって点が取りづらくなるようです。
私は受けたことありませんが。

B. データベースの文字コードをShift_JISにする

これが一番オススメです。すべて同じ文字コードで統一してしまえば文字化けの心配はありません。

Groongaの場合は、データベース作成時--encodingオプションを指定することでデータベースの
文字コードを変更することができます(デフォルトはUTF-8)。

> groonga -n --encoding sjis test.db

とはいえ、既存のデータベースがある場合はデータベースを作り直す必要があるので、
選びづらい選択肢ではあります。

C. 何かで文字コードを変換する

何か別のツールを使用して、入力をUTF-8に変換してからデータベースに渡してやる方法です。

この方法ならデータベースを作り直す必要はありません。ただし、ツールによってはインターフェイスが
大幅に変わってしまうため、過去の資産が使えなくなってしまうおそれがあります。

この話題ではgroongaコマンドによる対話型インターフェイス(REPL)が使われていたので、
同じようなインターフェイスにするのが無難です。

私はRubyが好きなので、Rubyを使ってツールを作ってみることにしました。

既存ツールを調べたところgroongaコマンドをPryの上で - Qiitaがとてもよさそうだったので、
これを参考にPryを使って作ろうとしたのですが、一朝一夕では難しそうだったので諦めました。
余談ですが、締め切りの「締」と諦めの「諦」は似ていますね。

そこでもっとシンプルな方法を探していたところ、Rubyの標準添付ライブラリにReadlineがある
のを見つけました。

http://docs.ruby-lang.org/ja/search/version:2.2.0/query:readline/

使い方も簡単そうだったので、これを採用することにしました。でき上がったのが以下です。

https://github.com/myokoym/grnlip

メイン処理部分:
https://github.com/myokoym/grnlip/blob/master/exe/grnlip

RubyGems.orgに公開してあるので、以下のコマンドでインストールできます。

gem install grnlip

以下のコマンドで、UTF-8なDBに対してShift_JISで全文検索できる対話型インターフェイスが
起動します。引数には、groonga.exeのパスとデータベースのパス、そして文字コードを指定します。

> grnlip \path\to\groonga.exe \path\to\db utf-8

複数行の入力に対応していなかったりしますが、(*1) そのかわりコマンドごとにpretty-printできる機能を
おまけで付けてあります。コマンドの先頭にppを付けると、そのコマンドだけ整形されて表示されます。

(*1) バージョン0.1.1で対応しました。

以下はLinuxで実行した例です。

% grnlip groonga ~/.feedcellar/db/feedcellar.db
groonga(feedcellar.db)> status
[[0,1449073618.25274,0.00140500068664551],{"alloc_count":200,"starttime":1449073618,"start_time":1449073618,"uptime":0,"version":"5.1.0","n_queries":0,"cache_hit_rate":0.0,"command_version":1,"default_command_version":1,"max_command_version":2}]
groonga(feedcellar.db)> pp status
[
  [
    0,
    1449073621.71188,
    9.48905944824219e-05
  ],
  {
    "alloc_count": 200,
    "starttime": 1449073621,
    "start_time": 1449073621,
    "uptime": 0,
    "version": "5.1.0",
    "n_queries": 0,
    "cache_hit_rate": 0.0,
    "command_version": 1,
    "default_command_version": 1,
    "max_command_version": 2
  }
]

Groonga 5.1.0以降ではgroongaコマンドにpretty print機能が追加されたので、そちらを使うこともできます。

7.3.3. プリティープリント — Groonga v5.1.0ドキュメント
http://groonga.org/ja/docs/reference/command/pretty_print.html

おわりに

UTF-8なデータベースに対して、コマンドプロンプト上で日本語を使う方法を2つ紹介しました。
参考になれば幸いです。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away