More Related Content More from Toshi Harada (20) textsearch jaで吉川三国志を読み解く15. テーブル構成
sangokushi=# d
List of relations
Schema |
Name
|
Type
| Owner
--------+-------------------+----------+-------public | sangokushi
| table
| harada
public | sangokushi_id_seq | sequence | harada
(2 rows)
sangokushi=# d sangokushi
Table "public.sangokushi"
Column | Type
|
Modifiers
---------+---------+--------------------------------------------------------id
| integer | not null default nextval('sangokushi_id_seq'::regclass)
vol
| text
|
chapter | text
|
body
| text
|
Indexes:
"idx" gin (to_tsvector('japanese'::regconfig, body)
18. 動作確認
sangokushi=# EXPLAIN ANALYZE SELECT id FROM sangokushi WHERE to_tsvector('japanese', body) @@ to_tsquery('japanese', ' 孔明 ');
QUERY PLAN
----------------------------------------------------------------------------------------------------------------Bitmap Heap Scan on sangokushi (cost=16.01..137.36 rows=2 width=4) (actual time=0.048..0.072 rows=134 loops=1)
Recheck Cond: (to_tsvector('japanese'::regconfig, body) @@ ''' 孔明 '''::tsquery)
-> Bitmap Index Scan on idx (cost=0.00..16.01 rows=2 width=0) (actual time=0.039..0.039 rows=134 loops=1)
Index Cond: (to_tsvector('japanese'::regconfig, body) @@ ''' 孔明 '''::tsquery)
Total runtime: 0.103 ms
(5 rows)
sangokushi=# EXPLAIN ANALYZE SELECT count(id) FROM sangokushi WHERE body LIKE '% 孔明 %';
QUERY PLAN
---------------------------------------------------------------------------------------------------------------Aggregate (cost=773.93..773.94 rows=1 width=4) (actual time=34.806..34.806 rows=1 loops=1)
-> Seq Scan on sangokushi (cost=0.00..773.92 rows=1 width=4) (actual time=13.361..34.763 rows=134 loops=1)
Filter: (body ~~ '% 孔明 %'::text)
Rows Removed by Filter: 180
Total runtime: 34.834 ms
(5 rows)
textsearch_ja を使った検索ではきちんと
インデックスが使用されている。
このくらいのデータ量でも、 LIKE との性能差は明らか。
27. こんな感じで
Mecab ユーザ辞書を追加する
劉備 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, りゅうび , リュウビ , リュービ
玄徳 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, げんとく , ゲントク , ゲントク
諸葛亮 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, しょかつりょう , ショカツリョウ , ショカツリョー
関羽 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, かんう , カンウ , カンウ
雲長 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, うんちょう , ウンチョウ , ウンチョー
張飛 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, ちょうひ , チョウヒ , チョーヒ
翼徳 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, よくとく , ヨクトク , ヨクトク
(省略)
呂布 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, りょふ , リョフ , リョフ
奉先 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, ほうせん , ホウセン , ホーセン
張遼 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, ちょうりょう , チョウリョウ , チョーリョー
文遠 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, ぶんえん , ブンエン , ブンエン
袁紹 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, えんしょう , エンショウ , エンショー
本初 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, ほんしょ , ホンショ , ホンショ
貂蝉 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, ちょうせん , チョウセン , チョーセン
赤兎馬 ,,,6000, 名詞 , 固有名詞 , 人名 , 名 ,*,*, せきとば , セキトバ , セキトバ
これを
Mecab 機能で
コンパイル&
登録する
今回は数十人の主要人物名の「姓名」「姓字名」を登録した。
(ついでに赤兎馬も)
31. こんな感じのクエリになる
しばちゅうさん(司馬懿)の例
sangokushi=# SELECT id, left(substr(chapter,8),10) AS chapter,
left(ts_headline('japanese',body, to_tsquery('japanese', ' 司馬懿 | 仲達 ')),30) AS body
FROM sangokushi
WHERE to_tsvector('japanese', body) @@ to_tsquery('japanese', ' 司馬懿 | 仲達 ') LIMIT 10;
id |
chapter
|
body
-----+----------------------+------------------------------------------------------138 | 臨戦《りんせん》第一 | <b> 司馬懿 </b> 《しばい》、字を <b> 仲達 </b> 《ちゅ
208 | 剣《けん》と戟《ほこ
| <b> 司馬懿 </b> 《しばい》 <b> 仲達 </b> 《ちゅうたつ
215 | 正月十五夜[#「正月 | <b> 司馬懿 </b><b> 仲達 </b> が、側で眉をひそめた。
225 | 漢中王《かんちゅうお | <b> 司馬懿 </b> 《しばい》、字《あざな》は <b> 仲達 </
231 | 建業会議《けんぎょう | <b> 司馬懿 </b> 《しばい》 <b> 仲達 </b> 《ちゅうたつ
239 | 国葬[#「国葬」は大 | <b> 司馬懿 </b> 《しばい》、字《あざな》は <b> 仲達 </
242 | 曹操《そうそう》死《
| <b> 司馬懿 </b> 《しばい》 <b> 仲達 </b> がそっと、枕
246 | 改元[#「改元」は大 | <b> 司馬懿 </b> 《しばい》 <b> 仲達 </b> があわてて、
259 | 魚紋[#「魚紋」は大 | <b> 司馬懿 </b> 《しばい》、字は <b> 仲達 </b> 《ちゅ
261 | 建艦総力[#「建艦総 | <b> 仲達 </b> は、「呉の守りは、長江を生命としています。
37. 章ごとの登場比率
吉川三国志 主要人物 / 章別 ランク比率
100%
90%
80%
70%
董卓
呂布
周瑜
孫家
司馬懿
曹操
孔明
関羽
劉備
60%
50%
40%
30%
20%
10%
0%
6 16 26 36 46 56 66 76 86 96 106 116 126 136 146 156 166 176 186 196 206 216 226 236 246 256 266 276 286 296 306
1 11 21 31 41 51 61 71 81 91 101 111 121 131 141 151 161 171 181 191 201 211 221 231 241 251 261 271 281 291 301 311
38. ストーリーと比較するとこんな感じに
虎牢関
小覇王 呂布の最期
赤壁
周瑜の最期
夷陵
出師の表
吉川三国志 主要人物 / 章別 ランク比率
100%
90%
80%
70%
董卓
呂布
周瑜
孫家
司馬懿
曹操
孔明
関羽
劉備
60%
50%
40%
30%
20%
10%
0%
6 16 26 36 46 56 66 76 86 96 106 116 126 136 146 156 166 176 186 196 206 216 226 236 246 256 266 276 286 296 306
1 11 21 31 41 51 61 71 81 91 101 111 121 131 141 151 161 171 181 191 201 211 221 231 241 251 261 271 281 291 301 311
桃園の誓い
連環の計
関羽千里行 関羽の最期 曹操の最期
南蛮行
五丈原
39. 章ごとの登場比率
冒頭の主役は劉備と関羽 ( と張飛 )
●
曹操も出てくるけど、そこまで目立たない
●
序盤での呂布の暴れっぷり
●中盤の主役は実は曹操なのだな
●終盤の主役は勿論、諸葛亮と司馬懿
●呉(笑)
●
小覇王の時代や赤壁など見せ場はあるけどさ
●
43. 補足
textsearch_ja は 9.0 以降、正式な対応が止まっている。
●現状は EXTENSION に対応していない。
●9.2 以降だと、 DL したファイルそのままだと、インストール
時に失敗するので、 LANGUAGE='C' を LANGUAGE=c など
に変更する必要がある。
●9.3 上で動かす場合、 textsearch_ja.c に
#include "access/htup_details.h"
の行を追加しないとビルド時に警告がでる。
●また、上記の対処をしないと、 ja_analyze() で異常終了する
ことがある。
●