mroongaで作ったテーブルをgroongaから検索するには


> もっとgroongaを知ってもらおう!ということで週刊groongaをはじめました。毎週木曜にgroongaやmroongaのトピックを投稿予定です。

groongaやmroongaを実際に使っていて、記事を書いてもいいよ、という人を募集しています。
すでに数名の方からご応募いただいていますが、まだまだ募集中です。
詳細は[groonga普及のための協力のお願い](http://sourceforge.jp/projects/groonga/lists/archive/dev/2013-February/001186.html)を参照してください。

# はじめに

MySQLで高速に全文検索するためのオープンソースのストレージエンジンとして[mroonga](http://mroonga.github.com/ja/)を公開しています。最新のバージョンは2013年2月28日にリリースしたmroonga [3.01](http://mroonga.github.com/ja/blog/2013/02/28/release.html)です。

mroonga 3.01では、限定的ながらFOREIGN KEY制約のサポートを追加しました。

これは、mroongaとgroongaの相互運用性を高めるための改善です。
今回はそのあたりの背景を説明してみたいと思います。

# groongaとmroongaの相互運用性について

そもそもmroongaでFOREIGN KEY制約が使えるようになると、何が嬉しいのでしょうか。

これを知るには、mroongaの構成について把握する必要があります。

mroongaはMySQLのストレージエンジンです。
内部では全文検索エンジンとしてgroongaを使用しています。

groongaはカラムストア機能つき全文検索エンジンなので、mroongaとMySQLとではテーブル間の関係性の表現に違いがあります。

groongaはカラムの型として別のテーブルを指定する[参照型](http://groonga.org/ja/docs/tutorial/data.html#reference-types)という機能があり、テーブル間の関係というとこの参照型を使います。

一方、MySQLではテーブル間の関係をカラムの型で明示することができないので、FOREIGN KEY制約を指定することでテーブル間の関係を明示するのが通例です。

mroonga 3.01では、mroongaでFOREGIN KEY制約を使ってテーブルを構築すると、透過的にgroongaのスキーマへと参照型を使ってその情報を反映できるようになりました。

つまり、mroongaで作ったgroongaのデータベースを(mroongaではなく)groongaから検索するときに参照型をうまく利用して検索ができるようになります。

データの更新はmroongaから行い、検索はgroongaから行うというような構成で相互運用性をより高めることができるようになります。

FOREIGN KEY制約のサポートは今のところMySQL 5.6に限定されていることに注意が必要です。
また、まだ実験的な機能であることにも注意してください。

# mroongaでテーブルを作成する

後でgroongaからアクセスするためのサンプルテーブルのスキーマとデータは以下の通りです。

```sql
use test;
drop table if exists articles;
drop table if exists comments;

create table articles (
  article int unsigned,
  content text not null,
  primary key(article)
) engine=mroonga default charset utf8;

create table comments (
  article int unsigned,
  content text not null,
  FOREIGN KEY (article) REFERENCES articles (article)
) engine=mroonga default charset utf8;


insert into articles (article, content) values (1, 'article1'),(2, 'article2'),(3, 'article3');
insert into comments (article, content) values (1, 'comment1'),(1, 'comment2'),(2, 'comment3');
```

以下のコマンドを実行してサンプルテーブルを作成します。

```sh
mysql < foreign-key.sql
```



# groongaからmroongaで作ったテーブルにアクセスする

それでは、実際にgroongaからmroongaで作ったテーブルにアクセスしてみましょう。

groongaコマンドでmroongaのテーブルにアクセスして実際に検索を行います。

データベースファイルはMySQLの標準的なディレクトリである$MYSQL_DATA_DIR以下にあります。
一般的には$MYSQL_DATA_DIRは/var/lib/mysql以下です。

そのため、通常mroongaはデータベースファイルを以下の場所に作成します。

* $MYSQL_DATA_DIR/データベース名.mrn

mroongaは上記ディレクトリ以下に大量の.mrnファイルを作成するので、(ドキュメントはまだ追加されていませんが) [mroonga_database_path_prefix](http://sourceforge.jp/projects/groonga/lists/archive/dev/2012-June/000956.html)という変数を使って専用のディレクトリを用意することもできます。


参考までに、mroonga_database_path_prefix変数はmysqlプロンプトからだと以下のようにして設定します。

```
SET GLOBAL mroonga_database_path_prefix = "mroonga.data/";
```

すると$MYSQL_DATA_DIR/mroonga.data/データベース名.mrnなファイルが作成されるようになります。

では、mroongaのデータベースファイルをgroongaコマンドを利用して参照してみます。

```sh
sudo groonga /var/lib/mysql/test.mrn
```

groongaのテーブルは[table_list](http://groonga.org/ja/docs/reference/commands/table_list.html)コマンドを実行することで確認することができます。

```
> table_list
[[0,1362039799.07777,0.0167779922485352],[[["id","UInt32"],["name","ShortText"],["path","ShortText"],["flags","ShortText"],["domain","ShortText"],["range","ShortText"],["default_tokenizer","ShortText"],["normalizer","ShortText"]],[263,"articles","/var/lib/mysql/test.mrn.0000107","TABLE_PAT_KEY|PERSISTENT","UInt32",null,null,null],[265,"comments","/var/lib/mysql/test.mrn.0000109","TABLE_NO_KEY|PERSISTENT",null,null,null,null],[259,"comments-article","/var/lib/mysql/test.mrn.0000103","TABLE_PAT_KEY|PERSISTENT","UInt32",null,null,null]]]
```

articlesテーブルやcommentsテーブルが存在していることがわかります。

では、articlesテーブルのカラムの情報を見てみましょう。その場合には、[column_list](http://groonga.org/ja/docs/reference/commands/column_list.html)コマンドを実行することで確認できます。

```
> column_list articles
[[0,1362039913.41331,0.00010991096496582],[[["id","UInt32"],["name","ShortText"],["path","ShortText"],["type","ShortText"],["flags","ShortText"],["domain","ShortText"],["range","ShortText"],["source","ShortText"]],[263,"_key","","","COLUMN_SCALAR","articles","UInt32",[]],[258,"article","/var/lib/mysql/test.mrn.0000102","fix","COLUMN_SCALAR|PERSISTENT","articles","UInt32",[]],[264,"comments-article-------------------------------------------------","/var/lib/mysql/test.mrn.0000108","index","COLUMN_INDEX|PERSISTENT","articles","comments",["comments.article"]],[260,"content","/var/lib/mysql/test.mrn.0000104","var","COLUMN_SCALAR|PERSISTENT","articles","LongText",[]]]]
```

commentsテーブルのカラムについても同様にしてcolumn_listコマンドを実行することで確認することができます。

```
> column_list comments
[[0,1362039908.59731,9.70363616943359e-05],[[["id","UInt32"],["name","ShortText"],["path","ShortText"],["type","ShortText"],["flags","ShortText"],["domain","ShortText"],["range","ShortText"],["source","ShortText"]],[266,"article","/var/lib/mysql/test.mrn.000010A","fix","COLUMN_SCALAR|PERSISTENT","comments","articles",[]],[261,"content","/var/lib/mysql/test.mrn.0000105","var","COLUMN_SCALAR|PERSISTENT","comments","LongText",[]]]]
```

contentカラムがあることがわかったので、selectコマンドを実行してみます。

```
> select comments --query content:@comment1
[[0,1362043569.80628,0.000375032424926758],[[[1],[["_id","UInt32"],["article","articles"],["content","LongText"]],[1,1,"comment1"]]]]
```

特に支障なく検索クエリを実行することができました。

# まとめ

mroongaで 3.01で追加された、FOREIGN KEY制約のサポートの背景とgroongaからmroongaのテーブルを参照する方法について紹介しました。

mroongaに興味を持ったなら、まずは[インストール](http://mroonga.github.com/ja/docs/install.html)して試してみてください。

[ユーザーガイド](http://mroonga.github.com/ja/docs/userguide.html)も用意しています。