4.4. Wrapper mode

Here we explain how to use wrapper mode of Mroonga

4.4.1. How to use wrapper mode

In wrapper mode, Mroonga works in wrapping an existing storage engine. To specify the wrapped storage engine, we use SQL comment like COMMENT = 'engine "InnoDB"' for now.

Note

For now, a primary key is mandatory in wrapper mode. That is not the case with storage mode.

Note

Wrapper mode supports the followings, that are not supported in storage mode for now.

  • null value
  • transaction (if storage engine supports. Note that rollback causes mismatch of indexes, it may affects search results, so recreate index of Mroonga in such a case.)

4.4.3. How to get search score

We often want to display more relevant results first in full text search. We use search score in such case.

We can get search score by MySQL's standard way [1], i.e. we use MATCH...AGAINST in one of columns in SELECT or ORDER BY.

Let's try.

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") FROM diaries WHERE MATCH (content) AGAINST ("fine") ORDER BY MATCH (content) AGAINST ("fine") DESC;
+----+--------------------------------------------------------------+------------------------------------+
| id | content                                                      | MATCH (content) AGAINST ("fine") |
+----+--------------------------------------------------------------+------------------------------------+
|  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)

The result having the search word fine more, i.e. id = 3 message having the higher search score, is displayed first. And you also get search score by using MATCH AGAINST in SELECT phrase.

You can use AS to change the attribute name.

mysql> SELECT *, MATCH (content) AGAINST ("fine") AS score FROM diaries WHERE MATCH (content) AGAINST ("fine") ORDER BY MATCH (content) AGAINST ("fine") 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)

4.4.5. How to specify the normalizer

Mroonga uses normalizer corresponding to the encoding of document. It is used when tokenizing text and storing table key.

It is used NormalizerMySQLGeneralCI normalizer when the encoding is utf8_general_ci or utf8mb4_general_ci.

It is used NormalizerMySQLUnicodeCI normalizer when the encoding is utf8_unicode_ci or utf8mb4_unicode_ci.

It isn't used normalizer when the encoding is utf8_bin.

Here is an example that uses NormalizerMySQLUnicodeCI normalizer by specifying utf8_unicode_ci.:

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 has the following syntax to specify Groonga's normalizer:

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

See Groonga's document document about Groonga's normalizer.

Here is an example that uses NormalizerAuto normalizer:

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)

4.4.6. How to get snippet (Keyword in context)

Mroonga provides functionality to get keyword in context. It is implemented as mroonga_snippet() UDF.

4.4.7. Logging

Mroonga outputs the logs by default.

Log files are located in MySQL's data directory with the filename groonga.log.

Here is the example of the 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)

The default log level is NOTICE, i.e. we have important information only and we don't have debug information etc.).

You can get the log level by mroonga_log_level system variable, that is a global variable. You can also modify it dynamically by using SET phrase.

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)

Available log levels are the followings.

  • NONE
  • EMERG
  • ALERT
  • CRIT
  • ERROR
  • WARNING
  • NOTICE
  • INFO
  • DEBUG
  • DUMP

See mroonga_log_level about details.

You can reopen the log file by FLUSH LOGS. If you want to rotate the log file without stopping MySQL server, you can do in the following procedure.

  1. change the file name of groonga.log (by using OS's mv command etc.).
  2. invoke "FLUSH LOGS" in MySQL server (by mysql command or mysqladmin command).

4.4.8. Next step

Now, you can use Mroonga as wrapper mode! If you want Mroonga to be faster, see also Optimizations.

Footnotes

[1]MySQL 5.1 Reference Manual :: 11 Functions and Operations :: 11.7 Full-Text Search Functions
[2]In Groonga, we call it a 'tokenizer'.