MySQLでの全文検索(MeCab編)

本記事は[東京学芸大学 櫨山研究室 Advent Calendar 2020](https://qiita.com/advent-calendar/2020/hazelab)の十日目の記事になります．

# はじめに

[前回](https://qiita.com/wf-yamaday/items/a123e7b0f79fa799454b)はMySQLのN-gramパーサーを使った全文検索を扱いました．
本記事では形態素解析エンジンのMeCabパーサーを使った全文検索について扱います．

# 形態素解析とは？

形態素解析とは文字列を文法や単位の品詞などの情報に基づき，意味の最小単位である形態素に分解する処理です．

例えば`明日の天気は晴れです`という文の場合，形態素解析をすると

```
'明日', `の`, `天気`, `は`, `晴れ`, `です`
```

となります．

日本語の形態素解析エンジンとしてMeCabは非常に有名です，
MySQLではMeCabパーサーを使って全文検索のためのindexを作成することができます．

# MySQLの準備

MySQLサーバをdockerで用意します．

バージョンはMySQL 8.0を使います．
日本語を使いたいので文字コードは`UTF-8`とします．

```docker:Dockerfile
FROM mysql:8

RUN apt-get update \
    && apt-get install -y locales \
    && locale-gen ja_JP.UTF-8
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL=ja_JP.UTF-8
RUN localedef -f UTF-8 -i ja_JP ja_JP.utf8
```

`my.cnf`は以下の通りです．
`my.cnf`は`./conf/my.cnf`に配置します．
前回との差分としては`innodb_ft_min_token_size`に`1`を指定していることです．
こちらはMeCabパーサーによるfulltext index構築の際の単語の最小の長さになります．

```conf:my.cnf
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
innodb-use-native-aio = 0
innodb_ft_min_token_size = 1
```

MeCabを利用するために`mecabrc`ファイルを用意します．

```conf:mecabrc
dicdir = /usr/lib64/mysql/mecab/dic/ipadic_utf-8
```

`docker-compose.yml`を用意します．

```yml:docker-compose.yml
version: '3.7'

services:
  db:
    container_name: db
    build:
      context: .
      dockerfile: ./Dockerfile
    volumes:
      - ./conf/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./conf/mecabrc:/usr/lib64/mysql/mecab/etc/mecabrc
    tty: true
    environment:
      TZ: 'Asia/Tokyo'
      MYSQL_USER: 'user'
      MYSQL_PASSWORD: 'password'
      MYSQL_ROOT_PASSWORD: 'root'
```

`docker-compose up`コマンドで立ち上げて`docker exec`コマンドでMySQLの中に入ります．

```bash:bash
docker-compose up
docker exec -it db bin/bash -c "mysql -u root -p"
```

## データベースの作成

はじめにデータベースを作りましょう．
データベース名は適当にsampleとします．

```sql:MySQL_Client
CREATE DATABASE sample;
use sample;
```

## MeCabプラグインの導入

MeCabプラグインを導入します．
MySQLで以下のコマンドを入力します．

```sql:MySQL_Client
INSTALL PLUGIN mecab SONAME 'libpluginmecab.so';
```

# 全文検索に使用するデータ

次に全文検索を試すデータを投入します．
前回と同様に小倉百人一首のデータを使います．

データ構造は以下のようになっています．

|項目|内容|
|:--|:--|
|id|主キー|
|poet|歌人|
|above|上の句|
|below|下の句|
|above_kana|上の句（かな）|
|below_kana|下の句（かな）|

先ほど作成した`sample`データベースの中に，この構造を持ったテーブルを作成します．
テーブル名は`ogura`とします．

```sql:MySQL_Client
create table `ogura` (
  `id` INT unsigned NOT NULL AUTO_INCREMENT,
  `poet` text,
  `above` text,
  `below` text,
  `above_kana` text,
  `below_kana` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```

テーブルを作成したらデータを投入します．

データは以下のリンクを元に作成しています．

> nyoronjp/Ogura_Hyakunin_Isshu.csv, https://github.com/nyoronjp/Ogura_Hyakunin_Isshu.csv


```sql:MySQL_Client
INSERT INTO `ogura` (`poet`,`above`,`below`,`above_kana`,`below_kana`)
VALUES
  ('天智天皇','秋の田のかりほの庵の苫をあらみ','わが衣手は露にぬれつつ','あきのたのかりほのいほのとまをあらみ','わがころもではつゆにぬれつつ'),
  ('持統天皇','春過ぎて夏来にけらし白妙の','衣干すてふ天の香具山','はるすぎてなつきにけらししろたへの','ころもほすてふあまのかぐやま'),
  ('柿本人麻呂','あしびきの山鳥の尾のしだり尾の','ながながし夜をひとりかも寝む','あしびきのやまどりのをのしだりをの','ながながしよをひとりかもねむ'),
  ('山辺赤人','田子の浦にうち出でてみれば白妙の','富士の高嶺に雪は降りつつ','たごのうらにうちいでてみればしろたへの','ふじのたかねにゆきはふりつつ'),
  ('猿丸大夫','奥山に紅葉踏み分け鳴く鹿の','声聞く時ぞ秋は悲しき','おくやまにもみぢふみわけなくしかの','こゑきくときぞあきはかなしき'),
  ('中納言家持','かささぎの渡せる橋に置く霜の','白きを見れば夜ぞ更けにける','かささぎのわたせるはしにおくしもの','しろきをみればよぞふけにける'),
  ('安倍仲麻呂','天の原ふりさけみれば春日なる','三笠の山に出でし月かも','あまのはらふりさけみればかすがなる','みかさのやまにいでしつきかも'),
  ('喜撰法師','わが庵は都の辰巳しかぞ住む','世をうぢ山と人はいふなり','わがいほはみやこのたつみしかぞすむ','よをうぢやまとひとはいふなり'),
  ('小野小町','花の色は移りにけりないたづらに','わが身世にふるながめせしまに','はなのいろはうつりにけりないたづらに','わがみよにふるながめせしまに'),
  ('蝉丸','これやこの行くも帰るも別れては','知るも知らぬも逢坂の関','これやこのゆくもかへるもわかれては','しるもしらぬもあふさかのせき'),
  ('参議篁','わたの原八十島かけて漕ぎ出でぬと','人にはつげよ海人の釣船','わたのはらやそしまかけてこぎいでぬと','ひとにはつげよあまのつりぶね'),
  ('僧正遍昭','天つ風雲の通ひ路吹きとぢよ','乙女の姿しばしとどめむ','あまつかぜくものかよひぢふきとぢよ','をとめのすがたしばしとどめむ'),
  ('陽成院','筑波嶺の峰より落つるみなの川','恋ぞつもりて淵となりぬる','つくばねのみねよりおつるみなのがは','こひぞつもりてふちとなりぬる'),
  ('河原左大臣','陸奥のしのぶもぢずりたれゆえに','乱れそめにしわれならなくに','みちのくのしのぶもぢずりたれゆゑに','みだれそめにしわれならなくに'),
  ('光孝天皇','君がため春の野に出でて若菜摘む','わが衣手に雪は降りつつ','きみがためはるののにいでてわかなつむ','わがころもでにゆきはふりつつ'),
  ('中納言行平','立ち別れいなばの山の峰に生ふる','まつとし聞かば今帰り来む','たちわかれいなばのやまのみねにおふる','まつとしきかばいまかへりこむ'),
  ('在原業平朝臣','ちはやぶる神代も聞かず竜田川','から紅に水くくるとは','ちはやぶるかみよもきかずたつたがは','からくれなゐにみづくくるとは'),
  ('藤原敏行朝臣','住の江の岸に寄る波よるさへや','夢の通ひ路人目よくらむ','すみのえのきしによるなみよるさへや','ゆめのかよひぢひとめよくらむ'),
  ('伊勢','難波潟短き葦のふしの間も','逢はでこの世を過ぐしてよとや','なにはがたみじかきあしのふしのまも','あはでこのよをすぐしてよとや'),
  ('元良親王','わびぬれば今はた同じ難波なる','身をつくしても逢はむとぞ思ふ','わびぬればいまはたおなじなにはなる','みをつくしてもあはむとぞおもふ'),
  ('素性法師','今来むといひしばかりに長月の','有明の月を待ち出でつるかな','いまこむといひしばかりにながつきの','ありあけのつきをまちいでつるかな'),
  ('文屋康秀','吹くからに秋の草木のしをるれば','むべ山風を嵐といふらむ','ふくからにあきのくさきのしをるれば','むべやまかぜをあらしといふらむ'),
  ('大江千里','月見れば千々にものこそ悲しけれ','わが身ひとつの秋にはあらねど','つきみればちぢにものこそかなしけれ','わがみひとつのあきにはあらねど'),
  ('菅家','このたびは幣もとりあへず手向山','紅葉の錦神のまにまに','このたびはぬさもとりあへずたむけやま','もみぢのにしきかみのまにまに'),
  ('三条右大臣','名にし負はば逢坂山のさねかずら','人に知られでくるよしもがな','なにしおはばあふさかやまのさねかづら','ひとにしられでくるよしもがな'),
  ('貞信公','小倉山峰のもみぢ葉心あらば','今ひとたびのみゆき待たなむ','をぐらやまみねのもみぢばこころあらば','いまひとたびのみゆきまたなむ'),
  ('中納言兼輔','みかの原わきて流るる泉川','いつ見きとてか恋しかるらむ','みかのはらわきてながるるいづみがは','いつみきとてかこひしかるらむ'),
  ('源宗于朝臣','山里は冬ぞ寂しさまさりける','人目も草もかれぬと思へば','やまざとはふゆぞさびしさまさりける','ひとめもくさもかれぬとおもへば'),
  ('凡河内躬恒','心あてに折らばや折らむ初霜の','置きまどはせる白菊の花','こころあてにをらばやをらむはつしもの','おきまどはせるしらぎくのはな'),
  ('壬生忠岑','有明のつれなく見えし別れより','暁ばかり憂きものはなし','ありあけのつれなくみえしわかれより','あかつきばかりうきものはなし'),
  ('坂上是則','朝ぼらけ有明の月と見るまでに','吉野の里に降れる白雪','あさぼらけありあけのつきとみるまでに','よしののさとに ふれるしらゆき'),
  ('春道列樹','山川に風のかけたるしがらみは','流れもあへぬ紅葉なりけり','やまがはにかぜのかけたるしがらみは','ながれもあへぬもみぢなりけり'),
  ('紀友則','ひさかたの光のどけき春の日に','しづ心なく花の散るらむ','ひさかたのひかりのどけきはるのひに','しづこころなくはなのちるらむ'),
  ('藤原興風','誰をかも知る人にせむ高砂の','松も昔の友ならなくに','たれをかもしるひとにせむたかさごの','まつもむかしのともならなくに'),
  ('紀貫之','人はいさ心も知らずふるさとは','花ぞ昔の香に匂ひける','ひとはいさこころもしらずふるさとは','はなぞむかしのかににほひける'),
  ('清原深養父','夏の夜はまだ宵ながら明けぬるを','雲のいずこに月宿るらむ','なつのよはまだよひながらあけぬるを','くものいづこにつきやどるらむ'),
  ('文屋朝康','白露に風の吹きしく秋の野は','つらぬきとめぬ玉ぞ散りける','しらつゆにかぜのふきしくあきののは','つらぬきとめぬたまぞちりける'),
  ('右近','忘らるる身をば思はず誓ひてし','人の命の惜しくもあるかな','わすらるるみをばおもはずちかひてし','ひとのいのちのをしくもあるかな'),
  ('参議等','浅茅生の小野の篠原忍ぶれど','あまりてなどか人の恋しき','あさぢふのをののしのはらしのぶれど','あまりてなどかひとのこひしき'),
  ('平兼盛','忍ぶれど色に出でにけりわが恋は','ものや思ふと人の問ふまで','しのぶれどいろにいでにけりわがこひは','ものやおもふとひとのとふまで'),
  ('壬生忠見','恋すてふわが名はまだき立ちにけり','人知れずこそ思ひそめしか','こひすてふわがなはまだきたちにけり','ひとしれずこそおもひそめしか'),
  ('清原元輔','契りきなかたみに袖をしぼりつつ','末の松山波越さじとは','ちぎりきなかたみにそでをしぼりつつ','すゑのまつやまなみこさじとは'),
  ('権中納言敦忠','逢ひ見ての後の心にくらぶれば','昔はものを思はざりけり','あひみてののちのこころにくらぶれば','むかしはものをおもはざりけり'),
  ('中納言朝忠','逢ふことの絶えてしなくはなかなかに','人をも身をも恨みざらまし','あふことのたえてしなくはなかなかに','ひとをもみをもうらみざらまし'),
  ('謙徳公','あはれともいふべき人は思ほえで','身のいたずらになりぬべきかな','あはれともいふべきひとはおもほえで','みのいたづらになりぬべきかな'),
  ('曾禰好忠','由良の戸を渡る舟人かぢをたえ','ゆくへも知らぬ恋の道かな','ゆらのとをわたるふなびとかぢをたえ','ゆくへもしらぬこひのみちかな'),
  ('恵慶法師','八重むぐら茂れる宿のさびしきに','人こそ見えね秋は来にけり','やへむぐらしげれるやどのさびしきに','ひとこそみえねあきはきにけり'),
  ('源重之','風をいたみ岩うつ波のおのれのみ','くだけてものを思ふころかな','かぜをいたみいはうつなみのおのれのみ','くだけてものをおもふころかな'),
  ('大中臣能宣','御垣守衛士のたく火の夜は燃え','昼は消えつつものをこそ思へ','みかきもりゑじのたくひのよるはもえ','ひるはきえつつものをこそおもへ'),
  ('藤原義孝','君がため惜しからざりし命さへ','長くもがなと思ひけるかな','きみがためをしからざりしいのちさへ','ながくもがなとおもひけるかな'),
  ('藤原実方朝臣','かくとだにえやはいぶきのさしも草','さしも知らじな燃ゆる思ひを','かくとだにえやはいぶきのさしもぐさ','さしもしらじなもゆるおもひを'),
  ('藤原道信朝臣','明けぬれば暮るるものとは知りながら','なほ恨めしき朝ぼらけかな','あけぬればくるるものとはしりながら','なほうらめしきあさぼらけかな'),
  ('右大将道綱母','嘆きつつひとり寝る夜の明くる間は','いかに久しきものとかは知る','なげきつつひとりぬるよのあくるまは','いかにひさしきものとかはしる'),
  ('儀同三司母','忘れじの行く末まではかたければ','今日をかぎりの命ともがな','わすれじのゆくすゑまではかたければ','けふをかぎりのいのちともがな'),
  ('大納言公任','滝の音は絶えて久しくなりぬれど','名こそ流れてなほ聞こえけれ','たきのおとはたえてひさしくなりぬれど','なこそながれてなほきこえけれ'),
  ('和泉式部','あらざらむこの世のほかの思ひ出に','今ひとたびの逢ふこともがな','あらざらむこのよのほかのおもひでに','いまひとたびのあふこともがな'),
  ('紫式部','めぐり逢ひて見しやそれとも分かぬ間に','雲隠れにし夜半の月かな','めぐりあひてみしやそれともわかぬまに','くもがくれにしよはのつきかな'),
  ('大弐三位','有馬山猪名の笹原風吹けば','いでそよ人を忘れやはする','ありまやまゐなのささはらかぜふけば','いでそよひとをわすれやはする'),
  ('赤染衛門','やすらはで寝なましものを小夜更けて','かたぶくまでの月を見しかな','やすらはでねなましものをさよふけて','かたぶくまでのつきをみしかな'),
  ('小式部内侍','大江山いく野の道の遠ければ','まだふみも見ず天の橋立','おほえやまいくののみちのとほければ','まだふみもみずあまのはしだて'),
  ('伊勢大輔','いにしへの奈良の都の八重桜','けふ九重に匂ひぬるかな','いにしへのならのみやこのやへざくら','けふここのへににほひぬるかな'),
  ('清少納言','夜をこめて鳥のそら音ははかるとも','よに逢坂の関はゆるさじ','よをこめてとりのそらねははかるとも','よにあふさかのせきはゆるさじ'),
  ('左京大夫道雅','今はただ思ひ絶えなむとばかりを','人づてならでいふよしもがな','いまはただおもひたえなむとばかりを','ひとづてならでいふよしもがな'),
  ('権中納言定頼','朝ぼらけ宇治の川霧たえだえに','あらはれわたる瀬々の網代木','あさぼらけうぢのかはぎりたえだえに','あらはれわたるせぜのあじろぎ'),
  ('相模','恨みわび干さぬ袖だにあるものを','恋に朽ちなむ名こそ惜しけれ','うらみわびほさぬそでだにあるものを','こひにくちなむなこそをしけれ'),
  ('前大僧正行尊','もろともにあはれと思え山桜','花よりほかに知る人もなし','もろともにあはれとおもへやまざくら','はなよりほかにしるひともなし'),
  ('周防内侍','春の夜の夢ばかりなる手枕に','かひなく立たむ名こそ惜しけれ','はるのよのゆめばかりなるたまくらに','かひなくたたむなこそをしけれ'),
  ('三条院','心にもあらで憂き夜にながらへば','恋しかるべき夜半の月かな','こころにもあらでうきよにながらへば','こひしかるべきよはのつきかな'),
  ('能因法師','嵐ふく三室の山のもみぢ葉は','竜田の川の錦なりけり','あらしふくみむろのやまのもみぢばは','たつたのかはのにしきなりけり'),
  ('良暹法師','寂しさに宿を立ち出でてながむれば','いづこも同じ秋の夕暮れ','さびしさにやどをたちいでてながむれば','いづこもおなじあきのゆふぐれ'),
  ('大納言経信','夕されば門田の稲葉おとづれて','葦のまろやに秋風ぞ吹く','ゆふさればかどたのいなばおとづれて','あしのまろやにあきかぜぞふく'),
  ('祐子内親王家紀伊','音に聞く高師の浜のあだ波は','かけじや袖のぬれもこそすれ','おとにきくたかしのはまのあだなみは','かけじやそでのぬれもこそすれ'),
  ('権中納言匡房','高砂の尾の上の桜咲きにけり','外山の霞立たずもあらなむ','たかさごのをのへのさくらさきにけり','とやまのかすみたたずもあらなむ'),
  ('源俊頼朝臣','憂かりける人を初瀬の山おろしよ','はげしかれとは祈らぬものを','うかりけるひとをはつせのやまおろしよ','はげしかれとはいのらぬものを'),
  ('藤原基俊','契りおきしさせもが露を命にて','あはれ今年の秋もいぬめり','ちぎりおきしさせもがつゆをいのちにて','あはれことしのあきもいぬめり'),
  ('法性寺入道前関白太政大臣','わたの原漕ぎ出でて見ればひさかたの','雲居にまがふ沖つ白波','わたのはらこぎいでてみればひさかたの','くもゐにまがふおきつしらなみ'),
  ('崇徳院','瀬をはやみ岩にせかるる滝川の','われても末に逢はむとぞ思ふ','せをはやみいはにせかるるたきがはの','われてもすゑにあはむとぞおもふ'),
  ('源兼昌','淡路島通ふ千鳥の鳴く声に','いく夜寝覚めぬ須磨の関守','あはぢしまかよふちどりのなくこゑに','いくよねざめぬすまのせきもり'),
  ('左京大夫顕輔','秋風にたなびく雲のたえ間より','もれ出づる月の影のさやけさ','あきかぜにたなびくくものたえまより','もれいづるつきのかげのさやけさ'),
  ('待賢門院堀河','ながからむ心も知らず黒髪の','乱れてけさはものをこそ思へ','ながからむこころもしらずくろかみの','みだれてけさはものをこそおもへ'),
  ('後徳大寺左大臣','ほととぎす鳴きつる方をながむれば','ただ有明の月ぞ残れる','ほととぎすなきつるかたをながむれば','ただありあけのつきぞのこれる'),
  ('道因法師','思ひわびさても命はあるものを','憂きに堪へぬは涙なりけり','おもひわびさてもいのちはあるものを','うきにたへぬはなみだなりけり'),
  ('皇太后宮大夫俊成','世の中よ道こそなけれ思ひ入る','山の奥にも鹿ぞ鳴くなる','よのなかよみちこそなけれおもひいる','やまのおくにもしかぞなくなる'),
  ('藤原清輔朝臣','ながらへばまたこのごろやしのばれむ','憂しと見し世ぞ今は恋しき','ながらへばまたこのごろやしのばれむ','うしとみしよぞいまはこひしき'),
  ('俊恵法師','夜もすがらもの思ふころは明けやらで','ねやのひまさへつれなかりけり','よもすがらものおもふころはあけやらで','ねやのひまさへつれなかりけり'),
  ('西行法師','嘆けとて月やはものを思はする','かこち顔なるわが涙かな','なげけとてつきやはものをおもはする','かこちがほなるわがなみだかな'),
  ('寂蓮法師','村雨の露もまだ干ぬまきの葉に','霧立ちのぼる秋の夕暮','むらさめのつゆもまだひぬまきのはに','きりたちのぼるあきのゆふぐれ'),
  ('皇嘉門院別当','難波江の葦のかりねのひとよゆゑ','身をつくしてや恋ひわたるべき','なにはえのあしのかりねのひとよゆゑ','みをつくしてやこひわたるべき'),
  ('式子内親王','玉の緒よ絶えなば絶えねながらへば','忍ぶることの弱りもぞする','たまのをよたえなばたえねながらへば','しのぶることのよわりもぞする'),
  ('殷富門院大輔','見せばやな雄島の海人の袖だにも','濡れにぞ濡れし色は変はらず','みせばやなをじまのあまのそでだにも','ぬれにぞぬれしいろはかはらず'),
  ('後京極摂政前太政大臣','きりぎりす鳴くや霜夜のさむしろに','衣かたしきひとりかも寝む','きりぎりすなくやしもよのさむしろに','ころもかたしきひとりかもねむ'),
  ('二条院讃岐','わが袖は潮干に見えぬ沖の石の','人こそ知らねかわく間もなし','わがそではしほひにみえぬおきのいしの','ひとこそしらねかわくまもなし'),
  ('鎌倉右大臣','世の中は常にもがもな渚漕ぐ','海人の小舟の綱手かなしも','よのなかはつねにもがもななぎさこぐ','あまのをぶねのつなでかなしも'),
  ('参議雅経','み吉野の山の秋風小夜更けて','ふるさと寒く衣うつなり','みよしののやまのあきかぜさよふけて','ふるさとさむくころもうつなり'),
  ('前大僧正慈円','おほけなく憂き世の民におほふかな','わが立つ杣にすみ染の袖','おほけなくうきよのたみにおほふかな','わがたつそまにすみぞめのそで'),
  ('入道前太政大臣','花さそふ嵐の庭の雪ならで','ふりゆくものはわが身なりけり','はなさそふあらしのにはのゆきならで','ふりゆくものはわがみなりけり'),
  ('権中納言定家','来ぬ人を松帆の浦の夕なぎに','焼くや藻塩の身もこがれつつ','こぬひとをまつほのうらのゆふなぎに','やくやもしほのみもこがれつつ'),
  ('従二位家隆','風そよぐ楢の小川の夕暮は','みそぎぞ夏のしるしなりける','かぜそよぐならのをがはのゆふぐれは','みそぎぞなつのしるしなりける'),
  ('後鳥羽院','人もをし人もうらめしあじきなく','世を思ふゆゑにもの思ふ身は','ひともをしひともうらめしあぢきなく','よをおもふゆゑにものおもふみは'),
  ('順徳院','百敷や古き軒端のしのぶにも','なほあまりある昔なりけり','ももしきやふるきのきばのしのぶにも','なほあまりあるむかしなりけり');
```


# MeCabパーサーでの全文検索を試す

全文検索の対象のカラムにMeCabパーサーでの`fulltext index`を貼ります．

```sql:MySQL_Client
ALTER TABLE ogura ADD FULLTEXT (poet) WITH PARSER mecab;
ALTER TABLE ogura ADD FULLTEXT (above) WITH PARSER mecab;
ALTER TABLE ogura ADD FULLTEXT (below) WITH PARSER mecab;
ALTER TABLE ogura ADD FULLTEXT (above_kana) WITH PARSER mecab;
ALTER TABLE ogura ADD FULLTEXT (below_kana) WITH PARSER mecab;
```

それでは上の句に**"春"**を含んだ句を検索してみましょう．

```sql:MySQL_Client
SELECT * FROM ogura WHERE MATCH (above) AGAINST ('春')\G;

*************************** 1. row ***************************
        id: 2
      poet: 持統天皇
     above: 春過ぎて夏来にけらし白妙の
     below: 衣干すてふ天の香具山
above_kana: はるすぎてなつきにけらししろたへの
below_kana: ころもほすてふあまのかぐやま
*************************** 2. row ***************************
        id: 15
      poet: 光孝天皇
     above: 君がため春の野に出でて若菜摘む
     below: わが衣手に雪は降りつつ
above_kana: きみがためはるののにいでてわかなつむ
below_kana: わがころもでにゆきはふりつつ
*************************** 3. row ***************************
        id: 33
      poet: 紀友則
     above: ひさかたの光のどけき春の日に
     below: しづ心なく花の散るらむ
above_kana: ひさかたのひかりのどけきはるのひに
below_kana: しづこころなくはなのちるらむ
*************************** 4. row ***************************
        id: 67
      poet: 周防内侍
     above: 春の夜の夢ばかりなる手枕に
     below: かひなく立たむ名こそ惜しけれ
above_kana: はるのよのゆめばかりなるたまくらに
below_kana: かひなくたたむなこそをしけれ
4 rows in set (0.00 sec)
```

bigramのngramパーサーでは取得できなかった検索結果を得ることができました✨

## indexの中身をみる

indexの中身をみてみましょう．

```sql:MySQL_Client
SET GLOBAL innodb_ft_aux_table="sample/ogura";

SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE ORDER BY doc_id LIMIT 20;
+--------+--------------+-------------+-----------+--------+----------+
| WORD   | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION |
+--------+--------------+-------------+-----------+--------+----------+
| ぬれ   |            3 |          74 |         2 |      3 |       21 |
| ほ     |            3 |           3 |         1 |      3 |       18 |
| の     |            3 |         102 |        68 |      3 |       12 |
| 田     |            3 |           3 |         1 |      3 |        6 |
| かり   |            3 |          90 |         3 |      3 |       12 |
| 庵     |            3 |          10 |         2 |      3 |       24 |
| の     |            3 |         102 |        68 |      3 |        6 |
| は     |            3 |         101 |        28 |      3 |       12 |
| わが   |            3 |          97 |         4 |      3 |        0 |
| 秋     |            3 |          39 |         3 |      3 |        0 |
| 露     |            3 |           3 |         1 |      3 |       15 |
| の     |            3 |         102 |        68 |      3 |        3 |
| に     |            3 |          97 |        28 |      3 |       18 |
| つつ   |            3 |          99 |         5 |      3 |       27 |
| あら   |            3 |          70 |         4 |      3 |       36 |
| み     |            3 |          96 |         2 |      3 |       42 |
| 衣手   |            3 |          17 |         2 |      3 |        6 |
| 苫     |            3 |           3 |         1 |      3 |       30 |
| を     |            3 |         101 |        20 |      3 |       33 |
| の     |            3 |         102 |        68 |      3 |        6 |
+--------+--------------+-------------+-----------+--------+----------+
20 rows in set (0.01 sec)
```

形態素解析された形でwordが登録されていることがわかります．

# おわりに

[前回の記事](https://qiita.com/wf-yamaday/items/a123e7b0f79fa799454b)に引き続きMySQLを使った全文検索について取り扱いました．

本記事で全文検索の対象とした百人一首のような古典的な文章はMeCabの苦手とする領域かもしれませんがMySQLを使った全文検索の手軽さが伝わればと思います．