MROONGA(1)

NAME
mroonga - Mroonga Documentation

リリース情報はこちら: お知らせ <>

MROONGAの特徴

  Mroongaとは

Mroongaは全文検索エンジンであるGroongaをベースとしたMySQLのストレージエンジンです。

MySQLではver5.1からPluggable Storage Engineインタフェースが採用され、以前よりも柔軟に独自のストレージエンジンを利用できるようになりました。そこでGroongaにストレージエンジンインタフェースを実装し、MySQL経由でもGroongaを利用できるようにしました。

Mroongaを経由することでGroongaをSQLコマンドでも利用することができるようになります。

  Tritonnの後継

MySQLで日本語全文検索を実現するための方法として、MySQLにGroongaの前身である全文検索ライブラリSennaを組み込んだプロダクトをTritonnプロジェクトから開発・リリースされて来ました。Mroongaはその後継プロダクトとなります。

  MySQLのプラグインとして動作

TritonnではMySQLサーバのソースコードを直接修正していましたので、使用するためには利用者がソースから自分でビルドするか、あるいはTritonnプロジェクトが配布するバイナリを使う必要がありました（MySQL本家が配布する公式バイナリを利用できませんでした）。

一方、MroongaはPluggable Storage Engineインタフェースを利用した独立したプログラム(共有ライブラリ)であるため、MySQLの公式バイナリに手を加えずにプラグインとして動的にロードして利用することが可能となっています。これによりTritonnよりもさらに手軽に利用できるようになりました。

  更新性能の向上

Sennaと比較するとGroongaではインデックス追加/更新時のスループットが大幅に改善されています。

Mroongaでもこの更新性能の向上の恩恵を受けています。

  検索性能の向上

TritonnではMyISAMストレージエンジンを利用していたため、データ更新(インデックス更新)が発生するとテーブル全体に排他ロックがかかり、検索処理が阻害される問題がありました。

Mroongaではこの問題がなくなり(参照ロックフリー)、特にデータ更新が多いケースでの検索性能が向上しています。

  位置情報検索のサポート

Groongaには全文検索機能だけではなく、インデックスを利用した高速な位置情報検索機能があります。また、MySQLにも位置情報検索のための記法があります。Mroongaでは、Groongaの位置情報検索機能を使ってMySQLの位置情報の記法で書かれたSQLを実行するため、高速に位置情報検索を行うことができます。

  Groongaストレージファイル経由でのシステム連携

MroongaではGroongaのDB APIを使用してデータの格納を行っています。この時作成されるストレージファイルはGroonga単体でデータ管理を行う場合と同じフォーマットとなります。つまり以下のような使い方も可能となります。

•   Mroonga(MySQL)経由で格納したデータをGroongaサーバ(単体)の高度な検索機能を利用して検索

•   Groongaサーバ(単体)経由で格納したデータをMroonga(MySQL)経由で参照

    またGroongaのストレージファイルは複数プロセスや複数スレッドで共有することができますので、同じストレージファイルに対して複数パタンでの同時アクセスも可能です。

  他のストレージエンジンとの連携

Mroongaには2つの動作モードがあります。

1つが「ストレージモード」で、データストアも検索機能もすべてGroongaを使うモードです。これがデフォルトのモードです。上述の参照ロックフリーなGroongaの性能特性をフルに活かした高速なデータ更新・全文検索・位置情報検索が特長です。一方、トランザクションなどの機能は提供されません。

もう1つが「ラッパーモード」で、MyISAMやInnoDBといった他のストレージエンジンに 全文検索機能だけ を追加するモードです。このモードではトランザクションなど他のストレージエンジンがサポートしている機能に加えてGroongaの高速な全文検索機能を利用することができます。一方、Groongaの参照ロックフリーな特性は活かすことができません。また、更新処理は他のストレージエンジンがボトルネックになることが多いでしょう。

  サポートしているプラットフォーム

Mroongaは主要なプラットフォームの多くをサポートしています。

サポートしているプラットフォームは インストール <> を参照してください。

インストール

このセクションではMroongaのインストール方法を環境毎に説明します。主要なプラットフォームにはパッケージがあります。自分でMroongaをビルドするよりもパッケージを使うことを推奨します。しかし、心配しないでください。ソースからMroongaをビルドするためのドキュメントもあります。

32-bit用と64-bit用のパッケージを配布していますが、サーバ用途には64-bitパッケージを利用することをオススメします。32-bit用パッケージはテスト用か開発用にだけ使って下さい。32-bit用パッケージを使った場合は、中程度のサイズのデータでもメモリ不足エラーになることがあります。

  Windows

このセクションではWindows上でMroongaをインストールする方法を説明します。Mroongaをインストールするにはzipパッケージを展開します。

MroongaのWindowsバイナリはMariaDBのバイナリと一緒に提供しています。これは、MroongaのWindows版をビルドするのに MariaDB本体にいくつかの変更 <https://github.com/mroonga/mroonga/tree/main/packages/source/patches> が必要だからです。

  インストール

  zipファイルをダウンロードして展開する

zipファイルをダウンロードして展開してください。環境に合わせてzipファイルを選ぶ必要があります

•   MariaDB with Mroonga-16.01 <https://github.com/mroonga/mroonga/releases/tag/v16.01>

  mariadb-install-db.exe を実行する

bin\mariadb-install-db.exe を実行してデータベースを初期化してください。mariadb-install-db.exe コマンドはzipファイルに含まれています。

    > bin\mariadb-install-db.exe --datadir=C:\EXAMPLE\data --service=MariaDB --password=PASSWORD

•   --datadir=C:\EXAMPLE\data

•   データベースのフォルダ名を指定します

•   --service=MariaDB

•   Windowsのサービス名を指定します

•   MariaDBをWindowsサービスとして登録する場合は指定してください

•   --password=PASSWORD

•   rootユーザのパスワードを指定します

  MariaDBサーバーを起動する

次のように単にMariaDBサーバーを起動します。

    > bin\mariadbd.exe --defaults-file=.\MY-PREFERRED-INI.ini --console

MariaDBをWindowsサービスに登録した場合は、WindowsサービスがMariaDBサーバーを起動していることを確認します。

  MariaDBにMroongaをインストール

MariaDBに次のコマンドで接続します。

    > bin\mariadb.exe
    MariaDB [(none)]>

接続できたら share\mroonga\install.sql を実行してMroongaをインストールします。そのファイルはzipファイルに含まれているので、ファイルを配置したパスを指定してください。

    MariaDB [(none)]> SOURCE C:PATHTO\share\mroonga\install.sql;
    Query OK, 0 rows affected (0.064 sec)
    Query OK, 0 rows affected, 1 warning (0.000 sec)
    Query OK, 0 rows affected (0.002 sec)
    Query OK, 0 rows affected, 1 warning (0.000 sec)
    Query OK, 0 rows affected (0.001 sec)
    Query OK, 0 rows affected, 1 warning (0.000 sec)
    Query OK, 0 rows affected (0.001 sec)
    Query OK, 0 rows affected, 1 warning (0.000 sec)
    Query OK, 0 rows affected (0.000 sec)
    Query OK, 0 rows affected, 1 warning (0.000 sec)
    Query OK, 0 rows affected (0.001 sec)
    Query OK, 0 rows affected, 1 warning (0.000 sec)
    Query OK, 0 rows affected (0.000 sec)
    Query OK, 0 rows affected, 1 warning (0.000 sec)
    Query OK, 0 rows affected (0.000 sec)
    Query OK, 0 rows affected, 1 warning (0.000 sec)
    Query OK, 0 rows affected (0.001 sec)
    Query OK, 0 rows affected, 1 warning (0.000 sec)
    Query OK, 0 rows affected (0.000 sec)
    MariaDB [(none)]> SHOW ENGINES;
    +--------------------+---------+------------------------------------------------------------+--------------+------+------------+
    | Engine             | Support | Comment                                                    | Transactions | XA   | Savepoints |
    +--------------------+---------+------------------------------------------------------------+--------------+------+------------+
    | CSV                | YES     | CSV storage engine                                         | NO           | NO   | NO         |
    | PERFORMANCE_SCHEMA | YES     | Performance Schema                                         | NO           | NO   | NO         |
    | MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables  | NO           | NO   | NO         |
    | MyISAM             | YES     | MyISAM storage engine                                      | NO           | NO   | NO         |
    | MRG_MyISAM         | YES     | Collection of identical MyISAM tables                      | NO           | NO   | NO         |
    | InnoDB             | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES          | YES  | YES        |
    | Mroonga            | YES     | CJK-ready fulltext search, column store                    | NO           | NO   | NO         |
    | Aria               | YES     | Crash-safe tables with MyISAM heritage                     | NO           | NO   | NO         |
    +--------------------+---------+------------------------------------------------------------+--------------+------+------------+
    8 rows in set (0.00 sec)

  MariaDBと一緒にソースからビルド

Mroongaプロジェクトが提供しているMroongaを含んだMariaDBのソースを使う必要があります。

このソースは <https://packages.groonga.org/source/mroonga/> にあります。Mroongaを含んだMariaDBのソースは mariadb-${MARIADB_VERSION}-with-mroonga-${MROONGA_VERSION}.zip というファイル名になっています。

このソースは MariaDBの標準的なビルド方法 <https://mariadb.com/kb/en/mariadb/documentation/getting-started/compiling-mariadb-from-source/Building_MariaDB_on_Windows/> でビルドできます。

MariaDBをビルドしたらMroongaを登録する必要があります。 ${MARIADB_BUILD_DIR}\storage\mroonga\data\install.sql にあるSQLを使ってMroongaを登録してください。

  macOS

このセクションではmacOS上でMroongaをインストールする方法を説明します。 Homebrew <https://brew.sh/> を使ってインストールできます。

  Homebrew

詳細は mroonga/homebrew-mroonga on GitHub <https://github.com/mroonga/homebrew-mroonga> を見てください。

  Debian GNU/Linux

このセクションではDebian GNU/Linux上でMroonga関連のdebパッケージをインストールする方法を説明します。これらのパッケージは apt でインストールできます。

  bookworm (MariaDB)

インストール:

    $ sudo apt update
    $ sudo apt install -y -V wget
    $ wget https://packages.apache.org/artifactory/arrow/debian/apache-arrow-apt-source-latest-bookworm.deb
    $ sudo apt install -y -V ./apache-arrow-apt-source-latest-bookworm.deb
    $ rm -rf apache-arrow-apt-source-latest-bookworm.deb
    $ wget https://packages.groonga.org/debian/groonga-apt-source-latest-bookworm.deb
    $ sudo apt install -y -V ./groonga-apt-source-latest-bookworm.deb
    $ rm -rf groonga-apt-source-latest-bookworm.deb
    $ sudo apt update
    $ sudo apt install -y -V mariadb-10.11-mroonga

トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

groonga-tokenizer-mecabをインストール:

    $ sudo apt install -y -V groonga-tokenizer-mecab

  bookworm（OracleのMySQL 8.0パッケージを利用）

インストール:

    $ sudo apt update
    $ sudo apt install -y -V wget
    $ wget https://packages.groonga.org/debian/groonga-apt-source-latest-bookworm.deb
    $ sudo apt install -y -V ./groonga-apt-source-latest-bookworm.deb
    $ rm -rf groonga-apt-source-latest-bookworm.deb
    $ wget https://repo.mysql.com/mysql-apt-config.deb
    $ sudo env DEBIAN_FRONTEND=noninteractive MYSQL_SERVER_VERSION=mysql-8.0 apt install -y ./mysql-apt-config.deb
    $ rm -rf mysql-apt-config.deb
    $ sudo apt update
    $ sudo apt install -y -V mysql-community-8.0-mroonga

トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

groonga-tokenizer-mecabをインストール:

    $ sudo apt install -y -V groonga-tokenizer-mecab

  trixie (MariaDB)

インストール:

    $ sudo apt update
    $ sudo apt install -y -V wget
    $ wget https://packages.apache.org/artifactory/arrow/debian/apache-arrow-apt-source-latest-trixie.deb
    $ sudo apt install -y -V ./apache-arrow-apt-source-latest-trixie.deb
    $ rm -rf apache-arrow-apt-source-latest-trixie.deb
    $ wget https://packages.groonga.org/debian/groonga-apt-source-latest-trixie.deb
    $ sudo apt install -y -V ./groonga-apt-source-latest-trixie.deb
    $ rm -rf groonga-apt-source-latest-trixie.deb
    $ sudo apt update
    $ sudo apt install -y -V mariadb-11.8-mroonga

トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

groonga-tokenizer-mecabをインストール:

    $ sudo apt install -y -V groonga-tokenizer-mecab

  trixie （OracleのMySQL 8.4パッケージを利用）

インストール:

    $ sudo apt update
    $ sudo apt install -y -V wget
    $ wget https://packages.groonga.org/debian/groonga-apt-source-latest-trixie.deb
    $ sudo apt install -y -V ./groonga-apt-source-latest-trixie.deb
    $ rm -rf groonga-apt-source-latest-trixie.deb
    $ wget https://repo.mysql.com/mysql-apt-config.deb
    $ sudo env DEBIAN_FRONTEND=noninteractive MYSQL_SERVER_VERSION=mysql-8.4-lts apt install -y ./mysql-apt-config.deb
    $ rm -rf mysql-apt-config.deb
    $ sudo apt update
    $ sudo apt install -y -V mysql-community-8.4-mroonga

トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

groonga-tokenizer-mecabをインストール:

    $ sudo apt install -y -V groonga-tokenizer-mecab

  Ubuntu

このセクションではUbuntu上でMroonga関連のdebパッケージをインストールする方法を説明します。これらのパッケージは apt でインストールできます。

  PPA (Personal Package Archive)

Ubuntu用のMroongaのAPTリポジトリーはLaunchpad上のPPA（Personal Package Archive）を使っています。このPPAからAPTでMroongaをインストールできます。

サポートしているUbuntuのバージョンは次の通りです。

•   22.04 Jammy Jellyfish

•   24.04 Noble Numbat

    MySQLをサポートしているUbuntuのバージョンは次の通りです。

•   22.04 Jammy Jellyfish

•   24.04 Noble Numbat

    MariaDBをサポートしているUbuntuのバージョンは次の通りです。

•   22.04 Jammy Jellyfish

•   24.04 Noble Numbat

    Mroongaをインストールするときは、universeリポジトリーとセキュリティアップデートリポジトリを有効にしてください。:

        % sudo apt-get install -y -V software-properties-common lsb-release
        % sudo add-apt-repository -y universe
        % sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu $(lsb_release --short --codename)-security main restricted"

    ppa:groonga/ppa PPAをシステムに追加します:

        % sudo add-apt-repository -y ppa:groonga/ppa
        % sudo apt-get update

    MySQL用のMroongaをインストール:

        % sudo apt-get install -y -V mysql-server-mroonga

    MariaDB用のMroongaをインストール:

        % sudo apt-get install -y -V mariadb-server-mroonga

    トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

    groonga-tokenizer-mecabをインストール:

        % sudo apt-get install -y -V groonga-tokenizer-mecab

  AlmaLinux

このセクションではAlmaLinux上でMroonga関連のRPMパッケージをインストールする方法を説明します。これらのパッケージは dnf でインストールできます。

  AlmaLinux 8（OracleのMySQL 8.0パッケージを利用）

AlmaLinux 8では、Mroonga 11.10からOracleのMySQL 8.0パッケージを利用できます。

注釈: MySQL 8.0に関しては以下の既知の問題があります。

•   ラッパーモード <> ラッパーモードは未対応です。

•   ストレージモード <> ストレージモードは以下の機能が未対応です。

•   最適化関連の機能

    インストール:

        $ sudo dnf -y module disable mysql
        $ sudo dnf install -y  https://packages.apache.org/artifactory/arrow/almalinux/8/apache-arrow-release-latest.rpm
        $ sudo dnf install -y https://packages.groonga.org/almalinux/8/groonga-release-latest.noarch.rpm
        $ sudo dnf install -y https://repo.mysql.com/mysql80-community-release-el8.rpm
        $ sudo dnf install --disablerepo=AppStream -y --enablerepo=epel,powertools mysql-community-8.0-mroonga
        ($ sudo systemctl start mysqld)
        ($ tmp_password=$(sudo grep 'A temporary password' /var/log/mysqld.log | sed -e 's/^.*: //'))
        ($ sudo mysqladmin -u root --password="${tmp_password}" password)

    トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

    groonga-tokenizer-mecabをインストール:

        $ sudo dnf -y module enable mysql
        $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab
        $ sudo dnf -y module disable mysql

  AlmaLinux 8（OracleのMySQL 8.4パッケージを利用）

AlmaLinux 8では、Mroonga 14.04からOracleのMySQL 8.4パッケージを利用できます。

注釈: MySQL 8.4に関しては以下の既知の問題があります。

•   ラッパーモード <> ラッパーモードは未対応です。

•   ストレージモード <> ストレージモードは最適化関連の機能が未対応です。

    インストール:

        $ sudo dnf -y module disable mysql
        $ sudo dnf install -y  https://packages.apache.org/artifactory/arrow/almalinux/8/apache-arrow-release-latest.rpm
        $ sudo dnf install -y https://packages.groonga.org/almalinux/8/groonga-release-latest.noarch.rpm
        $ sudo dnf install -y https://repo.mysql.com/mysql84-community-release-el8.rpm
        $ sudo dnf install -y --enablerepo=epel,powertools mysql-community-8.4-mroonga
        ($ sudo systemctl start mysqld)
        ($ tmp_password=$(sudo grep 'A temporary password' /var/log/mysqld.log | sed -e 's/^.*: //'))
        ($ sudo mysqladmin -u root --password="${tmp_password}" password)

    トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

    groonga-tokenizer-mecabをインストール:

        $ sudo dnf -y module enable mysql
        $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab
        $ sudo dnf -y module disable mysql

  AlmaLinux 8（Percona Server 8.0パッケージを利用）

AlmaLinux 8では、Mroonga 11.10からPercona Server 8.0パッケージを利用できます。

インストール:

    $ sudo dnf install -y https://packages.apache.org/artifactory/arrow/almalinux/8/apache-arrow-release-latest.rpm
    $ sudo dnf install -y https://packages.groonga.org/almalinux/8/groonga-release-latest.noarch.rpm
    $ sudo dnf install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm
    $ sudo percona-release setup ps80
    $ sudo dnf install -y --enablerepo=epel,powertools percona-server-8.0-mroonga
    ($ sudo systemctl start mysqld)
    ($ tmp_password=$(sudo grep 'A temporary password' /var/log/mysqld.log | sed -e 's/^.*: //'))
    ($ sudo mysqladmin -u root --password="${tmp_password}" password)

トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

groonga-tokenizer-mecabをインストール:

    $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab

  AlmaLinux 8（MariaDB 10.6のパッケージを利用）

AlmaLinux 8では、Mroonga 11.10からMariaDB提供のMariaDB 10.6パッケージを利用できます。

以下の内容で /etc/yum.repos.d/MariaDB.repo を作成してください:

    [mariadb]
    name = MariaDB
    baseurl = https://rpm.mariadb.org/10.6/rhel/$releasever/$basearch
    gpgkey = https://rpm.mariadb.org/RPM-GPG-KEY-MariaDB
    gpgcheck = 1

インストール:

    $ sudo dnf install -y https://packages.apache.org/artifactory/arrow/almalinux/8/apache-arrow-release-latest.rpm
    $ sudo dnf install -y https://packages.groonga.org/almalinux/8/groonga-release-latest.noarch.rpm
    $ sudo dnf module -y disable mariadb
    $ sudo dnf module -y disable mysql
    $ sudo dnf install -y --enablerepo=powertools mariadb-server
    $ sudo systemctl start mariadb
    $ sudo dnf install -y --enablerepo=powertools mariadb-10.6-mroonga
    ($ sudo mysqladmin -u root password 'new-password')

トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

groonga-tokenizer-mecabをインストール:

    $ sudo dnf module -y enable mysql
    $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab
    $ sudo dnf module -y disable mysql

  AlmaLinux 8（MariaDB 10.11のパッケージを利用）

AlmaLinux 8では、Mroonga 13.01からMariaDB提供のMariaDB 10.11パッケージを利用できます。

以下の内容で /etc/yum.repos.d/MariaDB.repo を作成してください:

    [mariadb]
    name = MariaDB
    baseurl = https://rpm.mariadb.org/10.11/rhel/$releasever/$basearch
    gpgkey = https://rpm.mariadb.org/RPM-GPG-KEY-MariaDB
    gpgcheck = 1

インストール:

    $ sudo dnf install -y https://packages.apache.org/artifactory/arrow/almalinux/8/apache-arrow-release-latest.rpm
    $ sudo dnf install -y https://packages.groonga.org/almalinux/8/groonga-release-latest.noarch.rpm
    $ sudo dnf module -y disable mariadb
    $ sudo dnf module -y disable mysql
    $ sudo dnf install -y --enablerepo=powertools mariadb-server
    $ sudo systemctl start mariadb
    $ sudo dnf install -y --enablerepo=powertools mariadb-10.11-mroonga
    ($ sudo mysqladmin -u root password 'new-password')

トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

groonga-tokenizer-mecabをインストール:

    $ sudo dnf module -y enable mysql
    $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab
    $ sudo dnf module -y disable mysql

  AlmaLinux 8（MariaDB 11.4のパッケージを利用）

AlmaLinux 8では、Mroonga 14.07からMariaDB提供のMariaDB 11.4パッケージを利用できます。

以下の内容で /etc/yum.repos.d/MariaDB.repo を作成してください:

    [mariadb]
    name = MariaDB
    baseurl = https://rpm.mariadb.org/11.4/rhel/$releasever/$basearch
    gpgkey = https://rpm.mariadb.org/RPM-GPG-KEY-MariaDB
    gpgcheck = 1

インストール:

    $ sudo dnf install -y https://packages.apache.org/artifactory/arrow/almalinux/8/apache-arrow-release-latest.rpm
    $ sudo dnf install -y https://packages.groonga.org/almalinux/8/groonga-release-latest.noarch.rpm
    $ sudo dnf module -y disable mariadb
    $ sudo dnf module -y disable mysql
    $ sudo dnf install -y --enablerepo=powertools mariadb-server
    $ sudo systemctl start mariadb
    $ sudo dnf install -y --enablerepo=powertools mariadb-11.4-mroonga
    ($ sudo mariadb-admin -u root password 'new-password')

トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

groonga-tokenizer-mecabをインストール:

    $ sudo dnf module -y enable mysql
    $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab
    $ sudo dnf module -y disable mysql

  AlmaLinux 8（MariaDB 11.8のパッケージを利用）

AlmaLinux 8では、Mroonga 15.21からMariaDB提供のMariaDB 11.8パッケージを利用できます。

以下の内容で /etc/yum.repos.d/MariaDB.repo を作成してください:

    [mariadb]
    name = MariaDB
    baseurl = https://rpm.mariadb.org/11.8/rhel/$releasever/$basearch
    gpgkey = https://rpm.mariadb.org/RPM-GPG-KEY-MariaDB
    gpgcheck = 1

インストール:

    $ sudo dnf install -y https://packages.apache.org/artifactory/arrow/almalinux/8/apache-arrow-release-latest.rpm
    $ sudo dnf install -y https://packages.groonga.org/almalinux/8/groonga-release-latest.noarch.rpm
    $ sudo dnf module -y disable mariadb
    $ sudo dnf module -y disable mysql
    $ sudo dnf install -y --enablerepo=powertools mariadb-server
    $ sudo systemctl start mariadb
    $ sudo dnf install -y --enablerepo=powertools mariadb-11.8-mroonga
    ($ sudo mariadb-admin -u root password 'new-password')

トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

groonga-tokenizer-mecabをインストール:

    $ sudo dnf module -y enable mysql
    $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab
    $ sudo dnf module -y disable mysql

  AlmaLinux 9（OracleのMySQL 8.0パッケージを利用）

AlmaLinux 9では、Mroonga 12.12からOracleのMySQL 8.0パッケージを利用できます。

注釈: MySQL 8.0に関しては以下の既知の問題があります。

•   ラッパーモード <> ラッパーモードは未対応です。

•   ストレージモード <> ストレージモードは以下の機能が未対応です。

•   最適化関連の機能

    インストール:

        $ sudo dnf install -y https://packages.apache.org/artifactory/arrow/almalinux/9/apache-arrow-release-latest.rpm
        $ sudo dnf install -y https://packages.groonga.org/almalinux/9/groonga-release-latest.noarch.rpm
        $ sudo dnf install -y https://repo.mysql.com/mysql80-community-release-el9.rpm
        $ sudo dnf install --disablerepo=AppStream -y --enablerepo=epel,crb mysql-community-8.0-mroonga
        ($ sudo systemctl start mysqld)
        ($ tmp_password=$(sudo grep 'A temporary password' /var/log/mysqld.log | sed -e 's/^.*: //'))
        ($ sudo mysqladmin -u root --password="${tmp_password}" password)

    トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

    groonga-tokenizer-mecabをインストール:

        $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab

  AlmaLinux 9（OracleのMySQL 8.4パッケージを利用）

AlmaLinux 9では、Mroonga 14.04からOracleのMySQL 8.4パッケージを利用できます。

注釈: MySQL 8.4に関しては以下の既知の問題があります。

•   ラッパーモード <> ラッパーモードは未対応です。

•   ストレージモード <> ストレージモードは最適化関連の機能が未対応です。

    インストール:

        $ sudo dnf install -y https://packages.apache.org/artifactory/arrow/almalinux/9/apache-arrow-release-latest.rpm
        $ sudo dnf install -y https://packages.groonga.org/almalinux/9/groonga-release-latest.noarch.rpm
        $ sudo dnf install -y https://repo.mysql.com/mysql84-community-release-el9.rpm
        $ sudo dnf install -y --enablerepo=epel,crb mysql-community-8.4-mroonga
        ($ sudo systemctl start mysqld)
        ($ tmp_password=$(sudo grep 'A temporary password' /var/log/mysqld.log | sed -e 's/^.*: //'))
        ($ sudo mysqladmin -u root --password="${tmp_password}" password)

    トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

    groonga-tokenizer-mecabをインストール:

        $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab

  AlmaLinux 9（Percona Server 8.0パッケージを利用）

AlmaLinux 9では、Mroonga 12.12からPercona Server 8.0パッケージを利用できます。

インストール:

    $ sudo dnf install -y https://packages.apache.org/artifactory/arrow/almalinux/9/apache-arrow-release-latest.rpm
    $ sudo dnf install -y https://packages.groonga.org/almalinux/9/groonga-release-latest.noarch.rpm
    $ sudo dnf install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm
    $ sudo percona-release setup ps80
    $ sudo dnf install -y --enablerepo=epel percona-server-8.0-mroonga
    ($ sudo systemctl start mysqld)
    ($ tmp_password=$(sudo grep 'A temporary password' /var/log/mysqld.log | sed -e 's/^.*: //'))
    ($ sudo mysqladmin -u root --password="${tmp_password}" password)

トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

groonga-tokenizer-mecabをインストール:

    $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab

  AlmaLinux 9（Percona Server 8.4パッケージを利用）

AlmaLinux 9では、Mroonga 15.04からPercona Server 8.4パッケージを利用できます。

インストール:

    $ sudo dnf install -y https://packages.apache.org/artifactory/arrow/almalinux/9/apache-arrow-release-latest.rpm
    $ sudo dnf install -y https://packages.groonga.org/almalinux/9/groonga-release-latest.noarch.rpm
    $ sudo dnf install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm
    $ sudo percona-release enable-only ps-84-lts release
    $ sudo dnf install -y --enablerepo=epel percona-server-8.4-mroonga
    ($ sudo systemctl start mysqld)
    ($ tmp_password=$(sudo grep 'A temporary password' /var/log/mysqld.log | sed -e 's/^.*: //'))
    ($ sudo mysqladmin -u root --password="${tmp_password}" password)

トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

groonga-tokenizer-mecabをインストール:

    $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab

  AlmaLinux 9（MariaDB 10.6のパッケージを利用）

AlmaLinux 9では、Mroonga 12.12からMariaDB提供のMariaDB 10.6パッケージを利用できます。

以下の内容で /etc/yum.repos.d/MariaDB.repo を作成してください:

    [mariadb]
    name = MariaDB
    baseurl = https://rpm.mariadb.org/10.6/rhel/$releasever/$basearch
    gpgkey = https://rpm.mariadb.org/RPM-GPG-KEY-MariaDB
    gpgcheck = 1

インストール:

    $ sudo dnf install -y https://packages.apache.org/artifactory/arrow/almalinux/9/apache-arrow-release-latest.rpm
    $ sudo dnf install -y https://packages.groonga.org/almalinux/9/groonga-release-latest.noarch.rpm
    $ sudo dnf install -y mariadb-server
    $ sudo systemctl start mariadb
    $ sudo dnf install -y mariadb-10.6-mroonga
    ($ sudo mysqladmin -u root password 'new-password')

トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

groonga-tokenizer-mecabをインストール:

    $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab

  AlmaLinux 9（MariaDB 10.11のパッケージを利用）

AlmaLinux 9では、Mroonga 13.01からMariaDB提供のMariaDB 10.11パッケージを利用できます。

以下の内容で /etc/yum.repos.d/MariaDB.repo を作成してください:

    [mariadb]
    name = MariaDB
    baseurl = https://rpm.mariadb.org/10.11/rhel/$releasever/$basearch
    gpgkey = https://rpm.mariadb.org/RPM-GPG-KEY-MariaDB
    gpgcheck = 1

インストール:

    $ sudo dnf install -y https://packages.apache.org/artifactory/arrow/almalinux/9/apache-arrow-release-latest.rpm
    $ sudo dnf install -y https://packages.groonga.org/almalinux/9/groonga-release-latest.noarch.rpm
    $ sudo dnf install -y mariadb-server
    $ sudo systemctl start mariadb
    $ sudo dnf install -y mariadb-10.11-mroonga
    ($ sudo mysqladmin -u root password 'new-password')

トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

groonga-tokenizer-mecabをインストール:

    $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab

  AlmaLinux 9（MariaDB 11.4のパッケージを利用）

AlmaLinux 9では、Mroonga 14.07からMariaDB提供のMariaDB 11.4パッケージを利用できます。

以下の内容で /etc/yum.repos.d/MariaDB.repo を作成してください:

    [mariadb]
    name = MariaDB
    baseurl = https://rpm.mariadb.org/11.4/rhel/$releasever/$basearch
    gpgkey = https://rpm.mariadb.org/RPM-GPG-KEY-MariaDB
    gpgcheck = 1

インストール:

    $ sudo dnf install -y https://packages.apache.org/artifactory/arrow/almalinux/9/apache-arrow-release-latest.rpm
    $ sudo dnf install -y https://packages.groonga.org/almalinux/9/groonga-release-latest.noarch.rpm
    $ sudo dnf install -y mariadb-server
    $ sudo systemctl start mariadb
    $ sudo dnf install -y mariadb-11.4-mroonga
    ($ sudo mariadb-admin -u root password 'new-password')

トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

groonga-tokenizer-mecabをインストール:

    $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab

  AlmaLinux 10（OracleのMySQL 8.4パッケージを利用）

AlmaLinux 10では、Mroonga 15.18からOracleのMySQL 8.4パッケージを利用できます。

注釈:

•   ラッパーモード <> ラッパーモードは未対応です。

•   ストレージモード <> ストレージモードは最適化関連の機能が未対応です。

    インストール:

        $ sudo dnf install -y  https://packages.apache.org/artifactory/arrow/almalinux/10/apache-arrow-release-latest.rpm
        $ sudo dnf install -y https://packages.groonga.org/almalinux/10/groonga-release-latest.noarch.rpm
        $ sudo dnf install -y https://repo.mysql.com/mysql84-community-release-el10.rpm
        $ sudo dnf install --disablerepo=AppStream -y --enablerepo=epel mysql-community-8.4-mroonga
        ($ sudo systemctl start mysqld)
        ($ tmp_password=$(sudo grep 'A temporary password' /var/log/mysqld.log | sed -e 's/^.*: //'))
        ($ sudo mysqladmin -u root --password="${tmp_password}" password)

    トークナイザーとして MeCab <https://taku910.github.io/mecab/> を利用したい場合はgroonga-tokenizer-mecabをインストールしてください。

    groonga-tokenizer-mecabをインストール:

        $ sudo dnf install -y --enablerepo=epel groonga-tokenizer-mecab

  Oracle Linux

This section describes how to install Mroonga related RPM packages on AlmaLinux. You can install them by dnf.

  Oracle Linux 8 (with the Oracle MySQL 8.0 package)

You can use Oracle's MySQL packages version 8.0 on Oracle Linux 8 since Mroonga 12.08 release.

注釈: There are already known issues about MySQL 8.0.

•   ラッパーモード <> Wrapper mode is not supported yet

•   ストレージモード <> Storage mode does not support the following feature.

•   The feature of relevant to the optimization.

    Install:

        % sudo dnf -y module disable mysql
        % sudo dnf install -y https://packages.groonga.org/almalinux/8/groonga-release-latest.noarch.rpm
        % sudo dnf install -y https://repo.mysql.com/mysql80-community-release-el8.rpm
        % sudo dnf install --disablerepo=AppStream -y --enablerepo=ol8_codeready_builder mysql-community-8.0-mroonga
        (% sudo systemctl start mysqld)
        (% tmp_password=$(sudo grep 'A temporary password' /var/log/mysqld.log | sed -e 's/^.*: //'))
        (% sudo mysqladmin -u root --password="${tmp_password}" password)

    If you want to use MeCab <https://taku910.github.io/mecab/> as a tokenizer, install groonga-tokenizer-mecab package.

    Install groonga-tokenizer-mecab package:

        % sudo dnf install -y --enablerepo=ol8_codeready_builder groonga-tokenizer-mecab

  Fedora

  Fedora 21

Fedora 21ではMariaDB 10.0.xが採用されました。MroongaはMariaDB 10.0.15以降バンドルされるようになったので、MariaDBをインストールすることで使えます。

バンドルされているMroongaのバージョンはやや古いです。

  Docker

MroongaはDocker Hub経由でも利用できます。

まずは クイックスタートガイド（英語） <https://hub.docker.com/r/groonga/mroonga/> をご覧ください。

  その他

このセクションではUNIX系の環境でMroongaをソースコードからインストールする方法を説明します。

  依存関係

MroongaをビルドするためにはいくつかのツールとライブラリーとMySQLが必要です。MySQLの代わりにMariaDBを使うこともできます。

  ツール

必須のツール

•   wget、curl または Web ブラウザ（ソースアーカイブをダウンロードするため）

•   tar と gzip（ソースアーカイブを展開するため）

•   シェル（ dash 、 bash 、 zsh など、どのようなシェルでもたぶん大丈夫）

•   CコンパイラーとC++コンパイラー （ gcc と g++ がサポート対象だが、他のコンパイラーでもたぶん大丈夫）

•   CMake <https://cmake.org/>（クロスプラットフォームのビルドシステムとして利用するため）

•   Ninja <https://ninja-build.org/>（高速にビルドするため）

•   pkg-config <http://www.freedesktop.org/wiki/Software/pkg-config>（ライブラリを検出するため）

    これらを用意してください。

    あるとよいツール

•   sudo（ビルドしたGroongaをインストールするため）

  ライブラリー

必須のライブラリー

•   Groonga <https://groonga.org/>

•   もしパッケージを使うなら、開発用パッケージをインストールしてください。debなら libgroonga-dev で、RPMなら groonga-devel です

•   groonga-normalizer-mysql <https://github.com/groonga/groonga-normalizer-mysql>

    あるとよいライブラリー

•   MeCab <https://taku910.github.io/mecab/>: 日本語形態素解析器

    注釈: 形態素単位でトークナイズした全文検索索引を使用したい場合は、Groongaのインストール前に MeCab <https://taku910.github.io/mecab/>をインストールしてください。

  MySQL

Mroongaはインストール済みのMySQLだけでなくMySQLのソースとビルドディレクトリーも必要です。そのため、MySQLのパッケージを使うことはできません。MySQLのパッケージはMySQLのソースとビルドディレクトリーを提供していないからです。MySQLのソースとビルドディレクトリーが必要です！

MySQLの代わりにMariaDBを使う場合でもMariaDBのソースが必要です。

MySQL 8.4最新版のソースコードをダウンロードし、ビルド＆インストールして下さい。

こちらのDownload MySQL Community Server <http://dev.mysql.com/downloads/mysql/> を参照して下さい。

mysql-8.4.1を使用し、以下にソースディレクトリが展開されているものと仮定します。

    ${HOME}/local/src/mysql-8.4.1

次のディレクトリーでビルドします。

    ${HOME}/local/build/mysql-8.4.1

次のコマンドラインはMySQLをビルド・インストールするコマンドラインです。

    $ cmake \
        -S ${HOME}/local/src/mysql-8.4.1 \
        -B ${HOME}/local/build/mysql-8.4.1 \
        -GNinja \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=${HOME}/local
    $ cmake --build ${HOME}/local/build/mysql-8.4.1
    $ cmake --install ${HOME}/local/build/mysql-8.4.1

Mroongaをインストールする前にMySQLを起動する必要があります。なぜならMroongaを登録するためにいくつかのSQL文を実行する必要があるからです。

  MariaDB

MySQLの代わりにMariaDBを使うことができます。

MariaDBをビルドする前にstorage/mroonga/（MariDBにバンドルされているMroonga）を削除しなければいけないことに注意してください。

    $ mkdir -p ${HOME}/local/src
    $ cd ${HOME}/local/src
    $ wget https://downloads.mariadb.org/rest-api/mariadb/11.4.3/mariadb-11.4.3.tar.gz
    $ tar xf mariadb-11.4.3.tar.gz
    $ rm -rf mariadb-11.4.3/storage/mroonga
    $ cd -
    $ cmake \
        -S ${HOME}/local/src/mariadb-11.4.3 \
        -B ${HOME}/local/build/mariadb-11.4.3 \
        -GNinja \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=${HOME}/local
    $ cmake --build ${HOME}/local/build/mariadb-11.4.3
    $ cmake --install ${HOME}/local/build/mariadb-11.4.3

  ソースからビルド

MroongaはCMakeを使っています。以下は一番簡単なビルド手順です。

    $ cd ${HOME}/local/src
    $ wget https://packages.groonga.org/source/mroonga/mroonga-latest.tar.gz
    $ tar xvf mroonga-latest.tar.gz
    $ mroonga_base_name=$(find mroonga-* -maxdepth 0 -type d)
    $ cmake \
        -S ${HOME}/local/src/${mroonga_base_name} \
        -B ${HOME}/local/build/${mroonga_base_name} \
        -GNinja \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=${HOME}/local \
        -DMYSQL_BUILD_DIR=${HOME}/local/build/mysql-8.4.1 \
        -DMYSQL_CONFIG=${HOME}/local/bin/mysql_config \
        -DMYSQL_SOURCE_DIR=${HOME}/local/src/mysql-8.4.1
    $ cmake --build ${HOME}/local/build/${mroonga_base_name}
    $ cmake --install ${HOME}/local/build/${mroonga_base_name}
    $ ${HOME}/local/bin/mysql -u root < ${HOME}/local/share/mroonga/install.sql

次のことを cmake で指定しなければいけません。

•   -DMYSQL_BUILD_DIR: MySQLのビルドディレクトリー

•   -DMYSQL_CONFIG: mysql_configコマンドのパス

•   -DMYSQL_SOURCE_DIR: MySQLのソースディレクトリー

    SHOW ENGINES SQLを実行することでMroongaが正常にインストールされているかを確認できます。 Mroonga という行があればMroongaは正常にインストールされています。

        mysql> SHOW ENGINES;
        +------------+---------+------------------------------------------------------------+--------------+------+------------+
        | Engine     | Support | Comment                                                    | Transactions | XA   | Savepoints |
        +------------+---------+------------------------------------------------------------+--------------+------+------------+
        | Mroonga    | YES     | Fulltext search, column base                               | NO           | NO   | NO         |
        | MRG_MYISAM | YES     | Collection of identical MyISAM tables                      | NO           | NO   | NO         |
        | CSV        | YES     | CSV storage engine                                         | NO           | NO   | NO         |
        | MyISAM     | DEFAULT | Default engine as of MySQL 3.23 with great performance     | NO           | NO   | NO         |
        | InnoDB     | YES     | Supports transactions, row-level locking, and foreign keys | YES          | YES  | YES        |
        | MEMORY     | YES     | Hash based, stored in memory, useful for temporary tables  | NO           | NO   | NO         |
        +------------+---------+------------------------------------------------------------+--------------+------+------------+
        6 rows in set (0.00 sec)

    以下、それぞれの手順の詳細を説明します。

  cmake

まず cmake を実行します。重要な cmake の引数は以下の通りです。

  -DMYSQL_SOURCE_DIR=PATH

MySQLのソースコードがあるディレクトリーを指定します。

これは必須の引数です。

  -DMYSQL_BUILD_DIR=PATH

MySQLのソースコードをビルドしたディレクトリーを指定します。

MySQLのソースコードがあるディレクトリーでビルドした場合はこの引数を指定する必要はありません。他のディレクトリーでビルドしたときはこの引数を指定する必要があります。

  -DMYSQL_CONFIG=PATH

mysql_config コマンドのパスを指定します。

mysql_config コマンドが PATH から探索可能であればこの引数を指定する必要はありません。例えば、 mysql_config が /usr/bin/mysql_config にある場合はこの引数を指定する必要はありません。

  -DMRN_DEFAULT_TOKENIZER=TOKENIZER

全文検索用のデフォルトのトークナイザーを指定します。この値はmy.cnfでもカスタマイズできます。

デフォルト値は TokenBigram です。

デフォルトのトークナイザーとして TokenMecab を使う例です。

    $ cmake ... -DMRN_DEFAULT_TOKENIZER=TokenMecab

  -DCMAKE_BUILD_TYPE={Release,Debug,RelWithDebInfo}

ビルドタイプを指定します。

本番環境でこのMroongaを使う場合は-DCAMKE_BUILD_TYPE=Releaseまたは-DCAMKE_BUILD_TYPE=RelWithDebInfoを指定するべきです。最適化が有効になります。

開発用にこのMroongaを使う場合は-DCAMKE_BUILD_TYPE=Debugを使うべきです。最適化が無効になり、デバッグシンボルが有効になります。これらは開発時に有用です。

  -DCMAKE_INSTALL_PREFIX=PREFIX

インストール先となるディレクトリを指定します。Mroonga関連のファイルは ha_mroonga.so を除いて ${PREFIX}/ ディレクトリ以下にインストールされます。 ha_mroonga.so はMySQLのプラグインファイルです。これはMySQLのプラグインディレクトリーにインストールされます。

デフォルトは /usr/local です。この場合、Mroongaをインストールするために使う install.sql は /usr/local/share/mroonga/install.sql にインストールされます。

  cmake --build

cmake が成功したら cmake --build でMroongaをビルドします。

cmake --build で何かエラーが発生した場合は、そのエラーをレポートしてください: 見つけたバグを報告するには <>

  cmake --install

これでビルドしたMroongaをインストールできます！

${PREFIX}とMySQLのプラグインディレクトリーへの書き込み権限がない場合は、sudoを使わないといけません。

    $ sudo cmake --install ${HOME}/local/build/${mroonga_base_name}

  mysql -u root < install.sql

MroongaをMySQLに登録するために INSTALL PLUGIN や CREATE FUNCTION といったSQL文を実行する必要があります。これらのSQLは ${PREFIX}/share/mroonga/install.sql に書かれています。

  Mroongaのアンインストール

Mroongaをアンインストールしたい場合は次のコマンドラインを使ってください。

    $ ${HOME}/local/bin/mysql -u root < ${PREFIX}/share/mroonga/uninstall.sql
    $ xargs rm < ${HOME}/local/build/mroonga/install_manifest.txt

アップグレード

非互換な変更が新しいリリースでもたらされることがあります。もし、そういった非互換がはいる場合にはリリースアナウンスでアナウンスします。

古いバージョンからMroongaをアップグレードする推奨方法のリストがこちらです。

以前のバージョンをお使いなら、アップグレード手順について次のURLを参照してください。

1.20以前からアップグレードするなら、 1.20リリース - 2012/01/29 <#release-1-20> を参照してください。

1.20からアップグレードするなら、 2.00 リリース <#release-2-00> を参照してください。

2.00もしくは2.01からアップグレードするなら、 2.02 リリース <#release-2-02> を参照してください。

もし2.00以降でマルチカラムインデックスをストレージモードで使用しているなら、 2.03 リリース <#release-2-03> を参照してください。

もし2.04以降でストレージモードでSETカラムまたは256未満の要素数のENUMを使っているなら 2.05リリース - 2012/07/29 <#release-2-05> を参照してください。

2.05以降でマルチカラムインデックスをVARCHARやCHAR型に対して使っている場合は、 2.08 リリース <#release-2-08> を参照してください。

2.08以降でTIMESTAMP型のカラムを使っているテーブルがあれば、データベースを再作成してください。CHAR(N)を主キーとしているテーブルがあれば、インデックスを再作成してください。 それぞれについては 2.09 リリース <#release-2-09> を参照してください。

5.03以前からのアップグレードで、次の条件に当てはまる場合には 5.04リリース - 2015/06/29 <#release-5-04> を参照してスキーマを更新してください。

•   インデックスコメントでトークナイザーを指定している

•   mroonga_default_parser <#server-variable-mroonga-default-parser> をサーバー変数に指定している

•   インデックスカラムに index_flags パラメータを指定している

•   ストレージモードでGroongaのカラム型の指定に type パラメータを指定している

チュートリアル

まだMroongaをインストールしていない場合は インストール <> を参照してください。そのドキュメントでMroongaのインストール方法を説明しています。

Mroongaをインストールしたら次のチュートリアルを試してください。Mroongaの使い方がわかります。

  インストールチェック

Mroongaを使う前にMroongaのインストールチェックをした方がよいです。もし、Mroongaのインストールに失敗していると、このチュートリアルででてくるSQLが失敗してしまいます。

MySQLサーバの起動停止方法は通常のMySQLと同じです。

MySQLサーバを起動した上でmysqlコマンドで接続します。パスワードを設定済みの場合は -p オプションでパスワードを指定して下さい。

    % mysql -uroot test

SHOW ENGINES コマンドでMroongaがインストールされているかどうかを確認します。

    SHOW ENGINES;
    -- +------------+---------+------------------------------------------------------------+--------------+------+------------+
    -- | Engine     | Support | Comment                                                    | Transactions | XA   | Savepoints |
    -- +------------+---------+------------------------------------------------------------+--------------+------+------------+
    -- | Mroonga    | YES     | Fulltext search, column base                               | NO           | NO   | NO         |
    -- | MRG_MYISAM | YES     | Collection of identical MyISAM tables                      | NO           | NO   | NO         |
    -- | CSV        | YES     | CSV storage engine                                         | NO           | NO   | NO         |
    -- | MyISAM     | DEFAULT | Default engine as of MySQL 3.23 with great performance     | NO           | NO   | NO         |
    -- | InnoDB     | YES     | Supports transactions, row-level locking, and foreign keys | YES          | YES  | YES        |
    -- | MEMORY     | YES     | Hash based, stored in memory, useful for temporary tables  | NO           | NO   | NO         |
    -- +------------+---------+------------------------------------------------------------+--------------+------+------------+
    -- 6 rows in set (0.00 sec)

上記のように Mroonga ストレージエンジンが見えていればインストールは無事完了しています。

もし Mroonga が表示されていない場合は以下のコマンドを実行してください。もし、Mroongaをパッケージでインストールしていない場合は install.sql のパスが違うかもしれません。:

    % mysql -uroot test < /usr/share/mroonga/install.sql

install.sql が見つからない場合は、以下のように手動で INSTALL PLUGIN コマンドを実行します。

    INSTALL PLUGIN Mroonga SONAME 'ha_mroonga.so';

Mroongaの正しいバージョンがインストールされているかどうかは、 SHOW VARIABLES コマンドを使ってサーバー変数を確認します。

    SHOW VARIABLES LIKE 'mroonga_version';

  モード

Mroongaには以下の2つのモードがあります。

•   ストレージモード

•   ラッパーモード

    ストレージモードでは、全文検索機能だけではなくデータストアも含めてGroongaの機能を利用します。ストレージエンジンのすべての機能をGroongaで実現するため、Groongaが得意としている集計操作が高速です。また、 groonga コマンドで直接データベースを操作できるという特長もあります。

    ストレージモードの構成を図で表すと以下のようになります。MyISAMやInnoDBなど既存のストレージエンジンの代わりに利用します。 [画像: ストレージモード] [画像]

    ラッパーモードでは全文検索機能のみGroongaの機能を利用し、データストアはInnoDBなど既存のストレージエンジンを利用します。ラッパーモードを利用することにより、ストレージエンジンとして多くの利用実績のあるInnoDBに全文検索エンジンとして実績のあるMroongaを組み合わせて、高速な全文検索機能付きの信頼性のあるデータベースとして利用できるという特長があります。

    ラッパーモードの構成を図で表すと以下のようになります。全文検索関連の処理はMroongaで処理し、それ以外の処理はMyISAMやInnoDBなど既存のストレージエンジンを利用します。SQLを処理するSQL Handlerと既存のストレージエンジンの間に位置するため、すべてのデータが一度Mroongaを通ることになります。これを利用して、全文検索用のインデックス作成などを透過的に行います。 [画像: ラッパーモード] [画像]

  ストレージモード

ここでは Mroonga におけるストレージモードの利用方法を説明します。

  全文検索の利用方法

インストールが確認できたら、テーブルを1つ作成してみましょう。 ENGINE = Mroonga とMroongaを指定するところがポイントです。

    CREATE TABLE diaries (
      id INT PRIMARY KEY AUTO_INCREMENT,
      content VARCHAR(255),
      FULLTEXT INDEX (content)
    ) ENGINE = Mroonga DEFAULT CHARSET utf8;
    -- Query OK, 0 rows affected (0.10 sec)

INSERT でデータを投入してみましょう。

    INSERT INTO diaries (content) VALUES ("It'll be fine tomorrow.");
    -- Query OK, 1 row affected (0.01 sec)
    INSERT INTO diaries (content) VALUES ("It'll rain tomorrow");
    -- Query OK, 1 row affected (0.00 sec)

全文検索を実行してみます。

    SELECT * FROM diaries WHERE MATCH(content) AGAINST("+fine" IN BOOLEAN MODE);
    -- +----+-----------------------------------------+
    -- | id | content                                 |
    -- +----+-----------------------------------------+
    -- |  1 | It'll be fine tomorrow. |
    -- +----+-----------------------------------------+
    -- 1 row in set (0.00 sec)

おぉぉー。検索できましたね。

  検索スコアの取得方法

注釈: 1.0.0以前のMroongaではMySQLの標準的な検索スコアの取得方法ではなく、 _score という専用のカラムを作成するという独自の方法でした。1.0.0からはMySQLの標準的な取得方法になっています。

全文検索を行う際、指定したキーワードにより内容が一致するレコードを上位に表示したいというような場合があります。そうしたケースでは検索スコアを利用します。

検索スコアはMySQLの標準的な方法 [1] で取得できます。つまり、SELECTの取得するカラム名を指定するところやORDER BYのところにMATCH...AGAINSTを指定します。

それでは実際にやってみましょう。

    INSERT INTO diaries (content) VALUES ("It's fine today. It'll be fine tomorrow as well.");
    -- Query OK, 1 row affected (0.00 sec)
    INSERT INTO diaries (content) VALUES ("It's fine today. But it'll rain tomorrow.");
    -- Query OK, 1 row affected (0.00 sec)
    SELECT *,
           MATCH (content) AGAINST ("+fine" IN BOOLEAN MODE)
      FROM diaries
     WHERE MATCH (content) AGAINST ("+fine" IN BOOLEAN MODE)
     ORDER BY
           MATCH (content) AGAINST ("+fine" IN BOOLEAN MODE) DESC;
    -- +----+--------------------------------------------------+---------------------------------------------------+
    -- | id | content                                          | MATCH (content) AGAINST ("+fine" IN BOOLEAN MODE) |
    -- +----+--------------------------------------------------+---------------------------------------------------+
    -- |  3 | It's fine today. It'll be fine tomorrow as well. |                                                 2 |
    -- |  1 | It'll be fine tomorrow.                          |                                                 1 |
    -- |  4 | It's fine today. But it'll rain tomorrow.        |                                                 1 |
    -- +----+--------------------------------------------------+---------------------------------------------------+
    -- 3 rows in set (0.00 sec)

検索対象の文字列 fine をより多く含む、すなわち検索スコアの高い id = 3 のメッセージが上に来ていることが確認できます。また、SELECT句にMATCH AGAINSTを記述しているため、検索スコアも取得できています。

属性名を変更したい場合は AS を使って下さい。

    SELECT *,
           MATCH (content) AGAINST ("+fine" IN BOOLEAN MODE) AS score
      FROM diaries
     WHERE MATCH (content) AGAINST ("+fine" IN BOOLEAN MODE)
     ORDER BY
           MATCH (content) AGAINST ("+fine" IN BOOLEAN MODE) DESC;
    -- +----+--------------------------------------------------+-------+
    -- | id | content                                          | score |
    -- +----+--------------------------------------------------+-------+
    -- |  3 | It's fine today. It'll be fine tomorrow as well. |     2 |
    -- |  1 | It'll be fine tomorrow.                          |     1 |
    -- |  4 | It's fine today. But it'll rain tomorrow.        |     1 |
    -- +----+--------------------------------------------------+-------+
    -- 3 rows in set (0.00 sec)

  全文検索用パーサの変更

MySQLは全文検索用のパーサ [2] を指定する以下のような構文を持っています。:

    FULLTEXT INDEX (content) WITH PARSER parser_name

しかし、この構文を利用する場合は、あらかじめすべてのパーサをMySQLに登録しておく必要があります。一方、Groongaはトークナイザー（MySQLでいうパーサ）を動的に追加することができます。そのため、Mroongaでもこの構文を採用するとGroonga側に動的に追加されたトークナイザーに対応できなくなります。Groongaに動的に追加されるトークナイザーにはMeCabを用いたトークナイザーもあり、この制限に縛られることは利便性を損なうと判断し、以下のようなコメントを用いた独自の構文を採用することにしました。:

    FULLTEXT INDEX (content) COMMENT 'tokenizer "TokenMecab"'

注釈: FULLTEXT INDEX に COMMENT を指定できるのはMySQL 5.5からになります。MySQL 5.1を利用している場合は後述の mroonga_default_tokenizer 変数を利用してください。

トークナイザーに指定できるのは以下の値です。Mroongaで言う「トークナイザー」とMySQLで言う「パーサー」は同じものです。

  利用可能なトークナイザー一覧
トークナイザー | 説明
off | (非推奨) トークナイズしません。 off は content をそのまま扱いたい場合に使います。例えば、この値は前方一致検索のために指定します。
none | Added in version 8.07: トークナイズしません。"off"は content をそのまま扱いたい場合に使います。例えば、この値は前方一致検索のために指定します。
TokenBigram | バイグラムでトークナイズする。ただし、連続したアルファベット・連続した数字・連続した記号はそれぞれ1つのトークンとして扱う。そのため、3文字以上のトークンも存在する。これはノイズを減らすためである。 デフォルト値。
TokenMecab | MeCabを用いてトークナイズする。groongaがMeCabサポート付きでビルドされている必要がある。
TokenBigramSplitSymbol | バイグラムでトークナイズする。 TokenBigram と異なり、記号が連続していても特別扱いして1つのトークンとして扱わず通常のバイグラムの処理を行う。 TokenBigramではなく TokenBigramSplitSymbol を利用すると「 Is it really!?!?!? 」の「 !?!?!? 」の部分に「 !? 」でマッチする。 TokenBigram の場合は「 !?!?!? 」でないとマッチしない。
TokenBigramSplitSymbolAlpha | バイグラムでトークナイズする。 TokenBigramSplitSymbol に加えて、連続したアルファベットも特別扱いせずに通常のバイグラムの処理を行う。 TokenBigram ではなく TokenBigramSplitSymbolAlpha を利用すると「 Is it really? 」に「 real 」でマッチする。 TokenBigram の場合は「 really 」でないとマッチしない。
TokenBigramSplitSymbolAlphaDigit | バイグラムでトークナイズする。 TokenBigramSplitSymbolAlpha に加えて、連続した数字も特別扱いせずに通常のバイグラムの処理を行う。つまり、すべての字種を特別扱いせずにバイグラムの処理を行う。 TokenBigram ではなく TokenBigramSplitSymbolAlphaDigit を利用すると「 090-0123-4567 」に「 567 」でマッチする。 TokenBigram の場合は「 4567 」でないとマッチしない。
TokenBigramIgnoreBlank | バイグラムでトークナイズする。 TokenBigram と異なり、空白を無視して処理する。 TokenBigram ではなく TokenBigramIgnoreBlank を利用すると「 み な さ ん 注 目 」に「 みなさん 」でマッチする。 TokenBigram の場合は「 み な さ ん 」でないとマッチしない。
TokenBigramIgnoreBlankSplitSymbol | バイグラムでトークナイズする。 TokenBigramSplitSymbol と異なり、空白を無視して処理する。 TokenBigramSplitSymbol ではなく TokenBigramIgnoreBlankSplitSymbol を利用すると「 ! !? ?? 」に「 ??? 」でマッチする。 TokenBigramSplitSymbol の場合は「 ? ?? 」でないとマッチしない。
TokenBigramIgnoreBlankSplitSymbolAlpha | バイグラムでトークナイズする。 TokenBigramSplitSymbolAlpha と異なり、空白を無視して処理する。 TokenBigramSplitSymbolAlpha ではなく TokenBigramIgnoreBlankSplitSymbolAlpha を利用すると「 I am a pen. 」に「 ama 」でマッチする。 TokenBigramSplitSymbolAlpha の場合は「 am a 」でないとマッチしない。
TokenBigramIgnoreBlankSplitSymbolAlphaDigit | バイグラムでトークナイズする。 TokenBigramSplitSymbolAlphaDigit と異なり、空白を無視して処理する。 TokenBigramSplitSymbolAlphaDigit ではなく TokenBigramIgnoreBlankSplitSymbolAlphaDigit を利用すると「 090 0123 4567 」に「 9001 」でマッチする。 TokenBigramSplitSymbolAlphaDigit の場合は「 90 01 」でないとマッチしない。
TokenDelimit | 空白区切りでトークナイズする。 「 movie horror topic 」をトークナイズすると「 movie 」、「 horror 」、「 topic 」になります。
TokenDelimitNull | null文字（ \\0 ）区切りでトークナイズする。 「 movie\\0horror\\0topic 」をトークナイズすると「 movie 」、「 horror 」、「 topic 」になります。
TokenUnigram | ユニグラムでトークナイズする。ただし、連続したアルファベット・連続した数字・連続した記号はそれぞれ1つのトークンとして扱う。そのため、2文字以上のトークンも存在する。これはノイズを減らすためである。
TokenTrigram | トリグラムでトークナイズする。ただし、連続したアルファベット・連続した数字・連続した記号はそれぞれ1つのトークンとして扱う。そのため、4文字以上のトークンも存在する。これはノイズを減らすためである。

デフォルトのパーサは configure の --with-default-tokenizer オプションでビルド時に指定することができます。:

    ./configure --with-default-tokenizer TokenMecab ...

また、 my.cnf またはSQL内で mroonga_default_tokenizer 変数を指定することでも指定できます。 my.cnf で指定するとMySQLを再起動しても値は変更されたままですが、反映させるために再起動しなければいけません。一方、SQLで指定した場合はすぐに設定が反映されますが、MySQLが再起動すると設定は失われます。

my.cnf:

    [mysqld]
    mroonga_default_tokenizer=TokenMecab

SQL:

    SET GLOBAL mroonga_default_tokenizer = TokenMecab;
    -- Query OK, 0 rows affected (0.00 sec)

  ノーマライザーの指定方法

Mroongaは、文書のエンコーディング(照合順序)に応じたノーマライザーを使用します。これはテキストをトークナイズするときとテーブルのキーを保存するときに使われます。

utf8_general_ci または utf8mb4_general_ci の場合、NormalizerMySQLGeneralCI ノーマライザーが使用されます。

utf8_unicode_ci または utf8mb4_unicode_ci の場合、NormalizerMySQLUnicodeCI ノーマライザーが使用されます。

utf8_bin の場合、ノーマライザーは使用されません。

以下は、 utf8_unicode_ci の照合順序を指定して NormalizerMySQLUnicodeCI ノーマライザーを使用する例です。

    SET NAMES utf8;
    -- Query OK, 0 rows affected (0.00 sec)
    CREATE TABLE diaries (
      day DATE PRIMARY KEY,
      content VARCHAR(64) NOT NULL,
      FULLTEXT INDEX (content)
    ) Engine=Mroonga DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    -- Query OK, 0 rows affected (0.18 sec)
    INSERT INTO diaries VALUES ("2013-04-23", "ブラックコーヒーを飲んだ。");
    -- Query OK, 1 row affected (0.00 sec)
    SELECT *
      FROM diaries
     WHERE MATCH (content) AGAINST ("+ふらつく" IN BOOLEAN MODE);
    -- +------------+-----------------------------------------+
    -- | day        | content                                 |
    -- +------------+-----------------------------------------+
    -- | 2013-04-23 | ブラックコーヒーを飲んだ。 |
    -- +------------+-----------------------------------------+
    -- 1 row in set (0.00 sec)
    SELECT *
      FROM diaries
     WHERE MATCH (content) AGAINST ("+ﾌﾞﾗｯｸ" IN BOOLEAN MODE);
    -- +------------+-----------------------------------------+
    -- | day        | content                                 |
    -- +------------+-----------------------------------------+
    -- | 2013-04-23 | ブラックコーヒーを飲んだ。 |
    -- +------------+-----------------------------------------+
    -- 1 row in set (0.00 sec)

Mroongaは、Groongaのノーマライザーを指定する以下のような構文を持っています。:

    FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"'

詳細は Groongaのノーマライザーのドキュメント <https://groonga.org/ja/docs/reference/normalizers.html> を確認してください。

以下は、NormalizerAuto のノーマライザーを使用する例です。

    SET NAMES utf8;
    -- Query OK, 0 rows affected (0.00 sec)
    CREATE TABLE diaries (
      day DATE PRIMARY KEY,
      content VARCHAR(64) NOT NULL,
      FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"'
    ) Engine=Mroonga DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    -- Query OK, 0 rows affected (0.19 sec)
    INSERT INTO diaries VALUES ("2013-04-23", "ブラックコーヒーを飲んだ。");
    -- Query OK, 1 row affected (0.00 sec)
    SELECT *
      FROM diaries
     WHERE MATCH (content) AGAINST ("+ふらつく" IN BOOLEAN MODE);
    -- Empty set (0.00 sec)
    SELECT *
      FROM diaries
     WHERE MATCH (content) AGAINST ("+ﾌﾞﾗｯｸ" IN BOOLEAN MODE);
    -- +------------+-----------------------------------------+
    -- | day        | content                                 |
    -- +------------+-----------------------------------------+
    -- | 2013-04-23 | ブラックコーヒーを飲んだ。 |
    -- +------------+-----------------------------------------+
    -- 1 row in set (0.00 sec)

  トークンフィルターの指定方法

Mroongaは、Groongaのトークンフィルターを指定する以下のような構文を持っています。:

    FULLTEXT INDEX (content) COMMENT 'token_filters "TokenFilterStem"'

以下は、TokenFilterStem のトークンフィルターを使用する例です。

    SELECT mroonga_command('register token_filters/stem');
    -- +------------------------------------------------+
    -- | mroonga_command('register token_filters/stem') |
    -- +------------------------------------------------+
    -- | true                                           |
    -- +------------------------------------------------+
    -- 1 row in set (0.00 sec)
    CREATE TABLE memos (
      id INT NOT NULL PRIMARY KEY,
      content TEXT NOT NULL,
      FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto", token_filters "TokenFilterStem"'
    ) Engine=Mroonga DEFAULT CHARSET=utf8;
    -- Query OK, 0 rows affected (0.18 sec)
    INSERT INTO memos VALUES (1, "I develop Groonga");
    -- Query OK, 1 row affected (0.00 sec)
    INSERT INTO memos VALUES (2, "I'm developing Groonga");
    -- Query OK, 1 row affected (0.00 sec)
    INSERT INTO memos VALUES (3, "I developed Groonga");
    -- Query OK, 1 row affected (0.00 sec)
    SELECT *
      FROM memos
     WHERE MATCH (content) AGAINST ("+develops" IN BOOLEAN MODE);
    -- +----+------------------------+
    -- | id | content                |
    -- +----+------------------------+
    -- |  1 | I develop Groonga      |
    -- |  2 | I'm developing Groonga |
    -- |  3 | I developed Groonga    |
    -- +----+------------------------+
    -- 3 rows in set (0.01 sec)

詳細は Groongaのトークンフィルターのドキュメント <https://groonga.org/ja/docs/reference/token_filters.html> を確認してください。

以下は、TokenFilterStopWord のトークンフィルターを使用する例です。

    SELECT mroonga_command("register token_filters/stop_word");
    -- +-----------------------------------------------------+
    -- | mroonga_command("register token_filters/stop_word") |
    -- +-----------------------------------------------------+
    -- | true                                                |
    -- +-----------------------------------------------------+
    -- 1 row in set (0.00 sec)
    CREATE TABLE terms (
      term VARCHAR(64) NOT NULL PRIMARY KEY,
      is_stop_word BOOL NOT NULL
    ) Engine=Mroonga COMMENT='tokenizer "TokenBigram", token_filters "TokenFilterStopWord"' DEFAULT CHARSET=utf8;
    -- Query OK, 0 rows affected (0.12 sec)
    CREATE TABLE memos (
      id INT NOT NULL PRIMARY KEY,
      content TEXT NOT NULL,
      FULLTEXT INDEX (content) COMMENT 'table "terms"'
    ) Engine=Mroonga DEFAULT CHARSET=utf8;
    -- Query OK, 0 rows affected (0.17 sec)
    INSERT INTO terms VALUES ("and", true);
    -- Query OK, 1 row affected (0.00 sec)
    INSERT INTO memos VALUES (1, "Hello");
    -- Query OK, 1 row affected (0.00 sec)
    INSERT INTO memos VALUES (2, "Hello and Good-bye");
    -- Query OK, 1 row affected (0.00 sec)
    INSERT INTO memos VALUES (3, "Good-bye");
    -- Query OK, 1 row affected (0.00 sec)
    SELECT *
      FROM memos
     WHERE MATCH (content) AGAINST ('+"Hello and"' IN BOOLEAN MODE);
    -- +----+--------------------+
    -- | id | content            |
    -- +----+--------------------+
    -- |  1 | Hello              |
    -- |  2 | Hello and Good-bye |
    -- +----+--------------------+
    -- 2 rows in set (0.01 sec)

これは、全文検索用の語彙表テーブルを指定する方法を使用しています。

  Groongaのカラムフラグの指定方法

Mroongaは、Groongaのカラムフラグを指定する以下のような構文を持っています。:

    content TEXT COMMENT 'flags "COLUMN_SCALAR|COMPRESS_ZLIB"'

以下は、COMPRESS_ZLIB フラグを使用する例です。

    CREATE TABLE entries (
      id INT UNSIGNED PRIMARY KEY,
      content TEXT COMMENT 'flags "COLUMN_SCALAR|COMPRESS_ZLIB"'
    ) Engine=Mroonga DEFAULT CHARSET=utf8;
    -- Query OK, 0 rows affected (0.12 sec)

Groongaのカラムフラグの詳細については Groongaのドキュメント <https://groonga.org/ja/docs/reference/commands/column_create.html#parameters> を参照してください。

  位置情報検索の利用方法

ストレージモードでは全文検索だけではなく位置情報検索も高速に実行できます。ただし、MyISAMとは異なりデータとして格納できるのはPOINT型のみです。LINEなどの他のデータ型は保存できません。また、インデックスを用いた高速な検索に対応しているのはMBRContainsだけです。MBRDisjointなどには対応していません。

位置情報検索を利用する場合のテーブル定義はMyISAMと同様にPOINT型のカラムを定義し、そのカラムに対してSPATIAL INDEXを指定します。

    CREATE TABLE shops (
      id INT PRIMARY KEY AUTO_INCREMENT,
      name VARCHAR(255),
      location POINT NOT NULL,
      SPATIAL INDEX (location)
    ) ENGINE = Mroonga;
    -- Query OK, 0 rows affected (0.06 sec)

データの登録方法もMyISAMのときと同様にGeomFromText()関数を使って文字列からPOINT型の値を作成します。

    INSERT INTO shops VALUES (null, 'Nezu''s Taiyaki', GeomFromText('POINT(139.762573 35.720253)'));
    -- Query OK, 1 row affected (0.00 sec)
    INSERT INTO shops VALUES (null, 'Naniwaya', GeomFromText('POINT(139.796234 35.730061)'));
    -- Query OK, 1 row affected (0.00 sec)
    INSERT INTO shops VALUES (null, 'Yanagiya Taiyaki', GeomFromText('POINT(139.783981 35.685341)'));
    -- Query OK, 1 row affected (0.00 sec)

池袋駅（139.7101 35.7292）が左上の点、東京駅（139.7662 35.6815）が右下の点となるような長方形内にあるお店を探す場合は以下のようなSELECTになります。

    SELECT id, name, AsText(location)
      FROM shops
     WHERE MBRContains(GeomFromText('LineString(139.7101 35.7292, 139.7662 35.6815)'), location);
    -- +----+-----------------------+------------------------------------------+
    -- | id | name                  | AsText(location)                         |
    -- +----+-----------------------+------------------------------------------+
    -- |  1 | Nezu's Taiyaki        | POINT(139.762572777778 35.7202527777778) |
    -- +----+-----------------------+------------------------------------------+
    -- 1 row in set (0.00 sec)

位置情報で検索できていますね！

  レコードIDの取得方法

Groongaではテーブルにレコードを追加した際にレコードを一意に識別するための番号が割当てられます。

Mroongaではアプリケーションの開発を容易にするため、このレコードIDをSQLで取得できるようになっています。

レコードIDを取得するためには、テーブル定義時に _id という名前のカラムを作成して下さい。

    CREATE TABLE memos (
      _id INT,
      content VARCHAR(255),
      UNIQUE KEY (_id) USING HASH
    ) ENGINE = Mroonga;
    -- Query OK, 0 rows affected (0.04 sec)

_id カラムのデータ型は整数型(TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT)である必要があります。

また_idカラムにはインデックスを作成することが可能ですが、HASH形式である必要があります。

INSERTでテーブルにレコードを追加してみましょう。_idカラムは仮想カラムとして実装されており、また_idの値であるレコードIDはGroongaにより割当てられるため、SQLによる更新時に値を指定することはできません。更新対象から外すか、値に null を使用する必要があります。

    INSERT INTO memos VALUES (null, "Saury for today's dinner.");
    -- Query OK, 1 row affected (0.00 sec)
    INSERT INTO memos VALUES (null, "Update mroonga tomorrow.");
    -- Query OK, 1 row affected (0.00 sec)
    INSERT INTO memos VALUES (null, "Buy some dumpling on the way home.");
    -- Query OK, 1 row affected (0.00 sec)
    INSERT INTO memos VALUES (null, "Thank God It's meat day.");
    -- Query OK, 1 row affected (0.00 sec)

レコードIDを取得するには、_idカラムを含むようにしてSELECTを行います。

    SELECT * FROM memos;
    -- +------+------------------------------------------+
    -- | _id  | content                                  |
    -- +------+------------------------------------------+
    -- |    1 | Saury for today's dinner.                |
    -- |    2 | Update mroonga tomorrow.                 |
    -- |    3 | Buy some dumpling on the way home.       |
    -- |    4 | Thank God It's meat day.                 |
    -- +------+------------------------------------------+
    -- 4 rows in set (0.00 sec)

また直前のINSERTにより割当てられたレコードIDについては、last_insert_grn_id関数により取得することもできます。

    INSERT INTO memos VALUES (null, "Just one bottle of milk in the fridge.");
    -- Query OK, 1 row affected (0.00 sec)
    SELECT last_insert_grn_id();
    -- +----------------------+
    -- | last_insert_grn_id() |
    -- +----------------------+
    -- |                    5 |
    -- +----------------------+
    -- 1 row in set (0.00 sec)

last_insert_grn_id関数はユーザ定義関数(UDF)としてMroongaに含まれていますが、インストール時にCREATE FUNCTIONでMySQLに追加していない場合には、以下の関数定義DDLを実行しておく必要があります。

    CREATE FUNCTION last_insert_grn_id RETURNS INTEGER SONAME 'ha_mroonga.so';

ご覧のように_idカラムやlast_insert_grn_id関数を通じてレコードIDを取得することができました。ここで取得したレコードIDは後続のUPDATEなどのSQL文で利用すると便利です。

    UPDATE memos SET content = "So much milk in the fridge." WHERE _id = last_insert_grn_id();
    -- Query OK, 1 row affected (0.00 sec)
    -- Rows matched: 1  Changed: 1  Warnings: 0

  スニペット（キーワード周辺のテキスト）の取得方法

Mroongaは周辺テキスト付きでキーワードを取得する機能を提供しています。この機能は mroonga_snippet() <> UDFとして実装されています。

  類似文書検索の利用方法

類似文書検索では、クエリーにキーワードの代わりに文書の内容を指定します。

類似文書検索は、関連する文書を見つけるのに便利です。

実行例で使用するスキーマ定義はこちら。

    CREATE TABLE similarities (
      id INT PRIMARY KEY AUTO_INCREMENT,
      title VARCHAR(32),
      content VARCHAR(255),
      FULLTEXT INDEX (content)
    ) ENGINE = Mroonga DEFAULT CHARSET utf8;

実行例で使用するサンプルデータはこちら。

    INSERT INTO similarities (title, content)
           VALUES ('Groonga similar search', 'Groonga is an open-source fulltext search engine and column store.');
    INSERT INTO similarities (title, content)
           VALUES ('Mroonga similar search', 'Mroonga is an open-source storage engine for fast fulltext search with MySQL.');
    INSERT INTO similarities (title, content)
           VALUES ('Rroonga library', 'A library to use Groonga features from Ruby.');

以下は文書の内容による類似文書検索の出力例です。

    SELECT title FROM similarities WHERE MATCH(content) AGAINST ('There are many open-source fulltext search engine.' IN NATURAL LANGUAGE MODE);

AGAINST('...' IN NATURAL LANGUAGE MODE) に文書の内容を指定する必要があることに注意してください。

    SELECT title FROM similarities WHERE MATCH(content) AGAINST ('There are many open-source fulltext search engine.' IN NATURAL LANGUAGE MODE);
    -- +------------------------+
    -- | title                  |
    -- +------------------------+
    -- | Groonga similar search |
    -- | Mroonga similar search |
    -- +------------------------+
    -- 2 rows in set (0.00 sec)

類似度合いを向上させるには、言語特有のパーサーを使うとか、タグ付けされたデータを使って望ましくない検索結果を取り除く必要があります。

例えば、日本語の文書の類似文書検索をするなら、TokenMecab をパーサーに指定するのがおすすめです。以下は TokenMecab を使うスキーマ定義の例です。:

    CREATE TABLE similarities (
      id INT PRIMARY KEY AUTO_INCREMENT,
      title VARCHAR(32),
      content VARCHAR(255),
      FULLTEXT INDEX (content) COMMENT 'tokenizer "TokenMecab"'
    ) ENGINE = Mroonga DEFAULT CHARSET utf8;

  Groongaコマンドの実行方法

ストレージモードではMroongaはすべてのデータをGroongaのデータベースに保存します。Mroongaを使うことでSQLでGroongaのデータベースにアクセスできるようになります。SQLはとても強力ですが、ファセット検索などのようないくつかの操作が得意ではありません。

最近ではファセット検索は一般的なものになりました。amazon.comやebay.comのように多くのオンラインショッピングサイトがファセット検索をサポートしています。ファセット検索はユーザが検索結果を絞り込む前に絞り込み検索をし、その絞り込み検索の結果を表示します。ユーザは絞りこまれた結果から自分が探しているものを選ぶだけです。ファセット検索を使うとユーザは以下のようなメリットがあります。

•   ユーザはどうやって検索結果を絞り込むかを考える必要はありません。単に表示された絞り込み結果から選ぶだけです。

•   ユーザは「見つかりませんでした」ページを見ることがありません。ファセット検索では絞り込んだ結果のうち、ヒットする項目がある結果だけを表示します。

    絞り込み検索は検索結果に対して複数の GROUP BY 操作を実行する必要があります。SQLでファセット検索をやろうとすると、複数の SELECT リクエストが必要になります。これは効率的ではありません。

    Groongaは1回のgroongaコマンドでファセット検索をできます。これは効率的です。Groongaには select コマンドというファセット検索に対応した検索コマンドがあります。Groongaではファセット検索は「ドリルダウン（drilldown）」と呼んでいます。Groongaの select コマンドの詳細については Groongaのドキュメント <https://groonga.org/ja/docs/reference/commands/select.html> を参照してください。

    Mroongaは mroonga_command() 関数を提供しています。この関数を使えばSQLの中で好きなGroongaコマンドを実行できます。しかし、使うのは select コマンドだけにしておくべきです。スキーマやデータを変更するコマンドを使うと一貫性が壊れてしまうかもしれません。

    実行例で使用するスキーマ定義はこちら。

        CREATE TABLE diaries (
          id INT PRIMARY KEY AUTO_INCREMENT,
          content VARCHAR(255),
          date DATE,
          year YEAR,
          `year_month` VARCHAR(9),
          tag VARCHAR(32),
          FULLTEXT INDEX (content)
        ) ENGINE = Mroonga DEFAULT CHARSET utf8;

    実行例で使用するサンプルデータはこちら。

        INSERT INTO diaries (content, date, year, `year_month`, tag)
               VALUES ('Groonga is an open-source fulltext search engine and column store.',
                       '2013-04-08',
                       '2013',
                       '2013-04',
                       'groonga');
        INSERT INTO diaries (content, date, year, `year_month`, tag)
               VALUES ('Mroonga is an open-source storage engine for fast fulltext search with MySQL.',
                       '2013-04-09',
                       '2013',
                       '2013-04',
                       'MySQL');
        INSERT INTO diaries (content, date, year, `year_month`, tag)
               VALUES ('Tritonn is a patched version of MySQL that supports better fulltext search function with Senna.',
                       '2013-03-29',
                       '2013',
                       '2013-03',
                       'MySQL');

    各レコードには tag として groonga あるいは MySQL が付いています。各レコードは year と year_month カラムも持っています。ファセット検索のキーとして tag 、 year 、 year_month を使えます。

    Groongaはファセット検索のことをドリルダウンと呼んでいます。そのため、Groongaでのパラメータ名は --drilldown となっています。Groongaは検索結果をJSONで返します。そのため、 mroonga_command() も検索結果をJSONで返します。これはSQLらしくありません。JSON形式の検索結果は自分でパースしないといけません。

    以下は利用可能なファセット検索キーをすべて使った例です。（結果のJSONは整形済み）

        SELECT mroonga_command("select diaries --output_columns _id --limit 0 --drilldown tag,year,year_month") AS faceted_result;
        -- +-----------------------------+
        -- | faceted_result              |
        -- +-----------------------------+
        -- | [[[3],                      |
        -- |   [["_id","UInt32"]]],      |
        -- |  [[2],                      |
        -- |   [["_key","ShortText"],    |
        -- |    ["_nsubrecs","Int32"]],  |
        -- |   ["groonga",1],            |
        -- |   ["MySQL",2]],             |
        -- |  [[1],                      |
        -- |   [["_key","Time"],         |
        -- |    ["_nsubrecs","Int32"]],  |
        -- |   [1356998400.0,3]],        |
        -- |  [[2],                      |
        -- |   [["_key","ShortText"],    |
        -- |    ["_nsubrecs","Int32"]],  |
        -- |   ["2013-04",2],            |
        -- |   ["2013-03",1]]]           |
        -- +-----------------------------+
        -- 1 row in set (0.00 sec)

    最初の要素 [[3], [["_id","UInt32"]]] は通常の検索の結果です。これはファセット検索の結果ではありません。

    2番目、3番目、4番目の要素がファセット検索の結果です。

        [[2],
         [["_key","ShortText"],
          ["_nsubrecs","Int32"]],
         ["groonga",1],
         ["MySQL",2]]

        [[1],
         [["_key","Time"],
          ["_nsubrecs","Int32"]],
         [1356998400.0,3]]

        [[2],
         [["_key","ShortText"],
          ["_nsubrecs","Int32"]],
         ["2013-04",2],
         ["2013-03",1]]

    ファセット検索の結果の順序は --drilldown に指定した値に対応します。この例では、 --drilldown の値に tag と year と year_month を指定しています。そのため、最初のファセット検索の結果は tag 用の結果で、2番目は year 用の結果で、 3番目は year_month 用の結果です。

    各ファセット検索の結果は次のフォーマットになります。このフォーマットは通常の検索の結果と同じです。

        [[${THE_NUMBER_OF_RECORDS}],
         [[${OUTPUT_COLUMN_NAME_0}, ${OUTPUT_COLUMN_TYPE_0}],
          [${OUTPUT_COLUMN_NAME_1}, ${OUTPUT_COLUMN_TYPE_1}],
          ...,
          [${OUTPUT_COLUMN_NAME_N}, ${OUTPUT_COLUMN_TYPE_N}]]
         [${OUTPUT_COLUMN_VALUE_0_FOR_RECORD_0},
          ${OUTPUT_COLUMN_VALUE_1_FOR_RECORD_0},
          ...,
          ${OUTPUT_COLUMN_VALUE_N_FOR_RECORD_0}],
         [${OUTPUT_COLUMN_VALUE_0_FOR_RECORD_1},
          ${OUTPUT_COLUMN_VALUE_1_FOR_RECORD_1},
          ...,
          ${OUTPUT_COLUMN_VALUE_N_FOR_RECORD_1}],
         ...
         [${OUTPUT_COLUMN_VALUE_0_FOR_RECORD_M},
          ${OUTPUT_COLUMN_VALUE_1_FOR_RECORD_M},
          ...,
          ${OUTPUT_COLUMN_VALUE_N_FOR_RECORD_M}]]

    ファセット検索の結果の _key カラムの値はファセット検索で使用したキーを示します。

    たとえば、最初のファセット検索の結果（ tag のファセット検索の結果）はマッチしたレコード（今回のケースではすべてのレコード）は tag の値として groonga と MySQL があることを示しています。

        [[2],
         [["_key","ShortText"],
          ["_nsubrecs","Int32"]],
         ["groonga",1],
         ["MySQL",2]]

    ファセット検索の結果の _nsubrecs カラムの値は対応するファセット検索のキーを持つレコードが何件あるかを示します。

    たとえば、最初のファセット検索の結果（ tag のファセット検索の結果）は tag の値として groonga を持つレコードは1件あり、 tag の値として MySQL を持つレコードは2件あることを示しています。

        [[2],
         [["_key","ShortText"],
          ["_nsubrecs","Int32"]],
         ["groonga",1],
         ["MySQL",2]]

    詳細は Groongaのselectコマンドのドキュメント <https://groonga.org/ja/docs/reference/commands/select.html> を確認してください。

  正規表現検索の利用方法

ストレージモードでは、すでに述べたようにMroongaからGroongaの機能が使えます。つまりGroongaの機能を使って正規表現で検索できます。

Mroongaで正規表現を使うにはいくつか条件があります。

•   COMMENT にて TokenRegexp トークナイザーを指定してインデックスを作成する

•   WHERE MATCH ... AGAINST にて *SS プラグマを使う

    以下は正規表現による検索の出力例です。

        CREATE TABLE paths (
          content text,
          FULLTEXT INDEX content_index (content) COMMENT 'tokenizer "TokenRegexp", normalizer "NormalizerAuto"'
        ) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
        INSERT INTO paths VALUES ('/usr/bin/groonga');
        INSERT INTO paths VALUES ('/var/log/auth.log');
        INSERT INTO paths VALUES ('/var/log/messages');
        INSERT INTO paths VALUES ('/tmp/local/var/log/auth.log');
        SELECT * FROM paths WHERE MATCH(content) AGAINST ('*SS content @~ "\\\\A/var/log/auth"' IN BOOLEAN MODE);
        -- +-------------------+
        -- | content           |
        -- +-------------------+
        -- | /var/log/auth.log |
        -- +-------------------+
        -- 1 row in set (0.024 sec)

    *SS <#boolean-mode-pragma-ss> プラグマを使うことにより、 content @~ "\\\\A/var/log/auth" で /var/log/auth ではじまるレコードを検索できます。 @~ はGroongaで正規表現検索するためのオペレーターで、 "\\\\A/var/log/auth" は前方一致検索を行うので、 /var/log/auth.log だけがマッチします。 /tmp/local/var/log/auth.log がマッチしないのは、/var/log/auth ではじまっていないからです。

    構文の詳細は Groongaの正規表現のドキュメント <https://groonga.org/ja/docs/reference/regular_expression.html#syntax> を確認してください。

  ログ出力

Mroongaではデフォルトでログの出力を行うようになっています。

ログファイルはMySQLのデータディレクトリ直下に groonga.log というファイル名で出力されます。

以下はログの出力例です。

    2010-10-07 17:32:39.209379|n|b1858f80|mroonga 1.10 started.
    2010-10-07 17:32:44.934048|d|46953940|hash get not found (key=test)
    2010-10-07 17:32:44.936113|d|46953940|hash put (key=test)

ログのデフォルトの出力レベルはNOTICE（必要な情報のみ出力。デバッグ情報などは出力しない）となっております。

ログの出力レベルは mroonga_log_level というシステム変数で確認することができます（グローバル変数）。またSET文で動的に出力レベルを変更することもできます。

    SHOW VARIABLES LIKE 'mroonga_log_level';
    -- +-------------------+--------+
    -- | Variable_name     | Value  |
    -- +-------------------+--------+
    -- | mroonga_log_level | NOTICE |
    -- +-------------------+--------+
    -- 1 row in set (0.00 sec)
    SET GLOBAL mroonga_log_level=DUMP;
    -- Query OK, 0 rows affected (0.00 sec)
    SHOW VARIABLES LIKE 'mroonga_log_level';
    -- +-------------------+-------+
    -- | Variable_name     | Value |
    -- +-------------------+-------+
    -- | mroonga_log_level | DUMP  |
    -- +-------------------+-------+
    -- 1 row in set (0.00 sec)

設定可能なログレベルは以下の通りです。

•   NONE

•   EMERG

•   ALERT

•   CRIT

•   ERROR

•   WARNING

•   NOTICE

•   INFO

•   DEBUG

•   DUMP

    詳細は mroonga_log_level <#server-variable-mroonga-log-level> を参照してください。

    またFLUSH LOGSでログの再オープンを行うことができます。MySQLサーバを停止せずにログのローテートを行いたいような場合には、以下の手順で実行すると良いでしょう。

1.  groonga.log ファイルの名前を変更（OSコマンドのmvなどで）

2.  MySQLサーバに対して"FLUSH LOGS"を実行（mysqlコマンドあるいはmysqladminコマンドにて）

  次のステップ

これでストレージモードでMroongaを使えるようになりました！Mroongaをもっと速くしたい場合は 最適化 <> も参照してください。

脚注

[1] MySQL 5.1 リファレンスマニュアル :: 11 関数と演算子 :: 11.7 全文検索関数 <http://dev.mysql.com/doc/refman/5.1/ja/fulltext-search.html>

[2] Groongaではトークナイザーと呼んでいる。

  ラッパーモード

ここでは Mroonga におけるラッパーモードの利用方法を説明します。

バージョン 12.02 で変更: MySQL 8.0以降でラッパーモードのサポートをやめました。

  ラッパーモードの利用方法

ラッパーモードでは、既存のストレージエンジンをラップするかたちで Mroonga が動作します。ラップする対象となるストレージエンジンは、現在のところ SQL のコメントを利用して COMMENT = 'engine "InnoDB"' のように指定するようになっています。

注釈: 現在のところ、ラッパーモードではテーブルに必ずプライマリーキーを設定する必要があります。ストレージモードはこの限りではありません。

注釈: ラッパーモードでは現在ストレージモードでサポートされていない、以下をサポートしています。

•   null値

•   トランザクション (ストレージエンジンがサポートしている場合。ロールバックするとインデックスの不整合が発生します。インデックスを使った検索に影響するので、その場合にはMroongaのインデックスを再作成します。)

  全文検索の利用方法

インストールが確認できたら、テーブルを1つ作成してみましょう。 ENGINE = Mroonga とMroongaを指定するところがポイントです。:

    mysql> CREATE TABLE diaries (
        ->   id INT PRIMARY KEY AUTO_INCREMENT,
        ->   content VARCHAR(255),
        ->   FULLTEXT INDEX (content)
        -> ) ENGINE = Mroonga COMMENT = 'engine "InnoDB"' DEFAULT CHARSET utf8;
    Query OK, 0 rows affected (0.52 sec)

INSERTでデータを投入してみましょう。

    mysql> INSERT INTO diaries (content) VALUES ("It'll be fine tomorrow.");
    Query OK, 1 row affected (0.01 sec)
    mysql> INSERT INTO diaries (content) VALUES ("It'll rain tomorrow");
    Query OK, 1 row affected (0.00 sec)

全文検索を実行してみます。

    mysql> SELECT * FROM diaries WHERE MATCH(content) AGAINST("+fine" IN BOOLEAN MODE);
    +----+-----------------------------------------+
    | id | content                                 |
    +----+-----------------------------------------+
    |  1 | It'll be fine tomorrow. |
    +----+-----------------------------------------+
    1 row in set (0.00 sec)

おぉぉー。検索できましたね。

  検索スコアの取得方法

全文検索を行う際、指定したキーワードにより内容が一致するレコードを上位に表示したいというような場合があります。そうしたケースでは検索スコアを利用します。

検索スコアはMySQLの標準的な方法 [1] で取得できます。つまり、SELECTの取得するカラム名を指定するところやORDER BYのところにMATCH...AGAINSTを指定します。

それでは実際にやってみましょう。:

    mysql> INSERT INTO diaries (content) VALUES ("It's fine today. It'll be fine tomorrow as well.");
    Query OK, 1 row affected (0.00 sec)
    mysql> INSERT INTO diaries (content) VALUES ("It's fine today. But it'll rain tomorrow.");
    Query OK, 1 row affected (0.00 sec)
    mysql> SELECT *, MATCH (content) AGAINST ("+fine" IN BOOLEAN MODE) FROM diaries WHERE MATCH (content) AGAINST ("+fine" IN BOOLEAN MODE) ORDER BY MATCH (content) AGAINST ("+fine" IN BOOLEAN MODE) DESC;
    +----+--------------------------------------------------+---------------------------------------------------+
    | id | content                                          | MATCH (content) AGAINST ("+fine" IN BOOLEAN MODE) |
    +----+--------------------------------------------------+---------------------------------------------------+
    |  3 | It's fine today. It'll be fine tomorrow as well. |                                                 2 |
    |  1 | It'll be fine tomorrow.                          |                                                 1 |
    |  4 | It's fine today. But it'll rain tomorrow.        |                                                 1 |
    +----+--------------------------------------------------+---------------------------------------------------+
    3 rows in set (0.00 sec)

検索対象の文字列 fine をより多く含む、すなわち検索スコアの高い id = 3 のメッセージが上に来ていることが確認できます。また、SELECT句にMATCH AGAINSTを記述しているため、検索スコアも取得できています。

属性名を変更したい場合は AS を使って下さい。

    mysql> SELECT *, MATCH (content) AGAINST ("+fine" IN BOOLEAN MODE) AS score FROM diaries WHERE MATCH (content) AGAINST ("+fine" IN BOOLEAN MODE) ORDER BY MATCH (content) AGAINST ("+fine" IN BOOLEAN MODE) DESC;
    +----+--------------------------------------------------+-------+
    | id | content                                          | score |
    +----+--------------------------------------------------+-------+
    |  3 | It's fine today. It'll be fine tomorrow as well. |     2 |
    |  1 | It'll be fine tomorrow.                          |     1 |
    |  4 | It's fine today. But it'll rain tomorrow.        |     1 |
    +----+--------------------------------------------------+-------+
    3 rows in set (0.00 sec)

  全文検索用パーサの変更

MySQLは全文検索用のパーサ [2] を指定する以下のような構文を持っています。:

    FULLTEXT INDEX (content) WITH PARSER parser_name

しかし、この構文を利用する場合は、あらかじめすべてのパーサをMySQLに登録しておく必要があります。一方、Groongaはトークナイザー（MySQLでいうパーサ）を動的に追加することができます。そのため、Mroongaでもこの構文を採用するとGroonga側に動的に追加されたトークナイザーに対応できなくなります。Groongaに動的に追加されるトークナイザーにはMeCabを用いたトークナイザーもあり、この制限に縛られることは利便性を損なうと判断し、以下のようなコメントを用いた独自の構文を採用することにしました。:

    FULLTEXT INDEX (content) COMMENT 'tokenizer "TokenMecab"'

注釈: FULLTEXT INDEX に COMMENT を指定できるのはMySQL 5.5からになります。MySQL 5.1を利用している場合は後述の mroonga_default_parser 変数を利用してください。

トークナイザーに指定できるのは以下の値です。

  利用可能なトークナイザー一覧
トークナイザー | 説明
off | (非推奨) トークナイズしません。 off は content をそのまま扱いたい場合に使います。例えば、この値は前方一致検索のために指定します。
none | Added in version 8.07: トークナイズしません。"off"は content をそのまま扱いたい場合に使います。例えば、この値は前方一致検索のために指定します。
TokenBigram | バイグラムでトークナイズする。ただし、連続したアルファベット・連続した数字・連続した記号はそれぞれ1つのトークンとして扱う。そのため、3文字以上のトークンも存在する。これはノイズを減らすためである。 デフォルト値。
TokenMecab | MeCabを用いてトークナイズする。groongaがMeCabサポート付きでビルドされている必要がある。
TokenBigramSplitSymbol | バイグラムでトークナイズする。 TokenBigram と異なり、記号が連続していても特別扱いして1つのトークンとして扱わず通常のバイグラムの処理を行う。 TokenBigramではなく TokenBigramSplitSymbol を利用すると「 Is it really!?!?!? 」の「 !?!?!? 」の部分に「 !? 」でマッチする。 TokenBigram の場合は「 !?!?!? 」でないとマッチしない。
TokenBigramSplitSymbolAlpha | バイグラムでトークナイズする。 TokenBigramSplitSymbol に加えて、連続したアルファベットも特別扱いせずに通常のバイグラムの処理を行う。 TokenBigram ではなく TokenBigramSplitSymbolAlpha を利用すると「 Is it really? 」に「 real 」でマッチする。 TokenBigram の場合は「 really 」でないとマッチしない。
TokenBigramSplitSymbolAlphaDigit | バイグラムでトークナイズする。 TokenBigramSplitSymbolAlpha に加えて、連続した数字も特別扱いせずに通常のバイグラムの処理を行う。つまり、すべての字種を特別扱いせずにバイグラムの処理を行う。 TokenBigram ではなく TokenBigramSplitSymbolAlphaDigit を利用すると「 090-0123-4567 」に「 567 」でマッチする。 TokenBigram の場合は「 4567 」でないとマッチしない。
TokenBigramIgnoreBlank | バイグラムでトークナイズする。 TokenBigram と異なり、空白を無視して処理する。 TokenBigram ではなく TokenBigramIgnoreBlank を利用すると「 み な さ ん 注 目 」に「 みなさん 」でマッチする。 TokenBigram の場合は「 み な さ ん 」でないとマッチしない。
TokenBigramIgnoreBlankSplitSymbol | バイグラムでトークナイズする。 TokenBigramSplitSymbol と異なり、空白を無視して処理する。 TokenBigramSplitSymbol ではなく TokenBigramIgnoreBlankSplitSymbol を利用すると「 ! !? ?? 」に「 ??? 」でマッチする。 TokenBigramSplitSymbol の場合は「 ? ?? 」でないとマッチしない。
TokenBigramIgnoreBlankSplitSymbolAlpha | バイグラムでトークナイズする。 TokenBigramSplitSymbolAlpha と異なり、空白を無視して処理する。 TokenBigramSplitSymbolAlpha ではなく TokenBigramIgnoreBlankSplitSymbolAlpha を利用すると「 I am a pen. 」に「 ama 」でマッチする。 TokenBigramSplitSymbolAlpha の場合は「 am a 」でないとマッチしない。
TokenBigramIgnoreBlankSplitSymbolAlphaDigit | バイグラムでトークナイズする。 TokenBigramSplitSymbolAlphaDigit と異なり、空白を無視して処理する。 TokenBigramSplitSymbolAlphaDigit ではなく TokenBigramIgnoreBlankSplitSymbolAlphaDigit を利用すると「 090 0123 4567 」に「 9001 」でマッチする。 TokenBigramSplitSymbolAlphaDigit の場合は「 90 01 」でないとマッチしない。
TokenDelimit | 空白区切りでトークナイズする。 「 movie horror topic 」をトークナイズすると「 movie 」、「 horror 」、「 topic 」になります。
TokenDelimitNull | null文字（ \\0 ）区切りでトークナイズする。 「 movie\\0horror\\0topic 」をトークナイズすると「 movie 」、「 horror 」、「 topic 」になります。
TokenUnigram | ユニグラムでトークナイズする。ただし、連続したアルファベット・連続した数字・連続した記号はそれぞれ1つのトークンとして扱う。そのため、2文字以上のトークンも存在する。これはノイズを減らすためである。
TokenTrigram | トリグラムでトークナイズする。ただし、連続したアルファベット・連続した数字・連続した記号はそれぞれ1つのトークンとして扱う。そのため、4文字以上のトークンも存在する。これはノイズを減らすためである。

デフォルトのパーサは configure の --with-default-tokenizer オプションでビルド時に指定することができます。:

    ./configure --with-default-tokenizer TokenMecab ...

また、my.cnfまたはSQL内で mroonga_default_tokenizer 変数を指定することでも指定できます。my.cnfで指定するとMySQLを再起動しても値は変更されたままですが、反映させるために再起動しなければいけません。一方、SQLで指定した場合はすぐに設定が反映されますが、MySQLが再起動すると設定は失われます。

my.cnf:

    [mysqld]
    mroonga_default_tokenizer=TokenMecab

SQL:

    mysql> SET GLOBAL mroonga_default_tokenizer = TokenMecab;
    Query OK, 0 rows affected (0.00 sec)

  ノーマライザーの指定方法

Mroongaは、文書のエンコーディング(照合順序)に応じたノーマライザーを使用します。これはテキストをトークナイズするときとテーブルのキーを保存するときに使われます。

utf8_general_ci または utf8mb4_general_ci の場合、NormalizerMySQLGeneralCI ノーマライザーが使用されます。

utf8_unicode_ci または utf8mb4_unicode_ci の場合、NormalizerMySQLUnicodeCI ノーマライザーが使用されます。

utf8_bin の場合、ノーマライザーは使用されません。

以下は、 utf8_unicode_ci の照合順序を指定して NormalizerMySQLUnicodeCI ノーマライザーを使用する例です。:

    mysql> SET NAMES utf8;
    Query OK, 0 rows affected (0.00 sec)
    mysql> CREATE TABLE diaries (
        ->   day DATE PRIMARY KEY,
        ->   content VARCHAR(64) NOT NULL,
        ->   FULLTEXT INDEX (content)
        -> ) Engine=Mroonga DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    Query OK, 0 rows affected (0.18 sec)
    mysql> INSERT INTO diaries VALUES ("2013-04-23", "ブラックコーヒーを飲んだ。");
    Query OK, 1 row affected (0.00 sec)
    mysql> SELECT * FROM diaries
        ->        WHERE MATCH (content) AGAINST ("+ふらつく" IN BOOLEAN MODE);
    +------------+-----------------------------------------+
    | day        | content                                 |
    +------------+-----------------------------------------+
    | 2013-04-23 | ブラックコーヒーを飲んだ。 |
    +------------+-----------------------------------------+
    1 row in set (0.00 sec)
    mysql> SELECT * FROM diaries
        ->        WHERE MATCH (content) AGAINST ("+ﾌﾞﾗｯｸ" IN BOOLEAN MODE);
    +------------+-----------------------------------------+
    | day        | content                                 |
    +------------+-----------------------------------------+
    | 2013-04-23 | ブラックコーヒーを飲んだ。 |
    +------------+-----------------------------------------+
    1 row in set (0.00 sec)

Mroongaは、Groongaのノーマライザーを指定する以下のような構文を持っています。:

    FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"'

詳細は Groongaのノーマライザーのドキュメント <https://groonga.org/ja/docs/reference/normalizers.html> を確認してください。

以下は、NormalizerAuto のノーマライザーを使用する例です。:

    mysql> SET NAMES utf8;
    Query OK, 0 rows affected (0.00 sec)
    mysql> CREATE TABLE diaries (
        ->   day DATE PRIMARY KEY,
        ->   content VARCHAR(64) NOT NULL,
        ->   FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"'
        -> ) Engine=Mroonga DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    Query OK, 0 rows affected (0.19 sec)
    mysql> INSERT INTO diaries VALUES ("2013-04-23", "ブラックコーヒーを飲んだ。");
    Query OK, 1 row affected (0.00 sec)
    mysql> SELECT * FROM diaries
        ->        WHERE MATCH (content) AGAINST ("+ふらつく" IN BOOLEAN MODE);
    Empty set (0.00 sec)
    mysql> SELECT * FROM diaries
        ->        WHERE MATCH (content) AGAINST ("+ﾌﾞﾗｯｸ" IN BOOLEAN MODE);
    +------------+-----------------------------------------+
    | day        | content                                 |
    +------------+-----------------------------------------+
    | 2013-04-23 | ブラックコーヒーを飲んだ。 |
    +------------+-----------------------------------------+
    1 row in set (0.00 sec)

  スニペット（キーワード周辺のテキスト）の取得方法

Mroongaは周辺テキスト付きでキーワードを取得する機能を提供しています。この機能は mroonga_snippet() <> UDFとして実装されています。

  ログ出力

Mroongaではデフォルトでログの出力を行うようになっています。

ログファイルはMySQLのデータディレクトリ直下に groonga.log というファイル名で出力されます。

以下はログの出力例です。

    2010-10-07 17:32:39.209379|n|b1858f80|mroonga 1.10 started.
    2010-10-07 17:32:44.934048|d|46953940|hash get not found (key=test)
    2010-10-07 17:32:44.936113|d|46953940|hash put (key=test)

ログのデフォルトの出力レベルはNOTICE（必要な情報のみ出力。デバッグ情報などは出力しない）となっております。

ログの出力レベルは mroonga_log_level というシステム変数で確認することができます（グローバル変数）。またSET文で動的に出力レベルを変更することもできます。

    mysql> SHOW VARIABLES LIKE 'mroonga_log_level';
    +-------------------+--------+
    | Variable_name     | Value  |
    +-------------------+--------+
    | mroonga_log_level | NOTICE |
    +-------------------+--------+
    1 row in set (0.00 sec)
    mysql> SET GLOBAL mroonga_log_level=DUMP;
    Query OK, 0 rows affected (0.00 sec)
    mysql> SHOW VARIABLES LIKE 'mroonga_log_level';
    +-------------------+-------+
    | Variable_name     | Value |
    +-------------------+-------+
    | mroonga_log_level | DUMP  |
    +-------------------+-------+
    1 row in set (0.00 sec)

設定可能なログレベルは以下の通りです。

•   NONE

•   EMERG

•   ALERT

•   CRIT

•   ERROR

•   WARNING

•   NOTICE

•   INFO

•   DEBUG

•   DUMP

    詳細は mroonga_log_level <#server-variable-mroonga-log-level> を参照してください。

    またFLUSH LOGSでログの再オープンを行うことができます。MySQLサーバを停止せずにログのローテートを行いたいような場合には、以下の手順で実行すると良いでしょう。

1.  groonga.log ファイルの名前を変更（OSコマンドのmvなどで）

2.  MySQLサーバに対して"FLUSH LOGS"を実行（mysqlコマンドあるいはmysqladminコマンドにて）

  次のステップ

これでラッパーモードでMroongaを使えるようになりました！Mroongaをもっと速くしたい場合は 最適化 <> も参照してください。

脚注

[1] MySQL 5.1 リファレンスマニュアル :: 11 関数と演算子 :: 11.7 全文検索関数 <http://dev.mysql.com/doc/refman/5.1/ja/fulltext-search.html>

[2] Groongaではトークナイザーと呼んでいる。

リファレンス

  最適化

Mroongaはより速くレスポンスを返すためにいくつか最適化しています。

いくつかの最適化は ストレージモード <> でだけ有効です。

  必要なカラムだけ取得

この最適化は ストレージモード <> でだけ有効です。

Groongaはカラム（列）ストアアーキテクチャーを採用しています。これは、1行の1つのカラムの値を取得するために、すべてのカラムの値を取得しなくてもよいということです。Groongaは必要なカラムの値だけを取得できます。

InnoDBとMyISAMはロー（行）ストアアーキテクチャーを採用しています。InnoDBとMyISAMは、1行の1つのカラムの値が必要な場合でもすべてのカラムの値を取得する必要があります。

SELECT で必要なカラムだけを指定した場合、Mroongaは指定されたカラムの値だけを取得します。Mroongaは他のカラムの値を取得しません。

Mroongaは処理とI/Oを減らすことでより高速になります。

これがこの最適化です。

以下はこの最適化を説明するためのテーブル定義です。:

    CREATE TABLE t1 (
      c1 INT PRIMARY KEY AUTO_INCREMENT,
      c2 INT,
      c3 INT,
      ...
      c11 VARCHAR(20),
      c12 VARCHAR(20),
      ...
      c20 DATETIME
    ) ENGINE=Mroonga DEFAULT CHARSET=utf8;

以下はこの最適化を説明するための SELECT です。:

    SELECT c1, c2, c11 FROM t1 WHERE c2 = XX AND c12 = "XXX";

このケースではMroongaは c1 、 c2 、 c11 、 c12 カラムの値だけを取得します。 c3 、 c4 、 ...、 c10 、 c13 、 ...、 c19 、c20 カラムの値は取得しません。

  行カウント

この最適化は ストレージモード <> でだけ有効です。

MySQLは COUNT(*) を処理する時、カラムの値が必要ないにも関わらず、ストレージエンジンモジュールにすべてのカラムの値を要求します。

この場合、Mroongaはカラムの値を取得しません。

Mroongaは処理とI/Oを減らすことでより高速になります。

これがこの最適化です。

以下はこの最適化を説明するための SELECT です。:

    SELECT COUNT(*) FROM t1 WHERE MATCH(c2) AGAINST("+keyword" IN BOOLEAN MODE);

この SELECT は COUNT(*) だけを取得し、 WHERE の条件はインデックスだけで処理できます。この場合、Mroongaはこの最適化を使います。

この最適化が使われたかどうかは Mroonga_count_skip <#status-variable-mroonga-count-skip> ステータス変数を参照するとわかります。:

    mysql> SHOW STATUS LIKE 'Mroonga_count_skip';
    +--------------------+-------+
    | Variable_name      | Value |
    +--------------------+-------+
    | Mroonga_count_skip | 1     |
    +--------------------+-------+
    1 row in set (0.00 sec)

Mroonga_count_skip <#status-variable-mroonga-count-skip> ステータス変数の値はMroongaがこの最適化を使うとインクリメントされます。

mroonga_enable_optimization <#server-variable-mroonga-enable-optimization> に false を指定するとこの最適化を無効にできます。

  ORDER BY LIMIT

この最適化は ストレージモード <> と ラッパーモード <> 両方で有効です

MySQLは、ヒットレコード数が多くても、インデックスを使ってソート済みの結果を取得できるなら ORDER BY と LIMIT を少ないコストで処理できます。

MySQLは MATCH() AGAINST(IN NATURAL LANGUAGE MODE) でこの処理を使えますが、 MATCH() AGAINST(IN BOOLEAN MODE) では使えません。

これは、多くのレコードがマッチする MATCH() AGAINST(IN BOOLEAN MODE) には時間がかかる可能性があるということです。

MroongaはGroongaを使って ORDER BY と LIMIT を処理し、MySQLには処理対象のレコードだけを返します。マッチレコード数が多いとき、MySQLで処理するよりもGroongaで処理する方が非常に高速です。

これがこの最適化です。

以下はこの最適化を説明するための SELECT です。:

    SELECT *
      FROM t1
     WHERE MATCH(c2) AGAINST("+keyword" IN BOOLEAN MODE)
     ORDER BY c1 LIMIT 1;

この SELECT は全文検索とソートをGroongaで実行し、MySQLには1件のレコードのみ返します。

この最適化が使われたかどうかは Mroonga_fast_order_limit <#status-variable-mroonga-fast-order-limit> ステータス変数を参照するとわかります。:

    mysql> SHOW STATUS LIKE 'Mroonga_fast_order_limit';
    +--------------------------+-------+
    | Variable_name            | Value |
    +--------------------------+-------+
    | Mroonga_fast_order_limit | 1     |
    +--------------------------+-------+
    1 row in set (0.00 sec)

Mroonga_fast_order_limit <#status-variable-mroonga-fast-order-limit> ステータス変数はMroongaがこの最適化を使うとインクリメントされます。

この最適化は以下のすべての条件が真のときだけ使われます。

•   ストレージモード <> ： WHERE 節にある条件が1つの MATCH AGAINST と0個以上の算術演算だけのとき。算術演算とは column < 100 のような演算です。

•   ラッパーモード <> ： WHERE 節にある条件が MATCH AGAINST だけのとき。

•   JOIN がない。

•   GROUP BY がない。

•   SQL_CALC_FOUND_ROWS がない。

•   LIMIT がある。

•   ストレージモード <> ： ORDER BY 節にはカラムまたは WHERE 節で使っているものと同じ MATCH AGAINST しかない。

•   ラッパーモード <> ： ORDER BY 節にはプライマリキーまたは WHERE 節で使っているものと同じ MATCH AGAINST しかない。

  SQLコマンド

このセクションでは、利用可能なSQLコマンドと利用できないSQLコマンドを記載しています。

  利用可能なSQLコマンドの一覧

•   ALTER TABLE table_name ADD COLUMN column_name TEXT

•   ALTER TABLE table_name ADD FULLTEXT INDEX index_name (column_name)

•   ALTER TABLE table_name ADD SPATIAL KEY index_name (geometry_column_name)

•   ALTER TABLE table_name ENGINE = mroonga

•   ALTER TABLE table_name RENAME new_table_name

•   COMMIT

•   CREATE FULLTEXT INDEX index_name ON table_name(column_name)

•   CREATE FULLTEXT INDEX index_name ON table_name(column_name, ...)

•   CREATE TABLE IF NOT EXISTS table_name (...)

•   CREATE TABLE \`table-name-with-hyphen\` (...)

•   CREATE TABLE table_name (... FULLTEXT INDEX index_name (column_name) COMMENT 'tokenizer "TokenMecab"')

•   CREATE TABLE table_name (... FULLTEXT INDEX index_name (column_name) COMMENT 'normalizer "NormalizerMySQLUnicodeCIExceptKanaCIKanaWithVoicedSoundMark"')

•   CREATE TABLE table_name (... FULLTEXT INDEX index_name (column_name) COMMENT 'tokenizer "TokenDelimit", normalizer "NormalizerMySQLUnicodeCIExceptKanaCIKanaWithVoicedSoundMark"')

•   CREATE TABLE table_name (... FULLTEXT INDEX index_name (column_name))

•   CREATE TABLE table_name (... FULLTEXT INDEX index_name (column_name, ...))

•   CREATE TABLE table_name (... INDEX (column_name))

•   CREATE TABLE table_name (... INDEX (column_name, ...))

•   CREATE TABLE table_name (... INDEX USING BTREE (column_name))

•   CREATE TABLE table_name (... PRIMARY KEY (column_name))

•   CREATE TABLE table_name (...) CHARSET ASCII

•   CREATE TABLE table_name (...) CHARSET BINARY

•   CREATE TABLE table_name (...) CHARSET CP932

•   CREATE TABLE table_name (...) CHARSET EUCJPMS

•   CREATE TABLE table_name (...) CHARSET KOI8R

•   CREATE TABLE table_name (...) CHARSET LATIN1

•   CREATE TABLE table_name (...) CHARSET SJIS

•   CREATE TABLE table_name (...) CHARSET UJIS

•   CREATE TABLE table_name (...) CHARSET UTF8

•   CREATE TABLE table_name (...) CHARSET UTF8MB4

•   CREATE TABLE table_name (...) ENGINE=mroonga COMMENT = 'ENGINE "InnoDB"'

•   CREATE TABLE table_name (...) ENGINE=mroonga

•   CREATE TABLE table_name (\`_id\` INT)

•   CREATE TABLE table_name (\`_id\` INT, KEY(_id) USING HASH)

•   CREATE TABLE table_name (column_name BIGINT UNSIGNED)

•   CREATE TABLE table_name (column_name BIGINT)

•   CREATE TABLE table_name (column_name BINARY(...))

•   CREATE TABLE table_name (column_name BIT)

•   CREATE TABLE table_name (column_name BLOB)

•   CREATE TABLE table_name (column_name CHAR(...))

•   CREATE TABLE table_name (column_name DATE)

•   CREATE TABLE table_name (column_name DATETIME)

•   CREATE TABLE table_name (column_name DECIMAL)

•   CREATE TABLE table_name (column_name DOUBLE)

•   CREATE TABLE table_name (column_name ENUM(...))

•   CREATE TABLE table_name (column_name FLOAT)

•   CREATE TABLE table_name (column_name GEOMETRY NOT NULL)

•   CREATE TABLE table_name (column_name INT UNSIGNED)

•   CREATE TABLE table_name (column_name INT)

•   CREATE TABLE table_name (column_name LONGBLOB)

•   CREATE TABLE table_name (column_name LONGTEXT)

•   CREATE TABLE table_name (column_name MEDIUMBLOB)

•   CREATE TABLE table_name (column_name MEDIUMINT UNSIGNED)

•   CREATE TABLE table_name (column_name MEDIUMINT)

•   CREATE TABLE table_name (column_name MEDIUMTEXT)

•   CREATE TABLE table_name (column_name SET(...))

•   CREATE TABLE table_name (column_name SMALLINT UNSIGNED)

•   CREATE TABLE table_name (column_name SMALLINT)

•   CREATE TABLE table_name (column_name TEXT)

•   CREATE TABLE table_name (column_name TIME)

•   CREATE TABLE table_name (column_name TIMESTAMP)

•   CREATE TABLE table_name (column_name TINYBLOB)

•   CREATE TABLE table_name (column_name TINYINT UNSIGNED)

•   CREATE TABLE table_name (column_name TINYINT)

•   CREATE TABLE table_name (column_name TINYTEXT)

•   CREATE TABLE table_name (column_name VARBINARY(...))

•   CREATE TABLE table_name (column_name VARCHAR(...))

•   CREATE TABLE table_name (column_name YEAR)

•   CREATE TABLE table_name (column_name INT AUTO_INCREMENT)

•   CREATE TABLE table_name (column_name INT PRIMARY KEY)

•   CREATE TABLE table_name (column_name DATE PRIMARY KEY)

•   CREATE TABLE table_name (column_name DATETIME PRIMARY KEY)

•   CREATE TABLE table_name (column_name DATETIME(fractional_seconds_precision) PRIMARY KEY)

•   CREATE TABLE table_name (column_name DECIMAL PRIMARY KEY)

•   CREATE TABLE table_name (column_name DECIMAL(maximum_number_digits, fractional_seconds_precision) PRIMARY KEY)

•   CREATE TABLE table_name (column_name TIME PRIMARY KEY)

•   CREATE TABLE table_name (column_name TIME(fractional_seconds_precision) PRIMARY KEY)

•   CREATE TABLE table_name (column_name TIMESTAMP PRIMARY KEY)

•   CREATE TABLE table_name (column_name TIMESTAMP(fractional_seconds_precision) PRIMARY KEY)

•   CREATE TABLE table_name (column_name YEAR PRIMARY KEY)

•   CREATE TABLE table_name (column_name1 INT, column_name2 ..., KEY (column_name1, column_name2))

•   CREATE TABLE table_name (column_name1 DOUBLE, column_name2 ..., KEY (column_name1, column_name2))

•   CREATE TABLE table_name (column_name1 FLOAT, column_name2 ..., KEY (column_name1, column_name2))

•   CREATE TABLE table_name (column_name1 CHAR(...), column_name2 ..., KEY (column_name1, column_name2))

•   CREATE TABLE table_name (column_name1 VARCHAR(...), column_name2 ..., KEY (column_name1, column_name2))

•   CREATE TEMPORARY TABLE table_name (...)

•   DELETE FROM table_name WHERE ...

•   DROP INDEX column_name ON table_name

•   DROP TABLE IF EXISTS table_name, ...

•   DROP TABLE \`table-name-with-hyphen\`, ...

•   DROP TABLE table_name, ...

•   DROP TEMPORARY TABLE table_name

•   FLUSH LOGS

•   FLUSH TABLES

•   INSERT INTO (geometry_column_name) VALUES (GeomFromText('POINT(...)'))

•   INSERT INTO ... VALUES ...

•   INSERT INTO ... VALUES ... ON DUPLICATE KEY UPDATE ... (for PRIMARY KEY)

•   INSERT INTO ... VALUES ... ON DUPLICATE KEY UPDATE ... (for UNIQUE KEY)

•   INSERT INTO table_name (column_name, ...) SELECT ... FROM other_table_name

•   REPLACE INTO table_name SELECT ... FROM other_table_name ...

•   SELECT * FROM information_schema.plugins WHERE plugin_name = "mroonga"

•   SELECT * FROM table_name

•   SELECT * FROM table_name FORCE INDEX(index_name) WHERE ...

•   SELECT * FROM table_name ORDER BY column_name ASC LIMIT ...

•   SELECT * FROM table_name ORDER BY column_name ASC

•   SELECT * FROM table_name ORDER BY column_name DESC LIMIT ...

•   SELECT * FROM table_name ORDER BY column_name DESC

•   SELECT * FROM table_name ORDER BY column_name

•   SELECT * FROM table_name WHERE MATCH(column_name) AGAINST("*D+ word ..." IN BOOLEAN MODE)

•   SELECT * FROM table_name WHERE MATCH(column_name) AGAINST("*D- word ..." IN BOOLEAN MODE)

•   SELECT * FROM table_name WHERE MATCH(column_name) AGAINST("*DOR word ..." IN BOOLEAN MODE)

•   SELECT * FROM table_name WHERE MATCH(column_name) AGAINST("*W word ..." IN BOOLEAN MODE)

•   SELECT * FROM table_name WHERE MATCH(column_name) AGAINST("+word ..." IN BOOLEAN MODE)

•   SELECT * FROM table_name WHERE MATCH(column_name) AGAINST("..." IN BOOLEAN MODE)

•   SELECT * FROM table_name WHERE MATCH(column_name, ...) AGAINST("..." IN BOOLEAN MODE)

•   SELECT * FROM table_name WHERE MBRContains(GeomFromText('LineString(...)'), geometry_column_name)

•   SELECT * FROM table_name WHERE NOT MATCH(column_name) AGAINST("..." IN BOOLEAN MODE)

•   SELECT * FROM table_name WHERE column_name < ...

•   SELECT * FROM table_name WHERE column_name <= ...

•   SELECT * FROM table_name WHERE column_name = ...

•   SELECT * FROM table_name WHERE column_name > ...

•   SELECT * FROM table_name WHERE column_name >= ...

•   SELECT * FROM table_name WHERE column_name BETWEEN ... AND ...

•   SELECT * FROM table_name WHERE column_name IN (SELECT sub_column_name FROM sub_table_name WHERE MATCH(sub_text_column_name) AGAINST("..."))

•   SELECT *, MATCH(column_name) AGAINST("..." IN BOOLEAN MODE) FROM table_name WHERE MATCH(column_name) AGAINST("..." IN BOOLEAN MODE)

•   SELECT FOUND_ROWS()

•   SELECT SQL_CALC_FOUND_ROWS * FROM table_name WHERE MATCH(...) AGAINST("..." IN BOOLEAN MODE) ORDER BY column_name LIMIT start,n_records

•   SELECT last_insert_grn_id()

•   SET binlog_format="MIXED"

•   SET binlog_format="ROW"

•   SET binlog_format="STATEMENT"

•   TRUNCATE TABLE table_name

•   UPDATE table_name SET column_name = ...

  利用できないSQLコマンドの一覧

•   CREATE TABLE (...) CHARSET 上記にないキャラクタセット

•   INSERT INTO (geometry_column_name) VALUES (GeomFromText('LineString(...)'))

•   INSERT INTO (...) VALUES (null)

•   START TRANSACTION

    基本的には、Groongaがサポートしているキャラクタセット(EUC-JP/UTF-8/SJIS/LATIN1/KOI8R)はMroongaでもサポートされています。

  リストにないSQLコマンドを見つけました

もし、あなたがリストにないSQLコマンドを見つけて、そのSQLコマンドが動くかどうかを確認した場合は、そのSQLコマンドをこのリストに追加させてください。そのSQLコマンドを 開発チーム <https://groonga.org/ja/docs/community.html> に連絡してもらうか、 ソースファイル <https://github.com/mroonga/mroonga/blob/main/doc/source/reference.rst> に対するパッチをGitHubでpull requestしてくれれば取り込みます！

  サーバ変数の一覧

独自に追加されたサーバ変数を説明します。

  mroonga_action_on_fulltext_query_error

全文検索クエリエラーの振舞いです。

mroonga_action_on_fulltext_query_error のデフォルト値は ERROR_AND_LOG です。これは従来のmroongaと同等に振舞います。

使用可能な mroonga_action_on_fulltext_query_error のリストです。
値 | 説明
ERROR | エラーを報告する。ログは無効です。
ERROR_AND_LOG | エラーを報告する。ログは有効です。(これがデフォルトです)
IGNORE | エラーを無視する。ログは無効です。
IGNORE_AND_LOG | エラーを無視するが、ログは有効です。 (InnoDBと似た振舞です)

mroonga_action_on_fulltext_query_error を確認するためのSQL例です:

    mysql> SHOW VARIABLES LIKE 'mroonga_action_on_fulltext_query_error';
    +----------------------------------------+---------------+
    | Variable_name                          | Value         |
    +----------------------------------------+---------------+
    | mroonga_action_on_fulltext_query_error | ERROR_AND_LOG |
    +----------------------------------------+---------------+
    1 row in set (0.00 sec)

  mroonga_boolean_mode_syntax_flags

MATCH () AGAINST ('...' IN BOOLEAN MODE) の構文をカスタマイズするフラグです。

この変数はシステム変数でもセッション変数でもあります。

以下は利用可能なフラグの一覧です。
フラグ | 説明
DEFAULT | SYNTAX_QUERY,ALLOW_LEADING_NOT と同じです。
SYNTAX_QUERY | Groongaのクエリー構文 <https://groonga.org/ja/docs/reference/grn_expr/query_syntax.html>. Groongaのクエリー構文はMySQLのBOOLEAN MODEの構文と互換性があります。 SYNTAX_QUERY も SYNTAX_SCRIPT もどちらも指定されない場合は SYNTAX_QUERY が指定されたものとして扱われます。
SYNTAX_SCRIPT | Groongaのスクリプト構文 <https://groonga.org/ja/docs/reference/grn_expr/script_syntax.html> を使います。 これはJavaScriptのような構文です。この構文を使うとGroongaの全ての機能を使うことができます。 SYNTAX_QUERY と SYNTAX_SCRIPT が両方指定された場合は SYNTAX_SCRIPT を使います。
ALLOW_COLUMN | クエリー構文で COLUMN:... という構文を使えるようにします。これはMySQLのBOOLEAN MODEの構文とは互換性がありません。 この構文を使うと1つの MATCH () AGAINST () の中で複数のインデックスを使うことができます。MySQLは1つのクエリーの中で1つのインデックスしか使えません。この構文を使うことでこの制限を回避することができます。 この構文を使うと全文検索だけでなく、等価比較や前方一致検索など他の演算も使うことができます。 詳細は Groongaのクエリー構文 <https://groonga.org/ja/docs/reference/grn_expr/query_syntax.html> を参照してください。
ALLOW_UPDATE | クエリー構文の中で、値の更新をする COLUMN:=NEW_VALUE という構文を使えるようにします。
ALLOW_LEADING_NOT | クエリー構文で -NOT_INCLUDED_KEYWORD ... 構文を使えるようにします。

デフォルトのフラグは DEFAULT です。これはMySQLのBOOLEAN MODEと互換性のある構文です。

SYNTAX_QUERY,ALLOW_LEADING_NOT というようにカンマで区切って複数のフラグを指定できます。

Groongaのスクリプト構文を使うようにするSQLの例です:

    mysql> SET mroonga_boolean_mode_syntax_flags = "SYNTAX_SCRIPT";

  mroonga_database_path_prefix

TODO:

  mroonga_default_parser

バージョン 5.04 で非推奨: Use mroonga_default_tokenizer instead.

デフォルトの全文検索用パーサ。デフォルト値はconfigureの with-default-parser オプションで指定できます（無指定時は TokenBigram ）。

全文検索パーサーとして TokenBigramSplitSymbolAlphaDigit を使う例です。この例では body_index 全文検索インデックスは TokenBigramSplitSymbolAlphaDigit を使います。

    SET GLOBAL mroonga_default_parser=TokenBigramSplitSymbolAlphaDigit;
    CREATE TABLE diaries (
      id INT PRIMARY KEY AUTO_INCREMENT,
      body TEXT,
      FULLTEXT INDEX body_index (body)
    ) DEFAULT CHARSET UTF8;

  mroonga_default_tokenizer

Added in version 5.04.

全文検索用のデフォルトのトークナイザー。デフォルト値はconfigureの --with-default-tokenizer=TOKENIZER オプションで指定できます。このオプションを指定しないときは TokenBigram になります。

全文検索用インデックスのトークナイザーとして TokenBigramSplitSymbolAlphaDigit を使う例です。この例では body_index 全文検索インデックスは TokenBigramSplitSymbolAlphaDigit を使います。

    SET GLOBAL mroonga_default_tokenizer=TokenBigramSplitSymbolAlphaDigit;
    CREATE TABLE diaries (
      id INT PRIMARY KEY AUTO_INCREMENT,
      body TEXT,
      FULLTEXT INDEX body_index (body)
    ) DEFAULT CHARSET UTF8;

  mroonga_default_wrapper_engine

TODO:

  mroonga_dry_write

Groongaデータベースに実際にデータを書き込むかどうかを指定します。デフォルト値は OFF で、実際にGroongaデータベースにデータを書き込みます。通常はこの値を変更する必要はありません。この変数はベンチマーク時に便利です。この値を ON にすることでMySQLとMroongaだけの処理時間を計測することができます。この時間にGroongaの処理時間は含まれません。

Groongaデータベースに値を書き込まないようにするSQLの例です:

    mysql> SHOW VARIABLES LIKE 'mroonga_dry_write';
    +-------------------+-------+
    | Variable_name     | Value |
    +-------------------+-------+
    | mroonga_dry_write | OFF   |
    +-------------------+-------+
    1 row in set (0.00 sec)
    mysql> SET mroonga_dry_write = true;
    Query OK, 0 rows affected (0.00 sec)
    mysql> SHOW VARIABLES LIKE 'mroonga_dry_write';
    +-------------------+-------+
    | Variable_name     | Value |
    +-------------------+-------+
    | mroonga_dry_write | ON    |
    +-------------------+-------+
    1 row in set (0.00 sec)

  mroonga_enable_optimization

最適化を有効にするかどうかを指定します。デフォルト値は ON で最適化は有効になっています。通常はこの値を変更する必要はありません。この変数はベンチマーク時に便利です。

最適化を無効にするSQLの例です:

    mysql> SHOW VARIABLES LIKE 'mroonga_enable_optimization';
    +-----------------------------+-------+
    | Variable_name               | Value |
    +-----------------------------+-------+
    | mroonga_enable_optimization | ON    |
    +-----------------------------+-------+
    1 row in set (0.00 sec)
    mysql> SET mroonga_enable_optimization = false;
    Query OK, 0 rows affected (0.00 sec)
    mysql> SHOW VARIABLES LIKE 'mroonga_enable_optimization';
    +-----------------------------+-------+
    | Variable_name               | Value |
    +-----------------------------+-------+
    | mroonga_enable_optimization | OFF   |
    +-----------------------------+-------+
    1 row in set (0.00 sec)

  mroonga_libgroonga_support_lz4

GroongaライブラリーのLZ4サポート状況

GroongaライブラリーがLZ4をサポートしているかを確認するためのSQL例です:

    mysql> SHOW GLOBAL VARIABLES LIKE 'mroonga_libgroonga_support_lz4';
    +--------------------------------+-------+
    | Variable_name                  | Value |
    +--------------------------------+-------+
    | mroonga_libgroonga_support_lz4 | ON    |
    +--------------------------------+-------+

  mroonga_libgroonga_support_zlib

Groongaライブラリーのzlibサポート状況

Groongaライブラリーがzlibをサポートしているかを確認するためのSQL例です:

    mysql> SHOW GLOBAL VARIABLES LIKE 'mroonga_libgroonga_support_zlib';
    +---------------------------------+-------+
    | Variable_name                   | Value |
    +---------------------------------+-------+
    | mroonga_libgroonga_support_zlib | ON    |
    +---------------------------------+-------+

  mroonga_libgroonga_support_zstd

GroongaライブラリーのZstandardサポート状況

GroongaライブラリーがZstandardをサポートしているかを確認するためのSQL例です:

    mysql> SHOW GLOBAL VARIABLES LIKE 'mroonga_libgroonga_support_zstd';
    +---------------------------------+-------+
    | Variable_name                   | Value |
    +---------------------------------+-------+
    | mroonga_libgroonga_support_zstd | ON    |
    +---------------------------------+-------+

  mroonga_libgroonga_support_mecab

GroongaライブラリーのMeCabサポート状況

GroongaライブラリーがMeCabをサポートしているかを確認するためのSQL例です。

    mysql> SHOW GLOBAL VARIABLES LIKE 'mroonga_libgroonga_support_mecab';
    +----------------------------------+-------+
    | Variable_name                    | Value |
    +----------------------------------+-------+
    | mroonga_libgroonga_support_mecab | ON    |
    +----------------------------------+-------+

  mroonga_libgroonga_version

groongaライブラリのバージョン

groongaライブラリのバージョンを確認するためのSQL例です:

    mysql> SHOW VARIABLES LIKE 'mroonga_libgroonga_version';
    +----------------------------+------------------+
    | Variable_name              | Value            |
    +----------------------------+------------------+
    | mroonga_libgroonga_version | 1.2.8-9-gbf05b82 |
    +----------------------------+------------------+
    1 row in set (0.00 sec)

  mroonga_lock_timeout

TODO:

  mroonga_log_file

Mroongaのログファイル名。デフォルト値は groonga.log 。

ログファイルを /tmp/mroonga.log に変更する例です:

    mysql> SHOW VARIABLES LIKE 'mroonga_log_file';
    +------------------+-------------+
    | Variable_name    | Value       |
    +------------------+-------------+
    | mroonga_log_file | groonga.log |
    +------------------+-------------+
    1 row in set (0.00 sec)
    mysql> SET GLOBAL mroonga_log_file = "/tmp/mroonga.log";
    Query OK, 0 rows affected (0.00 sec)
    mysql> SHOW VARIABLES LIKE 'mroonga_log_file';
    +------------------+------------------+
    | Variable_name    | Value            |
    +------------------+------------------+
    | mroonga_log_file | /tmp/mroonga.log |
    +------------------+------------------+
    1 row in set (0.00 sec)

  mroonga_log_level

Mroongaのログの出力レベル。デフォルト値は NOTICE 。

使用可能な mroonga_log_level のリストです。
ログレベル | 説明
NONE | ログ出力なし。
EMERG | データベースの破損などの緊急に対処が必要なログメッセージを出力する。
ALERT | 内部的なエラーを示すログを出力する。
CRIT | デッドロックの発生など致命的なログメッセージを出力する。
ERROR | Mroongaが使用しているAPIのエラーログメッセージを出力する。
WARNING | 引数の誤りなどの警告ログメッセージを出力する。
NOTICE | 設定や状態の変化を示すログメッセージを出力する。
INFO | ファイル操作などの情報をログメッセージとして出力する。
DEBUG | デバッグメッセージを出力する。 Mroonga開発者やバグレポートの際にお勧めします。
DUMP | テストツール向けのダンプログメッセージを出力します。

ログレベルを DEBUG に変更する例です。 DEBUG レベルにするとデバッグ用のたくさんのメッセージがログに出力されます:

    mysql> SHOW VARIABLES LIKE 'mroonga_log_level';
    +-------------------+--------+
    | Variable_name     | Value  |
    +-------------------+--------+
    | mroonga_log_level | NOTICE |
    +-------------------+--------+
    1 row in set (0.00 sec)
    mysql> SET GLOBAL mroonga_log_level = "debug";
    Query OK, 0 rows affected (0.00 sec)
    mysql> SHOW VARIABLES LIKE 'mroonga_log_level';
    +-------------------+-------+
    | Variable_name     | Value |
    +-------------------+-------+
    | mroonga_log_level | DEBUG |
    +-------------------+-------+
    1 row in set (0.00 sec)

  mroonga_query_log_file

Mroongaのクエリーログファイル名。デフォルト値は空です。

この値が空の場合、クエリーログはファイルに保存されません。この値が空ではない場合は、クエリーログは指定されたファイルに保存されます。

クエリーログファイルを /tmp/mroonga_query.log に変更する例です:

    mysql> SHOW VARIABLES LIKE 'mroonga_query_log_file';
    +------------------------+-------+
    | Variable_name          | Value |
    +------------------------+-------+
    | mroonga_query_log_file |       |
    +------------------------+-------+
    1 row in set (0.00 sec)
    mysql> SET GLOBAL mroonga_query_log_file = "/tmp/mroonga.log";
    Query OK, 0 rows affected (0.00 sec)
    mysql> SHOW VARIABLES LIKE 'mroonga_query_log_file';
    +------------------------+------------------+
    | Variable_name          | Value            |
    +------------------------+------------------+
    | mroonga_query_log_file | /tmp/mroonga.log |
    +------------------------+------------------+
    1 row in set (0.00 sec)

  mroonga_n_workers

Added in version 15.00.

Groongaの内部処理の並列数を指定します。

Mroongaにおいては並列処理を有効にすると CREATE INDEX 時に並列で処理され高速化が見込まれます。

使用可能な値のリストです。デフォルト値は 0 です。
値 | 説明
0 または 1 | 並列実行しません。
2 以上 | 指定したスレッド数以下で並列実行します。
-1 | CPUのコア数以下のスレッドで並列実行します。

並列数を 2 に変更するSQLの例です:

    mysql> SHOW VARIABLES LIKE 'mroonga_n_workers';
    +-------------------+-------+
    | Variable_name     | Value |
    +-------------------+-------+
    | mroonga_n_workers | 0     |
    +-------------------+-------+
    1 row in set (0.001 sec)
    mysql> SET GLOBAL mroonga_n_workers = 2;
    Query OK, 0 rows affected (0.000 sec)
    mysql> SHOW VARIABLES LIKE 'mroonga_n_workers';
    +-------------------+-------+
    | Variable_name     | Value |
    +-------------------+-------+
    | mroonga_n_workers | 2     |
    +-------------------+-------+
    1 row in set (0.001 sec)

GLOBAL でのみ設定可能です。

SET GLOBAL で設定すると、次のセッションから有効になります。現在のセッションでは有効にならないことに注意してください。永続的に設定する場合は、my.cnf で設定してください。

  mroonga_match_escalation_threshold

マッチ方法をエスカレーションするかどうかを決定する閾値です。マッチ方法については Groongaの検索の仕様 <https://groonga.org/docs/spec/search.html> を確認してください。

デフォルト値はGroongaのデフォルト値と同じです。デフォルトの設定でインストールした場合は0になります。この変数のスコープは「グローバル」と「セッション」の両方なので、my.cnfまたは SET GLOBAL mroonga_match_escalation_threshold = THRESHOLD; でデフォルト値を設定できます。

マッチ方法がエスカレーションするかどうかを決定する閾値として-1を使った例です。-1は絶対エスカレーションしないという意味です。

    SET GLOBAL mroonga_match_escalation_threshold = -1;

この変数の値による挙動の変化を示す別の例です。

    CREATE TABLE diaries (
      id INT PRIMARY KEY AUTO_INCREMENT,
      title TEXT,
      tags TEXT,
      FULLTEXT INDEX tags_index (tags) COMMENT 'tokenizer "TokenDelimit"'
    ) ENGINE=mroonga DEFAULT CHARSET=UTF8;
    -- Test data
    INSERT INTO diaries (title, tags) VALUES ("Hello groonga!", "groonga install");
    INSERT INTO diaries (title, tags) VALUES ("Hello mroonga!", "mroonga install");
    -- Matches all records that have "install" tag.
    SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("install" IN BOOLEAN MODE);
    -- id        title   tags
    -- 1 Hello groonga!  groonga install
    -- 2 Hello mroonga!  mroonga install
    -- Matches no records by "gr" tag search because no "gr" tag is used.
    -- But matches a record that has "groonga" tag because search
    -- method is escalated and prefix search with "gr" is used.
    -- The default threshold is 0. It means that no records are matched then
    -- search method is escalated.
    SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("gr" IN BOOLEAN MODE);
    -- id        title   tags
    -- 1 Hello groonga!  groonga install
    -- Disables escalation.
    SET mroonga_match_escalation_threshold = -1;
    -- No records are matched.
    SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("gr" IN BOOLEAN MODE);
    -- id        title   tags
    -- Enables escalation again.
    SET mroonga_match_escalation_threshold = 0;
    -- Matches a record by prefix search with "gr".
    SELECT * FROM diaries WHERE MATCH (tags) AGAINST ("gr" IN BOOLEAN MODE);
    -- id        title   tags
    -- 1 Hello groonga!  groonga install

  mroonga_max_n_records_for_estimate

Added in version 5.02.

TODO:

  mroonga_enable_operations_recording

復旧のために操作を記録するかどうかを指定します。デフォルトは OFF です。これはGroongaデータベースに操作を記録しないというおkとです。この変数の変更を反映するには FLUSH TABLES でデータベースを開き直す必要があります。

操作記録を無効にするSQLの例です:

    mysql> SET GLOBAL mroonga_enable_operations_recording = false;
    Query OK, 0 rows affected (0.00 sec)
    mysql> FLUSH TABLES;
    Query OK, 0 rows affected (0.00 sec)
    mysql> SHOW GLOBAL VARIABLES LIKE 'mroonga_enable_operations_recording';
    +-------------------------------------+-------+
    | Variable_name                       | Value |
    +-------------------------------------+-------+
    | mroonga_enable_operations_recording | OFF   |
    +-------------------------------------+-------+

  mroonga_vector_column_delimiter

ベクターカラムを出力する際の区切り文字。デフォルト値は空白です。

区切り文字を空白からセミコロンに変更するSQL例です:

    mysql> SHOW VARIABLES LIKE 'mroonga_vector_column_delimiter';
    +---------------------------------+-------+
    | Variable_name                   | Value |
    +---------------------------------+-------+
    | mroonga_vector_column_delimiter |       |
    +---------------------------------+-------+
    1 row in set (0.00 sec)
    mysql> SET GLOBAL mroonga_vector_column_delimiter = ';';
    Query OK, 0 rows affected (0.00 sec)
    mysql> SHOW GLOBAL VARIABLES LIKE 'mroonga_vector_column_delimiter';
    +---------------------------------+-------+
    | Variable_name                   | Value |
    +---------------------------------+-------+
    | mroonga_vector_column_delimiter | ;     |
    +---------------------------------+-------+

  mroonga_version

Mroongaのバージョン

実行中のmroongaのバージョンを確認するためのSQL例です:

    mysql> SHOW VARIABLES LIKE 'mroonga_version';
    +-----------------+-------+
    | Variable_name   | Value |
    +-----------------+-------+
    | mroonga_version | 1.10  |
    +-----------------+-------+
    1 row in set (0.00 sec)

  mroonga_condition_push_down_type

Added in version 7.10.

コンデイションプッシュダウンサポートをどのように有効にするかを制御します。

デフォルト値は ONE_FULL_TEXT_SEARCH です。このときは WHERE 句に MATCH AGAINST が1つしかない場合だけコンデイションプッシュダウンを有効にします。

以下は有効な値の一覧です。
値 | 説明
NONE | コンディションプッシュダウンを使いません。
ALL | 常にコンディションプッシュダウンを使います。今のところ実験的な機能です。
ONE_FULL_TEXT_SEARCH | WHERE 内に MATCH AGAINST が1つだけある場合だけコンディションプッシュダウンを使います。 これがデフォルトです。

現在の値を確認するためのSQL例です:

    mysql> SHOW VARIABLES LIKE 'mroonga_condition_push_down_type';
    +----------------------------------+----------------------+
    | Variable_name                    | Value                |
    +----------------------------------+----------------------+
    | mroonga_condition_push_down_type | ONE_FULL_TEXT_SEARCH |
    +----------------------------------+----------------------+
    1 row in set (0.00 sec)

  ステータス変数の一覧

独自に追加されたステータス変数を説明します。

  Mroonga_count_skip

行カウント高速化機能が動作する度にカウントアップされます。スキーマ/SQLチューニングを行って行カウント高速化機能を利用できるようにした際の動作確認に利用できます。

確認例です:

    mysql> SHOW STATUS LIKE 'Mroonga_count_skip';
    +--------------------+-------+
    | Variable_name      | Value |
    +--------------------+-------+
    | Mroonga_count_skip | 0     |
    +--------------------+-------+
    1 row in set (0.00 sec)

  Mroonga_fast_order_limit

ORDER BY LIMIT 高速化機能が動作する度にカウントアップされます。スキーマ/SQLチューニングを行って ORDER BY LIMIT 高速化機能を利用できるようにした際の動作確認に利用できます。

確認例です:

    mysql> SHOW STATUS LIKE 'Mroonga_fast_order_limit';
    +--------------------------+-------+
    | Variable_name            | Value |
    +--------------------------+-------+
    | Mroonga_fast_order_limit | 0     |
    +--------------------------+-------+
    1 row in set (0.00 sec)

  Mroonga_condition_push_down

コンディションプッシュダウンを使う度にカウントアップします。コンディションプッシュダウンが使われたかどうかを確認するために利用できます。

確認例です:

    mysql> SHOW STATUS LIKE 'Mroonga_condition_push_down';
    +-----------------------------+-------+
    | Variable_name               | Value |
    +-----------------------------+-------+
    | Mroonga_condition_push_down | 1     |
    +-----------------------------+-------+
    1 row in set (0.00 sec)

  Mroonga_n_pooling_contexts

mroonga_command() <> 用にプールしているコンテキストの数を示します。このコンテキストは複数の mroonga_command() <> 呼び出しで再利用します。そのため、継続的に増え続けるということはありません。

確認例です:

    mysql> SHOW STATUS LIKE 'Mroonga_n_pooling_contexts';
    +----------------------------+-------+
    | Variable_name              | Value |
    +----------------------------+-------+
    | Mroonga_n_pooling_contexts | 0     |
    +----------------------------+-------+
    1 row in set (0.00 sec)

  Mroonga_memory_map_size

Added in version 12.0.4.

この値は、現在のメモリーマップサイズをバイトで表しています。

確認例です:

    mysql> SHOW STATUS LIKE 'Mroonga_memory_map_size';
    +-------------------------+----------+
    | Variable_name           | Value    |
    +-------------------------+----------+
    | Mroonga_memory_map_size | 83406848 |
    +-------------------------+----------+
    1 row in set (0.00 sec)

  UDF (ユーザ定義関数)

Mroongaではいくつか便利な機能をUDF (ユーザ定義関数)として提供しています。

  mroonga_command()

Added in version 3.02.

  概要

mroonga_command() UDFは与えられた文字列をGroongaコマンドとして実行し、Groongaコマンドの結果を返します。おそらく、Groongaコマンドは、MySQLのクエリーより高速です。

mroonga_command() は上級者向けのUDFです。通常このUDFを使う必要はありません。

  構文

mroonga_command() の引数は1つで必須の引数です。:

    mroonga_command(command)

command は文字列型の値です。実行するGroongaコマンドを指定します。

  使いかた

TODO

  引数

  必須引数

必須引数は1つで command です。

  command

実行するGroongaコマンドを指定します。

  返り値

指定されたGroongaコマンドを実行した結果を文字列として返します。

  参照

Groongaのドキュメント内の コマンド <https://groonga.org/ja/docs/reference/command.html> 。

  mroonga_escape()

Added in version 3.08.

  概要

mroonga_escape UDF は与えられた文字列をエスケープする機能を提供します。そしてまたエスケープすべき文字を引数として受け取ります。

  構文

mroonga_escape() には必須引数と省略可能引数とがあります。:

    mroonga_escape(string)
    mroonga_escape(string, special_characters)

  使いかた

エスケープされた特殊文字を使うクエリーの例です。:

    SELECT * FROM `symbols` WHERE MATCH(`content`) AGAINST(mroonga_escape("+hello_world()", "()") IN BOOLEAN MODE);

特殊文字のエスケープ例です。:

    SELECT mroonga_escape("+-<>~*()\"\\\:");
    -- \+\-\<\>\~\*\(\)\"\\\:

  引数

  必須引数

必須引数は string です。

  string

エスケープしたいテキストを指定します。

  省略可能引数

special_characters は省略可能な引数です。

  special_characters

エスケープする文字を指定します。

デフォルト値は +-<>~*()"\\: です。

  返り値

エスケープされた文字列を返します。

  mroonga_highlight_html()

Added in version 7.05.

  概要

mroonga_highlight_html() は対象のテキストの中の指定されたキーワードをハイライトします。各キーワードを <span class="keyword">...</span> で囲み、< や > といったHTMLの特殊文字をエスケープします。この関数の結果は、安全なHTMLとして使うことができます。

  構文

mroonga_highlight_html() には必須引数と省略可能引数とがあります。:

    mroonga_highlight_html(text, query AS query)
    mroonga_highlight_html(text, query AS query, open_tag AS open_tag)
    mroonga_highlight_html(text, query AS query, close_tag AS close_tag)
    mroonga_highlight_html(text, query AS query, open_tag AS open_tag, close_tag AS close_tag)
    mroonga_highlight_html(text, keyword1, ..., keywordN)
    mroonga_highlight_html(text, keyword1, ..., keywordN, open_tag AS open_tag)
    mroonga_highlight_html(text, keyword1, ..., keywordN, open_tag AS close_tag)
    mroonga_highlight_html(text, keyword1, ..., keywordN, open_tag AS open_tag, close_tag AS close_tag)

AS query はとても重要です。クエリーを使ってキーワードを抽出する場合に指定する必要があります。

open_tag と close_tag は省略可能です。ハイライトに使用するタグを指定することができます。

  使いかた

以下は'mroonga OR groonga'というクエリーによって、対象テキストの中の'mroonga'と'groonga'をハイライトする例です。 AS query を指定する必要があります。:

    SELECT mroonga_highlight_html('Mroonga is the Groonga based storage engine.',
                                  'mroonga OR groonga' AS query) AS highlighted;

実行結果はこちらです。:

    +--------------------------------------------------------------------------------------------------------+
    | highlighted                                                                                            |
    +--------------------------------------------------------------------------------------------------------+
    | <span class="keyword">Mroonga</span> is the <span class="keyword">Groonga</span> based storage engine. |
    +--------------------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)

'mroonga'と'groonga'というキーワードで対象となるテキストのハイライトをするクエリーです。

    SELECT mroonga_highlight_html('Mroonga is the Groonga based storage engine.',
                                  'mroonga', 'groonga') AS highlighted;

実行結果はこちらです。:

    +--------------------------------------------------------------------------------------------------------+
    | highlighted                                                                                            |
    +--------------------------------------------------------------------------------------------------------+
    | <span class="keyword">Mroonga</span> is the <span class="keyword">Groonga</span> based storage engine. |
    +--------------------------------------------------------------------------------------------------------+

  引数

  必須引数

必須引数が1つあります。

  text

ハイライトされるカラム名もしくは文字列が必要です。

  省略可能引数

いくつか省略可能な引数があります。

  query

詳細は Groongaのクエリー構文 <https://groonga.org/ja/docs/reference/grn_expr/query_syntax.html> を参照してください。

クエリーを使ってキーワードを抽出するには、以下のように AS query を指定する必要があります。:

    SELECT mroonga_highlight_html('...', 'mroonga OR groonga' AS query);

  keyword

ハイライトする0個以上のキーワードを指定します。

  open_tag

ハイライトの開始タグを指定します。

このパラメーターを指定するには、以下のように AS open_tag を指定する必要があります。

    SELECT mroonga_highlight_html('Mroonga is the Groonga based storage engine.', 'groonga',
                                  '<span class="my-class">' AS open_tag) AS highlighted;
    -- +----------------------------------------------------------------------------+
    -- | highlighted                                                                |
    -- +----------------------------------------------------------------------------+
    -- | Mroonga is the <span class="my-class">Groonga</span> based storage engine. |
    -- +----------------------------------------------------------------------------+

デフォルト値は <span class="keyword"> です。

  close_tag

ハイライトの終了タグを指定します。

このパラメーターを指定するには、以下のように AS close_tag を指定する必要があります。

    SELECT mroonga_highlight_html('Mroonga is the Groonga based storage engine.', 'groonga',
                                  '<mark>' AS open_tag, '</mark>' AS close_tag) AS highlighted;
    -- +-----------------------------------------------------------+
    -- | highlighted                                               |
    -- +-----------------------------------------------------------+
    -- | Mroonga is the <mark>Groonga</mark> based storage engine. |
    -- +-----------------------------------------------------------+

デフォルト値は </span> です。

  返り値

ハイライトされたHTMLを返します。省略可能な引数が指定されない場合、text に含まれるHTMLの特殊文字 < や > をエスケープします。

  mroonga_last_insert_grn_id()

  概要

mroonga_last_insert_grn_id() UDF は、最後に挿入されたレコードのIDを取得する機能を提供します。

このIDにはGroonga内で一意なIDです。

  構文

  使い方

  引数

  必須引数

  返り値

最後に挿入したレコードのIDを返します。

  mroonga_normalize()

Added in version 5.11.

  概要

mroonga_normalize() UDFはGroongaのノーマライザーによってテキストをノーマライズします。

  構文

mroonga_normalize() には必須引数と省略可能引数とがあります。:

    mroonga_normalize(string)
    mroonga_normalize(string, normalizer_name)

  使いかた

Groongaの NormalizerAuto ノーマライザーを使用した実行例はこちらです

    SELECT mroonga_normalize("ABCDあぃうぇ㍑");
    abcdあぃうぇリットル

Groongaの NormalizerMySQLUnicodeCIExceptKanaCIKanaWithVoicedSoundMark ノーマライザーを使用した実行例はこちらです

    SELECT mroonga_normalize("aBｃＤあぃウェ㍑", "NormalizerMySQLUnicodeCIExceptKanaCIKanaWithVoicedSoundMark");
    ABCDあぃうぇ㍑

  引数

  必須引数

必須引数は string です。

  string

ノーマライズしたいテキストを指定します。

  省略可能引数

normalizer_name は省略可能な引数です。

  normalizer_name

Groongaのノーラマイザー名を指定します。

デフォルト値は NormalizerAuto です。

  返り値

ノーマライズされた文字列を返します。

  mroonga_snippet()

Added in version 2.07.

  概要

mroonga_snippet() UDFは文脈付き索引を取得する機能を提供します。

  構文

mroonga_snippet() には必須引数と省略可能引数とがあります。:

    mroonga_snippet(document,
                    max_length,
                    max_count,
                    encoding,
                    skip_leading_spaces,
                    html_escape,
                    snippet_prefix,
                    snippet_suffix,
                    word1, word1_prefix, word1_suffix,
                    ...,
                    [wordN, wordN_prefix, wordN_suffix])

  使いかた

キーワードと周辺のテキストを検索結果として取得したいことがあります。

スニペットは「キーワードと関連するテキスト」という意味です。「文脈付き索引」ともいいます。

mroonga_snippet() 関数は検索結果からスニペットを取得する方法を提供します。

mroonga_snippet() UDFはストレージモードとラッパーモードいずれでも使 えます。

mroonga_snippet() 関数はユーザ定義関数(UDF)としてMroongaに含まれていますが、インストール時にCREATE FUNCTIONでMySQLに追加していない場合には、以下の関数定義DDLを実行しておく必要があります。

    mysql> CREATE FUNCTION mroonga_snippet RETURNS STRING SONAME 'ha_mroonga.so';

mroonga_snippet() 関数は MATCH ... AGAINST構文とともに使用して、テキストに含まれるキーワードとその関連語句を検索するのに便利です。

'fulltext'というキーワードと'MySQL'と'search'という関連語を含む文書の検索をしてみましょう。

mroonga_snippet() 関数は上記のことができます。

実行例のスキーマ定義(ストレージモード)はこちらです:

    CREATE TABLE `snippet_test` (
      `id` int(11) NOT NULL,
      `text` text,
      PRIMARY KEY (`id`),
      FULLTEXT KEY `text` (`text`)
    ) ENGINE=mroonga DEFAULT CHARSET=utf8

実行例(ラッパーモード)のスキーマ定義はこちらです。:

    CREATE TABLE `snippet_test` (
      `id` int(11) NOT NULL,
      `text` text,
      PRIMARY KEY (`id`),
      FULLTEXT KEY `text` (`text`)
    ) ENGINE=mroonga COMMENT 'engine = "innodb"' DEFAULT CHARSET=utf8

Here is the sample data for execution examples:

    INSERt INTO snippet_test (id, text) VALUES (1, 'An open-source fulltext search engine and column store.');
    INSERT INTO snippet_test (id, text) VALUES (2, 'An open-source storage engine for fast fulltext search with MySQL.');
    INSERT INTO snippet_test (id, text) VALUES (3, 'Tritonn is a patched version of MySQL that supports better fulltext search function with Senna.');

実行結果がこちらです。

    mysql> SELECT * FROM snippet_test;
    +----+-------------------------------------------------------------------------------------------------+
    | id | text                                                                                            |
    +----+-------------------------------------------------------------------------------------------------+
    |  1 | An open-source fulltext search engine and column store.                                         |
    |  2 | An open-source storage engine for fast fulltext search with MySQL.                              |
    |  3 | Tritonn is a patched version of MySQL that supports better fulltext search function with Senna. |
    +----+-------------------------------------------------------------------------------------------------+
    3 rows in set (0.00 sec)
    mysql> SELECT id, text, mroonga_snippet(text, 8, 2, 'ascii_general_ci', 1, 1, '...', '...<br>', 'fulltext', '<span class="w1">', '</span>', 'MySQL', '<span class="w2">', '</span>', 'search', '<span calss="w3">', '</span>') FROM snippet_test WHERE MATCH(text) AGAINST ('+fulltext' IN BOOLEAN MODE);
    +----+-------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | id | text                                                                                            | mroonga_snippet(text, 8, 2, 'ascii_general_ci', 1, 1, '...', '...<br>', 'fulltext', '<span class="w1">', '</span>', 'MySQL', '<span class="w2">', '</span>', 'search', '<span calss="w3">', '</span>') |
    +----+-------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    |  1 | An open-source fulltext search engine and column store.                                         | ...<span class="w1">fulltext</span>...<br>... <span calss="w3">search</span> ...<br>                                                                                                                   |
    |  2 | An open-source storage engine for fast fulltext search with MySQL.                              | ...<span class="w1">fulltext</span>...<br>... <span calss="w3">search</span> ...<br>                                                                                                                   |
    |  3 | Tritonn is a patched version of MySQL that supports better fulltext search function with Senna. | ...f <span class="w2">MySQL</span> ...<br>...<span class="w1">fulltext</span>...<br>                                                                                                                   |
    +----+-------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    3 rows in set (0.00 sec)

The keyword 'fulltext' and associated keyword 'MySQL' and 'search' has been extracted.

  引数

  必須引数

多くの必須引数があります。

  document

カラム名もしくは文字列が必要です。

  max_length

スニペットの最大長(バイト単位)が必要です。

  max_count

スニペットの最大要素数Nが必要です。

  encoding

文書のエンコーティング(照合順序)を指定します。エンコーディングとして 'ascii_general_ci'や'cp932_japanese_ci'、'eucjpms_japanese_ci'などが指 定できます。

  skip_leading_spaces

先頭の空白を無視するかを指定します。1なら無視し、0なら無視しません。

  html_escape

HTMLのエスケープを行うかを指定します。1ならエスケープし、0ならそのまま 出力します。

  prefix

スニペットの開始テキストを指定します。

  suffix

スニペットの終了テキストを指定します。

  省略可能引数

省略可能な引数として wordN と開始テキスト、終了テキストがあります。

  wordN

任意の単語指定します。

  wordN_prefix

N番目の単語の開始テキストを指定します。

  wordN_suffix

N番目の単語の終了テキストを指定します。

  返り値

スニペット文字列を返します。

  mroonga_snippet_html()

Added in version 5.09.

  概要

mroonga_snippet_html() UDFは、コンテキスト内のキーワードをハイライトする機能を提供します。

  構文

mroonga_snippet_html() には必須引数と省略可能引数とがあります:

    mroonga_snippet_html(document, key_word)

  使い方

  引数

  必須引数

多くの必須引数があります。

  省略可能引数

  返り値

スニペット文字列を返します。

  制限事項

Mroongaストレージエンジンにはいくつか制限があります。

  テーブルの制限事項

テーブルには以下の制限があります。この制限はGroongaに由来します。

•   1つのキーの最大サイズ：4KiB

•   キーのサイズを合計した上限値：4GiB

•   最大レコード数：

•   プライマリーキーがないテーブル：1,073,741,815 (2 30 - 9)

•   PRIMARY KEY または PRIMARY KEY USING BTREE を指定したテーブル：1,073,741,823 (2 30 - 1)

•   PRIMARY KEY USING HASH を指定したテーブル：536,870,912 (2 29)

    実際には他の諸条件の制約により上記の値まで到達しない場合もあります。

  インデックスの制限事項

1つのインデックスにおける論理上の上限値は以下のとおりです。テーブルごとに適用されるgroonga由来の制限です。

•   最大語彙数: 268,435,455 (約2億6千万)

•   最大インデックスサイズ: 256GiB

    実際には他の諸条件の制約により上記の値まで到達しない場合もあります。

    テーブルがこの制限に該当するかは SHOW TABLE STATUS や SHOW INDEX FROM ... などで確認してください。

  プライマリーキーに関する制限事項

プライマリーキーに空データ（0バイトのデータ）は使用できません。

  カラムの値に関する制限事項

ストレージモードにおいて、カラムの値には制限があります。

MroongaストレージエンジンはNULL値を自動的に補正します。

例えば、 DATE 型や DATETIME 型に指定されたNULL値はMroongaストレージエンジンが日や月の値として0を1へと自動的に補正します。

つまり、0月は1月へ、0日は1日として扱います。

そして、NULL値はUNIX時間の0秒 (1970-01-01)として扱います。

このような自動変換は DATE 型や DATETIME 型に限定されません。

NULL値はカラムのデフォルト値へと変換されます。多くの場合、文字列型であれば空文字列へ、数値型であれば0へと変換されます。

上記挙動を示す例はこちらです。

    CREATE TABLE date_limitation (
      id INT PRIMARY KEY AUTO_INCREMENT,
      input varchar(32) DEFAULT NULL,
      date DATE DEFAULT NULL
    ) ENGINE=mroonga DEFAULT CHARSET=UTF8;
    CREATE TABLE datetime_limitation (
      id INT PRIMARY KEY AUTO_INCREMENT,
      input varchar(32) DEFAULT NULL,
      datetime DATETIME DEFAULT NULL
    ) ENGINE=mroonga DEFAULT CHARSET=UTF8;
    -- Test data for date_limitation
    INSERT INTO date_limitation (input) VALUES ("NULL");
    INSERT INTO date_limitation (input, date) VALUES ("1970-00-00", "1970-00-00");
    -- Test data for datetime_limitation
    INSERT INTO datetime_limitation (input) VALUES ("NULL");
    INSERT INTO datetime_limitation (input, datetime) VALUES ("1970-00-00 00:00:00", "1970-00-00 00:00:00");

実行結果はこちらです。:

    mysql> select * from date_limitation;
    +----+------------+------------+
    | id | input      | date       |
    +----+------------+------------+
    |  1 | NULL       | 1970-01-01 |
    |  2 | 1970-00-00 | 1970-01-01 |
    +----+------------+------------+
    2 rows in set (0.00 sec)
    mysql> select * from datetime_limitation;
    +----+---------------------+---------------------+
    | id | input               | datetime            |
    +----+---------------------+---------------------+
    |  1 | NULL                | 1970-01-01 00:00:00 |
    |  2 | 1970-00-00 00:00:00 | 1970-01-01 00:00:00 |
    +----+---------------------+---------------------+
    2 rows in set (0.00 sec)

  カラムサイズの制限事項

1つのカラムにつき、次の制限があります。

•   カラムに格納した値の合計サイズの上限値: 256GiB

  全文検索

  ブーリアンモード

  概要

Mroongaは MATCH AGAINST に IN BOOLEAN MODE 修飾子をつけることでブーリアン全文検索を実行できます。:

    SELECT ... WHERE MATCH(column) AGAINST ('...' IN BOOLEAN MODE);

通常、デフォルトの IN NATURAL LANGUAGE MODE よりも IN BOOLEAN MODE の方が適切です。なぜなら IN BOOLEAN MODE はWeb検索エンジンのクエリーと似ているからです。多くのユーザーはWeb検索エンジンのクエリーに慣れています。

ブーリアン全文検索のクエリーでは MySQLがサポートしている修飾子 <https://dev.mysql.com/doc/refman/5.6/ja/fulltext-boolean.html> とMroonga独自のプラグマを使うことができます。

この修飾子とプラグマで検索結果の順位を変更できます。

修飾子もプラグマもどちらも使わずに検索した場合、検索キーワードをより多く含むレコードの方が順位が高くなります。

  使いかた

以下は例を示すためのスキーマとデータです。:

    CREATE TABLE books (
      `id` INTEGER AUTO_INCREMENT,
      `title` text,
      PRIMARY KEY(`id`),
      FULLTEXT INDEX title_index (title)
    ) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
    INSERT INTO books (title) VALUES ('Professional MySQL');
    INSERT INTO books (title) VALUES ('MySQL for Professional');
    INSERT INTO books (title) VALUES ('Mroonga = MySQL + Groonga');

  修飾子

サポートしている修飾子は次の通りです。

  キーワード1 キーワード2

キーワード1 キーワード2 のようにキーワードの間に演算子がない場合は、指定したキーワードのどれかひとつでも含まれていればヒット、という検索条件になります。

Mroonga for というクエリーは Mroonga または for が含まれているという意味です。:

    SELECT title
      FROM books
     WHERE MATCH(title) AGAINST('Mroonga for' IN BOOLEAN MODE);
    -- +---------------------------+
    -- | title                     |
    -- +---------------------------+
    -- | Mroonga = MySQL + Groonga |
    -- | MySQL for Professional    |
    -- +---------------------------+

  キーワード1 OR キーワード2

OR （大文字にすること）は左辺のキーワードまたは右辺のキーワードのうち少なくともどちらか1つは含まれていること、という意味です。

Mroonga OR for というクエリーは Mroonga または for が含まれているという意味です。:

    SELECT title
      FROM books
     WHERE MATCH(title) AGAINST('Mroonga OR for' IN BOOLEAN MODE);
    -- +---------------------------+
    -- | title                     |
    -- +---------------------------+
    -- | Mroonga = MySQL + Groonga |
    -- | MySQL for Professional    |
    -- +---------------------------+

OR はデフォルトの演算子です。省略可能です。 Mroonga OR for と Mroonga for はどちらも同じ結果を返します。

  +キーワード

キーワードの前に「+」をつけると、そのキーワードは必ず含まれていること、という検索条件になります。

+MySQL +Mroonga というクエリーは MySQL も Mroonga もどちらも含まれていること、という意味になります。:

    SELECT title
      FROM books
     WHERE MATCH(title) AGAINST('+MySQL +Groonga' IN BOOLEAN MODE);
    -- +---------------------------+
    -- | title                     |
    -- +---------------------------+
    -- | Mroonga = MySQL + Groonga |
    -- +---------------------------+

  -キーワード

キーワードの前に「-」をつけると、そのキーワードは含まれないこと、という検索条件になります。

+MySQL -Mroonga というクエリーは MySQL は含まれるけど Mroonga は含まれないという意味になります。:

    SELECT title
      FROM books
     WHERE MATCH(title) AGAINST('+MySQL -Mroonga' IN BOOLEAN MODE);
    -- +------------------------+
    -- | title                  |
    -- +------------------------+
    -- | Professional MySQL     |
    -- | MySQL for Professional |
    -- +------------------------+

  プレフィックス*

プレフィックスの後に「*」をつけると、そのプレフィックスの単語を含むこと、という検索条件になります。

+M* というクエリーは M から始まる単語（この場合は MySQL と Mroonga ）が含まれていること、という意味になります。:

    SELECT title
      FROM books
     WHERE MATCH(title) AGAINST('+M*' IN BOOLEAN MODE);
    -- +---------------------------+
    -- | title                     |
    -- +---------------------------+
    -- | Mroonga = MySQL + Groonga |
    -- | Professional MySQL        |
    -- | MySQL for Professional    |
    -- +---------------------------+

注釈: 正確に言うと、「単語」はあなたが思っている「単語」ではないかもしれません。この文脈での「単語」は「トークン」ということです。「トークン」は単語ではないかもしれません。たとえば、「It's」の中のトークンは「It」と「'」と「s」です。

mroonga_command() <> と tokenize <https://groonga.org/ja/docs/reference/commands/tokenize.html> を使うとトークンを確認できます。:

    SELECT mroonga_command('tokenize TokenBigram "It''s" NormalizerMySQLGeneralCI');
    -- +--------------------------------------------------------------------------+
    -- | mroonga_command('tokenize TokenBigram "It''s" NormalizerMySQLGeneralCI') |
    -- +--------------------------------------------------------------------------+
    -- | [                                                                        |
    -- |   {                                                                      |
    -- |     "value":"IT",                                                        |
    -- |     "position":0,                                                        |
    -- |     "force_prefix":false                                                 |
    -- |   },                                                                     |
    -- |   {                                                                      |
    -- |     "value":"'",                                                         |
    -- |     "position":1,                                                        |
    -- |     "force_prefix":false                                                 |
    -- |   },                                                                     |
    -- |   {                                                                      |
    -- |     "value":"S",                                                         |
    -- |     "position":2,                                                        |
    -- |     "force_prefix":false                                                 |
    -- |   }                                                                      |
    -- | ]                                                                        |
    -- +--------------------------------------------------------------------------+

上の結果のJSONの値は手で整形しています。

  "フレーズ"

ダブルクォート（ " ）でフレーズを囲むと、そのフレーズが必ず含まれていること、という検索条件になります。

+"Professional MySQL" というクエリーは Professional MySQL というフレーズが含まれていること、という意味になります。このクエリーは MySQL for Profession にはマッチしません。 MySQL for Profession は MySQL という単語も Professional という単語も含んでいますが、 Professional MySQL というフレーズは含んでいません。:

    SELECT title
      FROM books
     WHERE MATCH(title) AGAINST('+"Professional MySQL"' IN BOOLEAN MODE);
    -- +--------------------+
    -- | title              |
    -- +--------------------+
    -- | Professional MySQL |
    -- +--------------------+

  (サブ式...)

カッコを使うと式をグルーピングできます。

+(Groonga OR Mroonga) +MySQL というクエリーは次のような意味です。

•   Groonga あるいは Mroonga のどちらかが含まれている。

•   MySQL が含まれている。

    以下はこのクエリーの実行結果です。:

        SELECT title
          FROM books
         WHERE MATCH(title) AGAINST('+(Groonga OR Mroonga) +MySQL' IN BOOLEAN MODE);
        -- +---------------------------+
        -- | title                     |
        -- +---------------------------+
        -- | Mroonga = MySQL + Groonga |
        -- +---------------------------+

  プラグマ

プラグマはクエリーのメタデータです。プラグマを指定することでクエリーのパース方法を変更できます。

実行方法をカスタマイズするためにクエリーの先頭にプラグマを埋め込むことができます。

プラグマはクエリーの先頭になければいけません。クエリーの先頭に空白を入れてはいけません。プラグマは * から始まります。:

    SELECT MATCH AGAINST('*PRAGMA ...' IN BOOLEAN MODE);

複数のプラグマを指定することができます。:

    SELECT MATCH AGAINST('*PRAGMA1PRAGMA2 ...' IN BOOLEAN MODE);

以下は利用可能なプラグマの一覧です。

  D プラグマ

D プラグマはデフォルトの演算子を指定します。個別の演算子を省略するとデフォルトの演算子を使います。

D プラグマの構文は次の通りです。 ${OPERATOR} には OR または + または - を指定します。:

    *D${OPERATOR}

  DOR

DOR はデフォルトの演算子として「OR」を使うという意味です。

これがデフォルトです。

DOR を使う例は次の通りです。 '*DOR for Mroonga' IN BOOLEAN MODE は for または Mroonga を含むという意味です。

    SELECT title
     FROM books
    WHERE MATCH (title) AGAINST('*DOR for Mroonga' IN BOOLEAN MODE);
    -- +---------------------------+
    -- | title                     |
    -- +---------------------------+
    -- | MySQL for Professional    |
    -- | Mroonga = MySQL + Groonga |
    -- +---------------------------+

  D+

D+ はデフォルトの演算子として「AND」を使うという意味です。これはWeb検索エンジンのクエリーと同じ挙動です。

D+ を使う例は次の通りです。 '*D+ MySQL Mroonga' IN BOOLEAN MODE は MySQL と Mroonga の両方を含むという意味です。:

    SELECT title
     FROM books
    WHERE MATCH (title) AGAINST('*D+ MySQL Mroonga' IN BOOLEAN MODE);
    -- +---------------------------+
    -- | title                     |
    -- +---------------------------+
    -- | Mroonga = MySQL + Groonga |
    -- +---------------------------+

  D-

D- はデフォルトの演算子として「NOT」を使うという意味です。

D- を使う例は次の通りです。 '*D- MySQL Mroonga' IN BOOLEAN MODE は MySQL を含むが Mroonga を含まないという意味です。:

    SELECT title
     FROM books
    WHERE MATCH (title) AGAINST('*D- MySQL Mroonga' IN BOOLEAN MODE);
    -- +------------------------+
    -- | title                  |
    -- +------------------------+
    -- | Professional MySQL     |
    -- | MySQL for Professional |
    -- +---------------------------+

  W プラグマ

W プラグマはマルチカラムインデックス用のプラグマです。検索対象のセクションとその重みを指定します。

各セクションごとに違う重みを指定できます。デフォルトの重みは 1 です。 1 は重みがないという意味です。

W プラグマの構文は次の通りです。 ${SECTION} は0ではなく1から始まる数値です。 ${WEIGHT} は省略可能です。:

    *W[${SECTION1}[:${WEIGHT1}]][,${SECTION2}[:${WEIGHT2}]][,...]

次は例を示すためのスキーマとデータです。 W プラグマを使うためにはマルチカラムインデックスを作る必要があります。:

    CREATE TABLE memos (
      `id` INTEGER AUTO_INCREMENT,
      `title` text,
      `content` text,
      PRIMARY KEY(`id`),
      FULLTEXT INDEX text_index (title, content)
    ) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
    INSERT INTO memos (title, content) VALUES (
      'MySQL', 'MySQL is a RDBMS.'
    );
    INSERT INTO memos (title, content) VALUES (
      'Groonga', 'Groonga is a full text search engine.'
    );
    INSERT INTO memos (title, content) VALUES (
      'Mroonga', 'Mroonga is a storage engine for MySQL based on Groonga.'
    );

次の例は重みの使い方を示す例です。 title カラムは重みが 10 で、 content カラムは重みが 1 です。これは title カラムの中にあるキーワードは content カラムの中にあるキーワードよりも10倍重要だということです。

    SELECT title,
           content,
           MATCH (title, content) AGAINST('*W1:10,2:1 +Groonga' IN BOOLEAN MODE) AS score
      FROM memos;
    -- +---------+--------------------------------------------------------+-------+
    -- | title   | content                                                | score |
    -- +---------+--------------------------------------------------------+-------+
    -- | MySQL   | MySQL is a RDBMS.                                      |     0 |
    -- | Groonga | Groonga is a full text search engine.                  |    11 |
    -- | Mroonga | Mroonga is a storage engine for MySQL based on Groonga |     1 |
    -- +---------+--------------------------------------------------------+-------+

最初のレコードのスコアーは 0 です。なぜなら、 title カラムにも content カラムにも Groonga が含まれていないからです。

二つめのレコードのスコアーは 11 です。なぜなら、 title カラムにも content カラムにもどちらにも Groonga が含まれているからです。 title カラム内の Groonga のスコアーは 10 です。 content カラム内の Groonga のスコアーは 1 です。 11 はこれらのスコアーの合計値です。

三つめのレコードのスコアーは 1 です。なぜなら、 content カラムにだけ Groonga が含まれているからです。 content カラムの Groonga のスコアーは 1 です。そのため、このレコードのスコアーは 1 になります。

  S プラグマ

S プラグマはクエリーの構文を指定します。

S プラグマの構文は次の通りです。:

    *S${SYNTAX}

利用可能な syntax は次の通りです。

•   S: スクリプト構文 <https://groonga.org/ja/docs/reference/grn_expr/script_syntax.html>

  *SS

*SS プラグマを使うと スクリプト構文 <https://groonga.org/ja/docs/reference/grn_expr/script_syntax.html> を使えます。スクリプト構文ではGroongaのすべての検索機能を使えます。

以下はスクリプト構文の使い方を示す例のためのスキーマとデータです。:

    CREATE TABLE comments (
      `content` text,
      FULLTEXT INDEX content_index (content)
    ) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
    INSERT INTO comments VALUES (
      'A student started to use Mroonga storage engine. It is very fast!'
    );
    INSERT INTO comments VALUES (
      'Another student also started to use Mroonga storage engine. It is very fast!'
    );

以下はスクリプト構文で 近傍検索 <https://groonga.org/ja/docs/reference/grn_expr/script_syntax.html#near-search-operator> を使う例です。:

    SELECT content,
           MATCH (content) AGAINST('*SS content *N "student fast"' IN BOOLEAN MODE) AS score
      FROM comments;
    -- +------------------------------------------------------------------------------+-------+
    -- | content                                                                      | score |
    -- +------------------------------------------------------------------------------+-------+
    -- | A student started to use Mroonga storage engine. It is very fast!            |     1 |
    -- | Another student also started to use Mroonga storage engine. It is very fast! |     0 |
    -- +------------------------------------------------------------------------------+-------+

近傍検索は指定した単語間（今回の場合は student と fast ）に10単語以下しかない場合のみマッチします。そのため、 student started ...（8単語）... very fast はマッチしますが、 student also started ...（8単語）... very fast はマッチしません。

他の上級者向け機能も使えます。

  Mroongaにおける検索スコア

  IN NATURAL LANGUAGE MODEにおける検索スコアの算出方法

IN NATURAL LANGUAGE MODEでの検索スコアはクエリと文書の類似度になります。スコアは以下の手順に従って算出されます。:

1.  クエリをトークンに分割する

2.  マッチしないトークンを除去する

3.  トークン毎の重みを計算する

4.  重みが大きい上位N個のトークンを取り出す

5.  上位N個のトークンについて、トークンが出現する文書に重みを足し、すべての重みを足したものがクエリと文書の類似度となる

    具体例を使って説明します。以下のテーブルとデータを用意します。:

        SET NAMES UTF8;
        CREATE TABLE diaries (
          id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
          content TEXT,
          FULLTEXT INDEX(content)
        ) ENGINE mroonga DEFAULT CHARSET UTF8;
        INSERT INTO diaries (content) VALUES("It'll be fine tomorrow as well.");
        INSERT INTO diaries (content) VALUES("It'll rain tomorrow.");
        INSERT INTO diaries (content) VALUES("It's fine today. It'll be fine tomorrow as well.");
        INSERT INTO diaries (content) VALUES("It's fine today. But it'll rain tomorrow.");

    このとき、以下のように「fine today」で類似文書検索したとします。検索の結果は以下となります。:

        mysql> SELECT *, MATCH (content) AGAINST ("fine today") AS score
            ->        FROM diaries
            ->        WHERE MATCH (content) AGAINST ("fine today")
            ->        ORDER BY MATCH (content) AGAINST ("fine today") DESC;
        +----+--------------------------------------------------+--------+
        | id | content                                          | score  |
        +----+--------------------------------------------------+--------+
        |  3 | It's fine today. It'll be fine tomorrow as well. | 131073 |
        |  4 | It's fine today. But it'll rain tomorrow.        | 131073 |
        +----+--------------------------------------------------+--------+
        2 rows in set (0.01 sec)

    このときのスコア"131073"の算出の具体的な挙動は以下となります。

  クエリをトークンに分割する

クエリ「fine today」をトークンに分割します。デフォルトトークナイザーは以下の二つのトークンにします。

•   fine

•   today

  マッチしないトークンを除去する

今回はすべてのトークンがどれかの文書に含まれているのでここでは取り除かれません。

•   fine: 文書id = 1,3,4

•   today: 文書id = 3,4

  トークン毎の重みを計算する

•   fine: 116508(= 1048576 / 9)

•   today: 131072(= 1048576 / 8)

    (= ...)が重みの計算式です。 "1048576"（= 2 ** 20）は文書全体に含まれるトークン数を表しています。 本当はテーブルなどから情報を取得してくるなどして正しい値を使いたいところですが、今のところ固定値になっています。

    "1048576 / 8"の分母の"8"はトークン「today」を含む文書数になります。

    "1048576 / 9"の分母の"9"はトークン「fine」を含む文書数になります。

    "8"と"9"はトークンを含む文書がいくつあるかの概算値です。本当は「today」を含む文書数は"2",「fine」を含む文書数は"3"ですが、概算値なのでずれています。

    概算値は以下のように確認できます。

        SELECT mroonga_command("select diaries-content --query '_key:fine OR _key:today' --output_columns _key, index --limit -1") AS groonga_response;

    The retrieval result of the above query is as follows:

        [[[2],[["_key","ShortText"],["index","diaries"]],["FINE",9],["TODAY",8]]]

  重みが大きい上位N個のトークンを取り出す

Nは以下の式で求めています。N = マッチしたトークン数 / 8 + 1

今回は「マッチしたトークン数」が2なので「2 / 8 + 1 = 1」で N = 1です。

マッチしたトークンを重み順に並び替えると以下の通りです。

•   today: 131072(= 1048576 / 8)

•   fine: 116508(= 1048576 / 9)

    このうち上位1件なのでtoday: 131072(= 1048576 / 8)だけが残ります。

  上位N個のトークンについて、トークンが出現する文書に重みを足す

•   today: 文書id = 3,4

    Finally document id 3,4 are hit, the similarity score between query and document(id=3) is 131072 + 1 = 131073 ("1" is the number of occurrence of token "today" in document).

    The similarity score between query and document(id=4) is the same as the score between query and document(id=3).

FAQ

MroongaのFAQを紹介します。

  「mmap Cannot allocate memory」エラーを回避するにはどうしたらよいですか？

  短い回答

vm.max_map_count Linuxカーネルパラメーターの値を増やしてください。

  長い回答

ログファイルに以下のようなmmapエラーが存在する場合があります。:

    2013-06-04 08:19:34.835218|A|4e86e700|mmap(4194304,551,432017408)=Cannot allocate memory <13036498944>

<13036498944> はこの場合mmapの合計サイズ(約12GB)です。

以下の観点を確認する必要があります。

•   十分なメモリの空きが存在するか?

•   マッピング最大数を超過していないか?

    十分な空きメモリがあるかを調べるために、vmstat コマンドを使うことができます。

    最大マッピング数を超過しているかどうかを確認するために、 vm.max_map_count の値を調べることができます。

    もしこの問題が vm.max_map_count の値を調整することで解決するなら、これが原因です。

    Groongaはメモリを256KBごとに確保するので、扱えるデータベースのサイズを以下の式で見積ることができます:

        (database size) = vm.max_map_count * (memory chunks)

    16GBを超えるデータベースを扱うには、少くとも65536を vm.max_map_count の値として設定しないといけません。

        database size (16GB) = vm.max_map_count (65536) * memory chunks (256KB)

    sudo sysctl -w vm.max_map_count=65536 で一時的に vm.max_map_count を調整することができます。

    その後、設定値を /etc/sysctl.conf もしくは /etc/sysctl.d/*.conf へと保存します。

コミュニティ

GroongaとMroongaの情報を共有する場所がいくつかあります。これらのコミュニティにぜひ参加してください。

  メーリングリスト

GroongaとMroongaに関する話題を扱うメーリングリストがあります。

英語で話題を扱う場合
    groonga-talk@lists.sourceforge.net <http://lists.sourceforge.net/mailman/listinfo/groonga-talk>

日本語で話題を扱う場合
    groonga-dev@lists.osdn.me <http://lists.osdn.me/mailman/listinfo/groonga-dev>

  チャットルーム

GroongaとMroongaに関する話題を扱うチャットルームがあります。

英語で話題を扱う場合
    Gitterのgroonga/enチャットルーム <https://gitter.im/groonga/en>

日本語で話題を扱う場合
    Gitterのgroonga/jaチャットルーム <https://gitter.im/groonga/ja>

  Twitter

@groonga <https://twitter.com/groonga/> はGroonga・Mroonga関連の情報をツイートします。

最新のGroonga・Mroonga情報をゲットするためにこのアカウントをフォローしてください！

  Facebook

FacebookのMroongaページ <http://www.facebook.com/mroonga> ではMroonga関連の情報をシェアしています。

Mroonga関連の最新情報を入手するためにこのページをいいね！してください！

HOW TO CONTRIBUTE TO MROONGA

We welcome your contributions to the Mroonga Project. There are many ways to contribute, such as using Mroonga, introduction to others, etc. For example, if you find a bug when using Mroonga, you are welcome to report the bug. Coding and documentation are also welcome for Mroonga and its related projects.

As a user:
    If you are interested in Mroonga, please read this document and try it.

As a spokesman:
    Please introduce Mroonga to your friends and colleagues.

As a developer: Bug report, development and documentation
    This section describes the details.

  見つけたバグを報告するには

バグを報告する方法はいくつかあります。

どのやりかたを使ってもらっても構いません。

  Issue trackerにバグを報告する

Mroongaプロジェクトでは、 GitHub issue tracker <https://github.com/mroonga/mroonga/issues> を使っています。

バグを報告するのは英語でも日本語でもどちらでも良いです。

  バグを報告する他の方法

Mroongaプロジェクトでは、Mroongaについて話す コミュニティ <> があります。バグの内容を記載したEメールを送ってください。

  再現可能なバグ報告をするためのデータをあつめるには

Mroongaがクラッシュしたり、SQLの結果が期待通りでない検索結果を返すことがあります。そういった問題を解決するためには再現可能なバグ報告が必要です。

再現可能なバグ報告には、次の情報をできるだけ提供してもらえると、問題を調査するのに役立ちます。
Name | Description
環境情報 | どのバージョンを使っているか、インストールしたパッケージの情報 rpm: rpm -qa > INSTALLED.txt deb: dpkg -l > INSTALLED.txt Windowsではどのzipパッケージを使っているかを教えてください。
問題の引き金となる実行中のクエリー | 実際に実行したクエリーを示します。
サンプルのスキーマとデータ | 問題を再現させる小さなサンプルスキーマとデータを提供してください。問題をすばやく解決するのにつながります。
MySQLのエラーログ | より低レベルのエラー情報を含んでいます。 例えば /var/log/mysqld.log にあります。( log-error 設定によりかわります)
groonga.log | より低レベルのエラー情報を含んでいます。 例えば /var/lib/mysql/groonga.log にあります。( mroonga_log_file の設定によりかわります)

上記の情報がバグの再現に十分でない場合、追加の情報が必要です。
Name | Description
MySQLのダンプ | 同じデータベースを再構築するのに必要です。 mysqldump -u USER -pPASSWORD --opt --flush-logs --single-transaction --master-data=2 --default-character-set=utf8 --hex-blob --databases DATABASE > dump.sql などとして作成します。
MySQLのbinlog | ダンプデータが問題の再現に十分ならば必要ありません。例えば、 /var/lib/mysql/mysql-bin.* にあります。 ( log-bin の設定によりかわります)
MySQLのデータディレクトリー(オフラインバックアップ) | ダンプデータやバイナリーログが残っていない場合、必要になることがあります。例えば、 /var/lib/mysql/ にあります。 ( datadir の設定によりかわります)

  How to contribute in documentation topics

We use Sphinx for documentation tool.

具体的にどんなことをやればいいのかを説明します。基本的にはドキュメントのソースファイルごとにpull requestを送ってもらうと進めやすいです。

対象となるファイルはdoc/sourceディレクトリ以下の拡張子が「.rst」となっているファイルです。

あまりGitHubでの作業に慣れていなくてもできるように、「最初にやること」と「作業ごとにやること」、「ファイルごとにやること」に分けて順に説明します。

•   The things you must do at first

•   The things you need to do every tasks

•   The things you need to do every files

  The things you must do at first

以下では、最初に一度だけ実施しておけば良いことを説明します。

  Git configuration

まずは、gitの設定をしましょう。すでにある程度gitを使っている場合には初期設定はすでに完了しているかも知れません。その場合には飛ばして構いません。

    $ git config --global user.name "Your Name"
    $ git config --global user.email "Email address"

上記はコミットログに使われます。公開しても差し支えないユーザ名もしくはメールアドレスを設定します。

  Fork on GitHub

First, create GitHub account. If your GitHub account is ready, login to GitHub and access following URL.

•   Fork the Mroonga repository <https://github.com/mroonga/mroonga/fork>

    Fork リポジトリ選択画面でご自分のリポジトリへとforkしてください。

  Initial configuration for working repository

Clone Mroonga repository to working directory. Don't forget to do "Git configuration".

    $ git clone git@github.com:(YOUR_GITHUB_ACCOUNT)/mroonga.git
    $ cd mroonga
    $ git remote add upstream git@github.com:mroonga/mroonga

  事前に必要な対応

Mroongaのドキュメントを生成する前に、まずMroongaをビルドする必要があります。Mroongaのビルド方法については、その他 <>を参照してください。

  必要なソフトウェア

Mroongaのドキュメントを生成するためには、以下が必要です。

•   Sphinx <https://www.sphinx-doc.org/>

•   gettext gem <https://github.com/ruby-gettext/gettext>

    ドキュメントツールとしてSphinxを使用し、ローカライズにはgettext gemを使用します。以下のコマンドでこれらのツールをインストールできます。

        $ pip install -r doc/requirements.txt
        $ (cd doc && bundle install)

  ドキュメント生成の初期設定

下記のコマンドで、Mroongaドキュメントを生成する設定をします。

    $ cmake \
        -S . \
        -B ../mroonga.doc \
        --preset=doc \
        -DMYSQL_SOURCE_DIR=(MySQL_SOURCE_DIRECTORY) \
        -DMYSQL_BUILD_DIR=(MySQL_BUILD_DIRECTORY) \
        -DMYSQL_CONFIG=(MySQL_CONFIG)

次のステップは、"ドキュメント編集・更新時に毎回必要な作業"の説明をします。

  The things you need to do every tasks

以下では作業ごとにやることを説明します。

  Follow the upstream

Mroonga本家の最新状態に追従して、作業がかぶらないようにします。

    $ git fetch --all
    $ git checkout main
    $ git rebase upstream/main

最新の状態に追従できたら、「ファイルごとにやること」へと進みます。

  The things you need to do every files

以下では、例えば Mroongaの特徴 <> を更新する場合で説明します。作業対象となるファイルは、リポジトリのdoc/source/ディレクトリ以下にあり拡張子が.rstなファイルです。今回は、doc/source/characteristic.rstを変更する例で説明します。

  Create working branch

Create a working branch. Use meaningful branch name.

    $ git checkout -b use-capitalized-notation-characteristic

  Editing text

Fix typos, styles or write a new document for Mroonga.

  生成されたドキュメントを確認

下記のコマンドで、変更内容を反映したHTMLを生成します。

    $ cmake --build ../mroonga.doc

変更が反映されたHTML形式のドキュメントをWebブラウザで確認します。

    $ open ../mroonga.doc/doc/en/html/characteristic.html

  Commit

HTMLに問題がないことを確認できたら、コミットします。

    $ cd ${cloneしたディレクトリーのトップディレクトリー}
    $ git add doc/source/characteristic.rst
    $ git commit

コミットするときのメッセージについては、例えば以下のようにします。

    doc: use "Mroonga" notation

  Push and pull request

Publish your changes to your own GitHub repository.

    $ git push -u origin use-capitalized-notation-characteristic

Note that use-capitalized-notation-characteristic is already created branch in advance.

ブラウザで https://github.com/(GitHubのアカウント)/mroonga を開くと「 @use-capitalized-notation-characteristic@ 」ブランチをpull requestする！みたいなUIができているので、そこのボタンを押してpull requestしてください。入力フォームがでてきますが、コミットしたときメッセージで十分なのでそのままpull requestしてOKです！

これで、ひととおりの作業は完了しました。

開発者向け情報

  デバッグ方法

  デバッグ用ビルド方法

デバッグ用にビルドすることにより、GDB上でのシンボル解決など開発時に得られる情報が多くなります。そのため、開発時はデバッグ用にMySQLとMroongaをビルドします。

注釈: 片方だけデバッグ用ビルドにすると構造体のサイズなどが異なってしまうため、Mroongaがロードできなかったり、実行時にassertに引っかかったりしてうまく動作しません。

  MySQLのデバッグ用ビルド方法

MySQL :: 2.9.4 標準ソース配布を使用して MySQL をインストールする <https://dev.mysql.com/doc/refman/8.4/ja/installing-source-distribution.html>にある通り、CMakeのオプションに-DWITH_DEBUG=ONオプションを渡すことでデバッグ用にビルドすることができます。

ダウンロードからビルドまでの流れは以下の通りです。

    $ mkdir -p ~/work/
    $ cd ~/work/
    $ wget https://cdn.mysql.com/Downloads/MySQL-8.4/mysql-8.4.2.tar.gz
    $ tar xf mysql-8.4.2.tar.gz
    $ cmake \
        -Smysql-8.4.2 \
        -Bmysql-8.4.2.build \
        -GNinja \
        -DCMAKE_BUILD_TYPE=Debug \
        -DCMAKE_INSTALL_PREFIX=/tmp/local \
        -DWITH_DEBUG=ON
    $ cmake --build mysql-8.4.2.build

  MariaDBのデバッグ用ビルド方法

MySQLの代わりにMariaDBを使いたい場合でも、-DWITH_DEBUG=ONを使えます。

MariaDBをビルドする前にstorage/mroonga/（MariaDBにバンドルされているMroonga）を削除しなければいけないことに注意してください。

ダウンロードからビルドまでの流れは以下の通りです。

    $ mkdir -p ~/work/
    $ cd ~/work/
    $ release_id=$(curl -s https://downloads.mariadb.org/rest-api/mariadb/ \
        | jq -r '.major_releases[] | select(.release_support_type == "Long Term Support" and .release_status == "Stable") | .release_id' \
        | head -n1)
    $ version=$(curl -s https://downloads.mariadb.org/rest-api/mariadb/$release_id \
        | jq -r '.releases[].release_id' \
        | head -n1)
    $ wget https://downloads.mariadb.org/rest-api/mariadb/$version/mariadb-$version.tar.gz
    $ tar xf mariadb-$version.tar.gz
    $ rm -rf mariadb-$version/storage/mroonga
    $ cmake \
        -Smariadb-$version \
        -Bmariadb-$version.build \
        -GNinja \
        -DCMAKE_BUILD_TYPE=Debug \
        -DCMAKE_INSTALL_PREFIX=/tmp/local \
        -DWITH_DEBUG=ON
    $ cmake --build mariadb-$version.build

  Mroongaのデバッグ用ビルド方法

MroongaはCMakeのオプションに--preset=debugを渡すことでデバッグ用にビルドすることができます。

注釈: Mroongaをビルドするには、必要なツールやライブラリーを事前にインストールする必要があります。

依存関係の詳細についてはその他 <>を参照してください。

リポジトリのcloneからビルドまでの流れは以下の通りです。

    $ cd ~/work/
    $ git clone git@github.com:mroonga/mroonga.git
    $ cmake \
        -Smroonga \
        -Bmroonga.mysql-8.4 \
        --preset=debug \
        -DCMAKE_INSTALL_PREFIX=/tmp/local \
        -DMYSQL_BUILD_DIR=$HOME/work/mysql-8.4.2.build \
        -DMYSQL_CONFIG=$HOME/work/mysql-8.4.2.build/scripts/mysql_config \
        -DMYSQL_SOURCE_DIR=$HOME/work/mysql-8.4.2
    $ cmake --build mroonga.mysql-8.4

無事にビルドができたら以下のようにテストを実行してください。すべてのテストが[pass]になればデバッグ用ビルドは成功しています。

    $ cd mroonga.mysql-8.4
    $ ../mroonga/test/run-sql-test.sh

  run-sql-test.shを使いこなす

run-sql-test.shはデバッグの友。ここでは、その便利な使い方の一例をご紹介します。

  指定したテストを実行する

何もオプションを渡さずにrun-sql-test.shを実行するとmysql-test/mroonga以下にある全てのテスト（*.test）が実行されてしまいます。

特定のテストだけを実行したい、という場合は次のようにしてテストを指定します。

    $ ../mroonga/test/run-sql-test.sh ../mroonga/mysql-test/mroonga/storage/t/truncate.test

  トレースを見る

次のようにして--debugオプションをつけてテストを実行すると、関数の呼び出しなどが記録されます。

    $ ../mroonga/test/run-sql-test.sh --debug ../mroonga/mysql-test/mroonga/storage/t/truncate.test

この呼び出しは${MySQLのビルドディレクトリ}/mysql-test/var/log/mysqld.1.traceに格納されます。

新しくメソッドを作成した場合はMRN_DBUG_ENTER_METHOD()/DBUG_RETURN()をメソッドの先頭/末尾に配置し、関数の呼び出しを記録するようにするとよいでしょう。

  GDB を立ち上げる

--manual-gdbオプションを指定することで、テストを実行する際にGDBを用いてデバッグをできます。

    $ ../mroonga/test/run-sql-test.sh --manual-gdb ../mroonga/mysql-test/mroonga/storage/t/truncate.test

このために別のターミナルでgdbを実行する必要があります。gdbを実行するためのコマンドラインはrun-sql-test.shが表示します。

  Release procedure

  必要なもの

以下はリリース手順に必要なものです。

•   Debian GNU/Linux (sid)

•   zshをユーザーシェルとして使います

    以下の作業ディレクトリを使います。

•   MROONGA_SOURCE_DIR=$HOME/work/mroonga

•   MROONGA_BUILD_DIR=$HOME/work/build-dir/mroonga

•   MROONGA_ORG_DIR=$HOME/work/mroonga.org

•   MARIADB_SOURCE_DIR=$HOME/work/mariadb

•   MARIADB_BUILD_DIR=$HOME/work/build-dir/mariadb

•   GROONGA_SOURCE_DIR=$HOME/work/groonga

•   GROONGA_BUILD_DIR=$HOME/work/build-dir/groonga

•   INSTALL_DIR=/tmp/local

  ビルド環境をセットアップする

以下のパッケージをインストールします:

    $ sudo apt-get install -V ruby mecab libmecab-dev gnupg2 dh-autoreconf bison

  変更点を記述する

前回のリリース以降の最近の変更点を doc/source/news/xx.md へまとめます。

含めるべきもの

•   ユーザーに影響のある変更点

•   互換性を壊すような変更点

    含めるべきでないもの

•   ユーザーに影響のない内部的な変更やリファクタリング

    以下のコマンドを実行して、ニュース用のHTMLを作成する:

        $ cmake -S ${MARIADB_SOURCE_DIR} -B ${MARIADB_BUILD_DIR} -GNinja -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DPLUGIN_CASSANDRA=NO
        $ cmake --build ${MARIADB_BUILD_DIR}
        $ cmake --install ${MARIADB_BUILD_DIR}
        $ cmake -S ${GROONGA_SOURCE_DIRECTORY} -B ${GROONGA_BUILD_DIR} --preset=release-default --fresh -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}"
        $ cmake --build ${GROONGA_BUILD_DIR}
        $ cmake --install ${GROONGA_BUILD_DIR}
        $ PKG_CONFIG_PATH=${INSTALL_DIR}/lib/pkgconfig cmake -S ${MROONGA_SOURCE_DIRECTORY} -B ${MROONGA_BUILD_DIR} --fresh --preset=doc -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" -DMYSQL_SOURCE_DIR=~${MARIADB_SOURCE_DIR} -DMYSQL_BUILD_DIR=${MARIADB_BUILD_DIR} -DMYSQL_CONFIG=${INSTALL_DIR}/bin/mariadb_config
        $ cmake --build ${MROONGA_BUILD_DIR}

  release タスクを実行する

rake release を実行:

    $ rake release

  release タスク について

release タスクは次の3つのタスクを実行します。

1.  release:version:update

•   RPMパッケージのspecファイルに新しいバージョンのチェンジログを追記したりなどします

•   環境変数 NEW_RELEASE_DATE でリリース日を指定することができます

2.  release:tag

•   リリース用のタグをプッシュします

•   これにより自動リリースが動き出します

3.  dev:version:bump

•   次のリリースに向けてバージョンをあげます

•   環境変数 NEW_VERSION でバージョンを指定することができます

  CIを確認する

以下のCIがグリーンかどうかを確認します。

•   GitHub Actions <https://github.com/mroonga/mroonga/actions>

    CIで自動リリースを行っているので、失敗していたらリトライします。（何度リトライしても問題ないように設定されています。）

  Dockerイメージを更新

次のコマンドを実行:

    $ git clone git@github.com:mroonga/docker.git mroonga-docker
    $ cd mroonga-docker
    $ ./update.sh
    $ git push
    $ git push --tags

  ドキュメントを更新

次のコマンドを実行:

    $ export GROONGA_ORG_REPOSITORY=${HOME}/work/groonga.org
    $ git clone git@github.com:groonga/groonga.org.git ${GROONGA_ORG_REPOSITORY}
    $ rake -C ${MROONGA_ORG_DIR} release

  Announce release for X(Twitter)

Tweetリンクをクリックすると、最新のリリースについてツイートできます。タイトルやブログエントリのURLがツイートに含まれます。

ツイートは日本語と英語のブログエントリから行います。ツイートは groonga アカウントでログインした状態で行ってください。

  リリースをFacebookで告知

FacebookのMroongaグループからリリースを告知します。

<https://www.facebook.com/mroonga/> TODO: Translate.

  コーディングスタイル

一般的に1つのコードベースに複数のスタイルがまざっているとソースコードが読みづらくなります。たとえ、それぞれのスタイル単独では読みやすいスタイルあっても、まざると読みづらくなります。そのため、Mroongaプロジェクトでもスタイルを統一して、読みやすいソースコードになるようにします。

読みやすいソースコードにする理由は以下の通りです。

•   機能を拡張するときのコストを下げる。

•   問題を修正するときのコストを下げる。

    どちらの場合も周辺のソースコードを読んで、それをベースにコードを追加・変更します。このとき、ソースコードが読みやすい状態だと周辺のソースコードの把握をスムーズに行うことができ、スムーズにその後の作業に移れます。

    TODO: 読みやすさの他にデバッグのしやすさ（gdbでの追いやすさ）も考慮に入れたほうがよさそうだがどうしよう。

  言語

基本的にすべてC++で記述します。よほどのことがない限りCは使いません。

よい例:

    ha_mroonga.cpp

悪い例（C言語を使っている）:

    mrn_sys.c

  ファイル名

ソースコードのファイル名は全て小文字にします。また、単語ごとに"_"で区切ります。

よい例:

    ha_mroonga.cpp

悪い例（大文字を使っている）:

    HA_MROONGA.cpp

悪い例（単語を"_"で区切らずにくっつけている）:

    hamroonga.cpp

悪い例（単語を"-"で区切っている）:

    ha-mroonga.cpp

ソースコードの拡張子 .cpp にします。

よい例:

    ha_mroonga.cpp

悪い例（ .cc を使っている）:

    ha_mroonga.cc

ヘッダーファイルの拡張子は .hpp にします。

よい例:

    ha_mroonga.hpp

悪い例（ .h を使っている）: ha_mroonga.h

  名前空間

ヘッダーファイルでは using namespace を使わない。ソースコードでは using namespace std であれば使ってもよい。他の名前空間は使ってはいけない。

よい例:

    ha_mroonga.cpp:
      using namespace std;

悪い例（ヘッダーファイル内で using namespace を使っている）:

    ha_mroonga.hpp:
      using namespace std;

悪い例（ std 以外の名前空間に対して using namespace を使っている）:

    ha_mroonga.cpp:
      using namespace zmq;

  include ガード

2重 include を防ぐためのマクロは、ヘッダーファイルの名前をすべて大文字にし、単語の区切りをアンダースコアにしたものにし、最後にアンダースコアをつけて HEADER_FILE_NAME_HPP_ という名前にする。

よい例:

    mrn_db_path.hpp:
      #ifndef MRN_DB_PATH_HPP_
      #define MRN_DB_PATH_HPP_
      ...
      #endif // MRN_DB_PATH_HPP_

悪い例（小文字になっている）:

    mrn_db_path.hpp:
      #ifndef mrn_db_path_hpp_
      #define mrn_db_path_hpp_
      ...
      #endif // mrn_db_path_hpp_

悪い例（アンダースコアが最後ではなく先頭についている）:

    mrn_db_path.hpp:
      #ifndef _MRN_DB_PATH_HPP
      #define _MRN_DB_PATH_HPP
      ...
      #endif // _MRN_DB_PATH_HPP

  代入

= の前後に1つスペースを入れる。

よい例:

    int i = 0;

悪い例（スペースが入っていない）:

    for (i=0; i<10; ++i) {...}

悪い例（2つスペースが入っている）:

    int i  = 0;

  文字列

文字列はポインタと長さで表現する。 \0 での終端を仮定しない。

よい例（本当はもっとすっきりした例がよいけど。。。）:

    char *raw_data = "table_name column_name column_value"
    char *column_name;
    size_t column_name_size;
    column_name = raw_data + strlen("table_name ");
    column_name_size = strlen("column_name");

悪い例（無理やり \0 終端にしている）:

    char *raw_data = "table_name column_name column_value"
    char *column_name;
    column_name = strndup(raw_data + strlen("table_name "), strlen("column_name"));

ただし、ファイル名など \0 が前提であるものに関しては \0 終端を仮定してよい。

よい例:

    char *database_path = "db/test.mrn";

悪い例（ \0 終端を仮定せず、長さも管理している）:

    char *database_path = "db/test.mrn";
    size_t database_path_size = strlen("db/test.mrn");

std::string は内部でメモリ確保などの処理が発生するので多用しない。

よい例:

    char database_path[MAX_PATH];

悪い例（最大サイズがわかっているのに std::string を使っている）:

    std::string database_path;

  バッファ

TODO: ちゃんと考える。

何度も繰り返し使う領域（バッファ）が必要な場合は GRN_BULK を使う。例えば、カラムの値を取得する領域などである。

  命名規則

  クラス名

クラスの名前は UpperCamelCase とする。

よい例:

    class MyClass
    {
    }

悪い例（ snail_case である）:

    class my_class
    {
    }

ただし、 ha_mroonga などMySQLとのインターフェイスとなるクラスでかつ他の類似のモジュールに命名規則がある場合はそれに従う。

よい例:

    class ha_mroonga: public handler
    {
    }

悪い例（ UpperCamelCase になっている）:

    class HaMroonga: public handler
    {
    }

  メンバー変数名

メンバー変数名は snail_case とし、末尾にアンダースコア（ _ ）を付ける。

よい例:

    class MyClass
    {
      char *my_name_;
    }

悪い例（ UpperCamelCase である）:

    class MyClass
    {
      char *MyName_;
    }

悪い例（末尾にアンダースコアがない）:

    class MyClass
    {
      char *my_name;
    }

  読み込み用アクセサ名

メンバー変数の値を読み込むメソッドの名前はメンバー変数名の末尾のアンダースコアを除いたものにする。

よい例:

    class MyClass
    {
      char *my_name_;
      const char *my_name() {return my_name_;};
    }

悪い例（末尾にアンダースコアが残っている）:

    class MyClass
    {
      char *my_name_;
      const char *my_name_() {return my_name_;};
    }

悪い例（先頭に get_ を付けている）:

    class MyClass
    {
      char *my_name_;
      const char *_my_name() {return my_name_;};
    }

  書き込み用アクセサ名

メンバー変数の値を設定するメソッドの名前は、メンバー変数名の末尾のアンダースコアを除き、先頭に set_ を加えたものにする。

よい例:

    class MyClass
    {
      unsigned int age_;
      void set_age(unsigned int age)
      {
        age_ = age;
      };
    }

悪い例（末尾にアンダースコアが残っている）:

    class MyClass
    {
      unsigned int age_;
      void set_age_(unsigned int age)
      {
        age_ = age;
      };
    }

悪い例（先頭に set_ ではなく update_ を付けている）:

    class MyClass
    {
      unsigned int age_;
      void update_age(unsigned int age)
      {
        age_ = age;
      };
    }

  コピーコンストラクター

基本的にコピーコンストラクターの使用を禁止する。よほどのことがなければ使用しないこと。

コピーコンストラクターは暗黙的に無駄なコピーが発生する可能性があるためパフォーマンス上の問題がある。コピーではなくポインターやリファレンスを用いること。

また、デフォルトのコピーコンストラクター実装はメンバー変数のポインターの値をそのままコピーするため、デコンストラクターで二重に解放してしまう危険性がある。そのため、明示的にコピーコンストラクターを定義しない場合は無効にする。

よい例:

    class MyClass
    {
    private:
      MyClass(const MyClass &);
    }

悪い例（コピーコンストラクターを禁止していない）:

    class MyClass
    {
    }

悪い例（カスタムコピーコンストラクターを使っている）:

    class MyClass
    {
      unsigned int age_;
      MyClass(const MyClass &object)
      {
        age_ = object.age_;
      }
    }

  クラスの代入

基本的に定義したクラスの代入を禁止する。よほどのことがなければ使用しないこと。

代入演算子は暗黙的に無駄なコピーが発生する可能性があるためパフォーマンス上の問題がある。コピーではなくポインターやリファレンスを用いること。

また、デフォルトの代入演算子の実装はメンバー変数のポインターの値をそのままコピーするため、デコンストラクターで二重に解放してしまう危険性がある。そのため、明示的に代入演算子を定義しない場合は無効にする。

よい例:

    class MyClass
    {
    private:
      MyClass &operator=(const MyClass &);
    }

悪い例（代入を禁止していない）:

    class MyClass
    {
    }

悪い例（代入を使っている）:

    class MyClass
    {
      unsigned int age_;
      MyClass &operator=(const MyClass &object)
      {
        age_ = object.age_;
        return *this;
      }
    }

  引数

  voidを省略

引数がない場合は void を省略する。

よい例:

    class MyClass
    {
      unsigned int age_;
      unsigned int age()
      {
         return age_;
      };
    }

悪い例（ void を省略していない）:

    class MyClass
    {
      unsigned int age_;
      unsigned int age(void)
      {
         return age_;
      };
    }

  入力用引数にはconstを付ける

入力のみに用いる引数には const を付ける。これは、入力のみに用いる引数である事を明示するためと、間違って引数を変更してしまわないためである。

よい例:

    class Table
    {
      void insert(unsigned int id, const char *column_name, const char *value)
      {
         Record *record = records[i];
         Column *column = columns[column_name];
         column.set_value(value);
      }
    }

悪い例（入力のみに用いているのに const が付いていない）:

    class Table
    {
      void insert(unsigned int id, char *column_name, char *value)
      {
         Record *record = records[i];
         Column *column = columns[column_name];
         column.set_value(value);
      }
    }

  定数

フラグやサイズなどを示す定数には const オブジェクトを用いる。これはデバッガー上でプログラムを走らせているときに名前で値を参照できるようにするためである。

よい例:

    const char *MRN_LOG_FILE_PATH = "groonga.log";

悪い例（ #define を用いている）:

    #define MRN_LOG_FILE_PATH "groonga.log"

  真偽値

  bool型を用いる

真偽値には bool 型を用いる。

よい例:

    bool is_searching;

悪い例（ int 型を用いている）:

    int is_searching;

  真偽値のリテラルには true または false を用いる

真偽値の値として true と false はより完結で説明的だからである。

よい例:

    bool is_searching = true;

悪い例（ 0 以外の値を真の値として用いている）:

    bool is_searching = 1;

  条件式

  真偽値は比較しない

真偽値の値は boolean_value == true などとせず、 boolean_value として条件式に使用する。すでに真偽値の値を真偽値のリテラルと比較することは重複したコードだからである。

よい例:

    boolean is_searching = true;
    if (!is_searching) { ... }

悪い例（真偽値のリテラルと比較している）:

    boolean is_searching = true;
    if (is_searching == false) { ... }

  NULL と比較しない

NULL かどうかを条件式に使う場合は value == NULL ではなく !value というように書く。多くの言語で NULL に相当する値（たとえばLispの nil ）は偽を表すため、明示的に NULL と比較しなくても意図は伝わるからである。

よい例:

    char *name = NULL;
    if (!name) { ... }

悪い例（ NULL と比較している）:

    char *name = NULL;
    if (name == NULL) { ... }

  数値は比較する

CやC++では 0 は偽、 0 以外は真の値となるが、条件式に数値を使う場合は strcmp(...) == 0 などというように明示的に比較する。

C++では真偽値に bool を使うためこのような状況は発生しないが、C言語由来のAPIでは int で真偽値を表現している場合が多い。しかし、 int だけでは真偽値として使っているか本当に数値として使っているかがわかりにくいため、 int のときはすべて数値として扱う。

よい例:

    if (memcmp(value1, value2, value_size) == 0) {
      printf("same value!\n");
    }

悪い例（ 0 を偽の値として扱っている）:

    if (!memcmp(value1, value2, value_size)) {
      printf("same value!\n");
    }

  初期化

  メンバー変数の初期化には初期化リストを用いる

無駄な処理を省くためにコンストラクターでのメンバー変数の初期化には初期化リストを用いる。初期化リストを用いないとコンストラクターの処理とコピーコンストラクター・代入処理が行われたりなど非効率である。（後述）

よい例:

    class Table
    {
      Table(const char *name);
      std::string name_;
    }
    Table::Table(const char *name) :
      name_(name)
    {
    }

悪い例（ std::string(name) のところでコンストラクターが動き、 name_ = ... のところで代入演算子が動いて2回初期化している）:

    class Table
    {
      Table(const char *name);
      std::string name_;
    }
    Table::Table(const char *name)
    {
      name_ = std::string(name);
    }

  変数宣言と同時に初期化する

変数を宣言したときに同時に初期化する。宣言時に初期化せずに代入して初期化すると、無駄な処理が発生する可能性があるため非効率である。（後述）

よい例:

    std::string name("users");

悪い例（ std::string() のところでコンストラクターが動き、 name = ... のところで代入演算子が動いて2回初期化している）:

    std::string name;
    name = std::string("users");

  インクリメント・デクリメント

  前置形式を用いる

後置形式ではオブジェクトのコピーをしなければいけないため非効率である。そのため、できるだけ前置形式を用いる。

よい例（ int だと効率は変わらないので本当はあんまりよい例ではない）:

    for (int i = 0; i < 10; ++i) {
    }

悪い例（後置形式を用いている）:

    for (int i = 0; i < 10; ++i) {
    }

  キャスト

  C++のスタイルを用いる

Cスタイルのキャストはなんでもキャストできてしまうため、意図しないキャストにも気付かない可能性がある。例えば、単に const を外したいだけなのに、間違って違う型に変換していても気付けない。C++のキャストでは const を外したいときは const_cast を使用し、型を変換するときは static_cast を指定する。こうすれば、 static_cast で間違って const を外してしまっている場合も気付ける。 reinterpret_cast はどうしても必要なときのみ注意して使う。

よい例（ const_cast を使っている）:

    uchar *to_key;
    const ucahr *from_key;
    KEY *key_info;
    uint key_length;
    key_copy(to_key, const_cast<uchar *>from_key, key_info, key_length);

よい例（ static_cast を使っている）:

    int n_hits = 1;
    int n_documents = 10;
    float hit_ratio = (float)(n_hits) / n_documents;

よい例（ static_cast では無理なので reinterpret_cast を使っている）:

    THD *thread = current_thd;
    my_hash_delete(&mrn_allocated_thds, reinterpret_cast<uchar *>(thread));

悪い例（Cスタイルのキャストを使っている）:

    int n_hits = 1;
    int n_documents = 10;
    float hit_ratio = (float)(n_hits) / n_documents;

悪い例（ static_cast で十分なのに reinterpret_cast を使っている）:

    void *value = get_value(key);
    char *name;
    name = reinterpret_cast<char *>(value);

  変数宣言

  ポインタ型を示す * とリファレンス型を示す & は変数名に寄せる

Cと同様にポインタ型を示す * は型名ではなく変数名に寄せる。これは、以下のように複数の変数を一度に宣言したときに一貫性がなくなるためである。2つめ以降の変数は近くに型名がないため * を寄せる場所がない。

例:

    char* key, *value;

同様に、リファレンス型を示す & も変数名に寄せる。

なお、 * や & と型名の間にはスペースを入れない。

よい例:

    char *key;

よい例:

    bool is_exist(const std::string &file_name);

悪い例（型名に寄せている）:

    char* key;

  その他

•   ここに書いていないものについては特にスタイルを定めないが、 プロジェクト内で常に一貫性のあるスタイルを使用すること。 同じような事をするときは同じような書き方にすること。 複数の書き方で同じようなことを実現している場合は1つの方法に合わせること。

    以下、具体例が必要。

•   ビルド時にできることを実行時に延ばさない(静的チェックを活用)

•   なるべく局所的に変数を定義し、同時に初期化する

•   長い関数や深いブロックのネストを避ける

•   2つに分けた方がよさそう。あと目安があるといいかも。 100行以上は長いよねーとか3段以上はデンジャーとか。

•   必要以上にオブジェクトを複製しない

•   暗黙の型変換はなるべく避ける

•   assertを積極的に使う

  メモ

•   動的テンプレートを使わない。（要追加情報。implicit template instantiationのことであれば、これはふつうに使わ れているものなので特に禁止しないんでいいんじゃない説？）

•   typeidを使わない。

•   例外はMySQLで問題がないようであればOK。Mroongaから外の世 界（MySQLの世界）にはださないようにする。

  開発手法について

Mroonga開発プロジェクトではBTSの1つであるRedmineを用いたチケット駆動開発を実施しています。

Redmineは以下のサイトで運用されています。

<http://redmine.groonga.org/projects/mroonga>

開発の作業はチケット単位で行っています。

開発者の方は上記サイトへのアカウント登録をお願いします。

  ロードマップについて

ロードマップに基づいた開発を行っています。ロードマップは以下のページから確認できます。

<http://redmine.groonga.org/projects/mroonga/roadmap>

ロードマップはオフラインあるいはオンラインでの開発会議で検討を行った上で決定されます。

ロードマップは各バージョンごとに追加する機能の一覧として構成されています。

  ソースコード管理について

GitHubを使用したgitによるソースコード管理を行っています。

<http://github.com/mroonga/mroonga>

上記レポジトリに対してread/writeでcloneを作成し、commitおよびpushして下さい。

アカウントを作成していない開発者の方はgithub.comへの登録をお願いします。

  開発環境

開発は以下の流れで行いたいと考えています。

1.  チケットの新規作成と内容の記述

2.  開発会議での検討(ロードマップへの反映)

3.  チケットの割り当て(担当者作業開始)

4.  機能実装あるいはバグの修正作業、必要に応じてレポジトリへのpush

5.  テストコードの追加と実行、レポジトリへのpush

6.  実装/テスト内容に対するレビュー(必要に応じて4へ戻る)

7.  ドキュメントの追加/変更、 レポジトリへのpush

8.  チケットの完了

    機能追加や仕様変更などについても積極的にアイデアを募集します。まずはチケットを新規作成して内容を記述して下さい。

    テストコードの追加と実行については後述しますのでそちらを参照して下さい。

    基本的にチケットを担当されている方が設計、実装、テスト、ドキュメントまで一通りお願いしたいと考えています。

    他の開発者にレビューを依頼し(特に機能追加の場合)、無事パスしたら最後にドキュメントを追加/変更してチケット完了となります。

    ドキュメントの追加/変更方法についても詳しくは後述します。

  開発環境

現在、以下のような開発環境を想定しています。

•   Linux x86_64

•   glibc

•   MySQL <http://www.mysql.com/>

•   Groonga <https://groonga.org/>

•   Cutter <http://cutter.sourceforge.net/> (C/C++単体テスト用)

•   Sphinx <https://www.sphinx-doc.org/ja/master/> (ドキュメント用)

  ソースディレクトリ解説

今のところソースファイルの数はごくわずかです。なるべくシンプルな状態を維持したいと考えています。

ha_mroonga.hpp
    Mroongaのヘッダファイル

ha_mroonga.cpp
    Mroongaの実装コード

mrnsys.hpp
    ユーティリティ関数のヘッダファイル

mrnsys.cpp
    ユーティリティ関数の実装コード

mysql-test/
    SQLによるテストコード用ディレクトリ

    SQLによるテストコード用ディレクトリSQLテストスクリプト（現在実行可能なSQL文の定義も兼ねる）

    SQLテスト想定実行結果（SQL動作仕様定義も兼ねる）

test/unit/
    C/C++関数単体でのテストコード用ディレクトリ

doc/source/
    Sphinx形式の英語ドキュメント一式

    Mroongaはまだ開発の立ち上げ段階であるため、SQL実行に関する仕様のドキュメント化は当面行いません。

    その代わりとしてSQLテストスクリプトとその想定実行結果を機能一覧/仕様定義として見なしています。

  テストコードの追加と実行について

Mroongaではプログラムの品質管理のため、2種類の回帰テストを用いています。

SQL tests
    SQL実行により動作確認を行えるような機能追加/バグ修正に関しては必ずSQLテストを追加して下さい。高速化機能などは一見するとSQLによる動作確認ができないように見える場合もありますが、ステータス変数やinformation_schemaプラグインなどを使用することで上手くテストできるものもあります。

C/C++単体テスト
    Cutterを使用した関数レベルでの回帰テストです。ユーティリティ関数などSQL実行結果による動作の差異を確認できないような実装を追加した場合にはこちらにテストを追加して下さい。

    ソースコードレポジトリへのpushを行う前に必ず回帰テストを実行し、デグレードが発生していないことを確認して下さい。

    上記の回帰テストは"make check"で双方とも呼び出されます。

    SQLテストはMySQLの回帰テストである"mysql-test"に対する"sub test suite"として実装しています。テストケースの追加や想定結果ファイルの改変方法などの詳細情報は以下のMySQLのドキュメントを参照して下さい。

    <http://dev.mysql.com/doc/mysqltest/2.0/en/index.html>

    C/C++単体テストの書き方についてはCutterのドキュメントを参照して下さい。

    <http://cutter.sourceforge.net/index.html.ja>

  ドキュメントの追加と変更について

ドキュメントの追加と変更については、 How to contribute in documentation topics <> を参照して下さい。

•   索引 <>

•   モジュール索引 <>

•   検索ページ <>

Author
Mroonga Project

Copyright
2009-2026, Mroonga Project