rabbit-slide-kou-db-tech-showcase-tokyo-2018 2018.9.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f4e56bdb9caffa3927d65a11ceea3b0c7b13be08e671e9dc32f5bf4b5280d583
4
+ data.tar.gz: caa57879f91e5fdfcd5c6e23e116cd8e5ffb32d3586dcbeff5ef5486de057c07
5
+ SHA512:
6
+ metadata.gz: 11b5bb5130d0e6484c5d441951c3d46c8fc9ca63bfb2091a9b06b8464287997b821aa0a2963e382d2b3bbe0afeafb1c892ceb1fb681d830b47b1c542c7d878d2
7
+ data.tar.gz: 46837f05913b91048fdc387e8649ee745ecd200ce9d276e6269d9aed4f0418b83fc704758983b99739500aabde2b3efce925c935427e3bc95ba3af1c51a5c709
data/.rabbit ADDED
@@ -0,0 +1 @@
1
+ --size 800,450 mysql-postgresql-fast-fuzzy-full-text-search-system.rab
@@ -0,0 +1,26 @@
1
+ = MySQL・PostgreSQLだけで作る高速あいまい全文検索システム
2
+
3
+ ナイーブな全文検索は単なる中間一致検索です。しかし、現実に人が入力するテキストは揺れまくっているので単なる中間一致検索では必要な情報を見つけられません。たとえば、「(090)1234-5678」も「090ー1234ー5678」も「09012345678」もすべて同じ電話番号として扱いたいのが現実です。
4
+
5
+ MySQLとPostgreSQLの全文検索機能ではこのようにゆるい全文検索を高速に実現することができません。そこでMroonga・PGroongaです。Mroonga・PGroongaを使ってMySQL・PostgreSQLだけで高速にゆるく全文検索する方法を紹介します。
6
+
7
+ == 作者向け
8
+
9
+ === 表示
10
+
11
+ rake
12
+
13
+ === 公開
14
+
15
+ rake publish
16
+
17
+ == 閲覧者向け
18
+
19
+ === インストール
20
+
21
+ gem install rabbit-slide-kou-db-tech-showcase-tokyo-2018
22
+
23
+ === 表示
24
+
25
+ rabbit rabbit-slide-kou-db-tech-showcase-tokyo-2018.gem
26
+
@@ -0,0 +1,17 @@
1
+ require "rabbit/task/slide"
2
+
3
+ # Edit ./config.yaml to customize meta data
4
+
5
+ spec = nil
6
+ Rabbit::Task::Slide.new do |task|
7
+ spec = task.spec
8
+ # spec.files += Dir.glob("doc/**/*.*")
9
+ # spec.files -= Dir.glob("private/**/*.*")
10
+ spec.add_runtime_dependency("rabbit-theme-groonga")
11
+ end
12
+
13
+ desc "Tag #{spec.version}"
14
+ task :tag do
15
+ sh("git", "tag", "-a", spec.version.to_s, "-m", "Publish #{spec.version}")
16
+ sh("git", "push", "--tags")
17
+ end
@@ -0,0 +1,31 @@
1
+ ---
2
+ id: db-tech-showcase-tokyo-2018
3
+ base_name: mysql-postgresql-fast-fuzzy-full-text-search-system
4
+ tags:
5
+ - rabbit
6
+ - dbts2018
7
+ - mysql
8
+ - mariadb
9
+ - postgresql
10
+ - mroonga
11
+ - pgroonga
12
+ - groonga
13
+ presentation_date: 2018-09-20
14
+ presentation_start_time: 2018-09-20
15
+ presentation_end_time: 2018-09-20
16
+ version: 2018.9.20.0
17
+ licenses:
18
+ - CC-BY-SA-4.0
19
+ - CC-BY-3.0
20
+ slideshare_id:
21
+ speaker_deck_id:
22
+ ustream_id:
23
+ vimeo_id:
24
+ youtube_id:
25
+ author:
26
+ markup_language: :rd
27
+ name: 須藤功平
28
+ email: kou@clear-code.com
29
+ rubygems_user: kou
30
+ slideshare_user: kou
31
+ speaker_deck_user:
@@ -0,0 +1,1025 @@
1
+ = MySQL・PostgreSQLだけで作る\n高速あいまい全文検索システム
2
+
3
+ : author
4
+ 須藤功平
5
+ : institution
6
+ 株式会社クリアコード
7
+ : content-source
8
+ db tech showcase Tokyo 2018
9
+ : date
10
+ 2018-09-20
11
+ : start-time
12
+ 2018-09-20T09:30:00+09:00
13
+ : end-time
14
+ 2018-09-20T10:15:00+09:00
15
+ : theme
16
+ .
17
+
18
+ = 全文検索システム
19
+
20
+ * 大量の文書から
21
+ * 指定されたキーワードを使って
22
+ * 高速に必要な文書を
23
+ * 見つけるシステム
24
+
25
+ = dbts2017
26
+
27
+ # image
28
+ # src = https://slide.rabbit-shocker.org/authors/kou/db-tech-showcase-tokyo-2017/mysql-postgresql-rich-full-text-search-system.pdf
29
+ # page = 1
30
+ # relative_height = 90
31
+
32
+ (('tag:xx-small'))
33
+ (('tag:center'))
34
+ ((<URL:https://slide.rabbit-shocker.org/authors/kou/db-tech-showcase-tokyo-2017/>))
35
+
36
+ = リッチな全文検索システム
37
+
38
+ * キーワードハイライト
39
+ * 周辺テキスト表示
40
+ * 入力補完・同義語展開
41
+ * 関連文書の表示
42
+ * 構造化データ対応(例:オフィス文書)
43
+
44
+ = もっとリッチな全文検索システム
45
+
46
+ * 大量の文書から
47
+ * ((*あいまいな情報を使って*))
48
+ * 高速に必要な文書を
49
+ * 見つけるシステム
50
+
51
+ = あいまいな情報
52
+
53
+ 相手が((*人*))だから
54
+
55
+ = 人
56
+
57
+ * 提供情報があいまい
58
+ * 例:「apple」(企業?食べ物?)
59
+ * 検索クエリー
60
+ * 文書内の表記が揺れる
61
+ * 例:「焼き肉」「焼きにく」
62
+ * 検索対象
63
+
64
+ = もっとリッチな全文検索システム
65
+
66
+ * 大量の文書から
67
+ * ((*あいまいな情報を使って*))
68
+ * 高速に必要な文書を
69
+ * 見つけるシステム
70
+
71
+ = ツール
72
+
73
+ 全文検索エンジン
74
+
75
+ = 普通の全文検索エンジン
76
+
77
+ * 高速検索
78
+ * あいまい検索
79
+ * 独自の使い方
80
+
81
+ = 開発しやすいシステム
82
+
83
+ SQLで使える
84
+
85
+ = 使いやすい全文検索エンジン
86
+
87
+ * 高速検索
88
+ * あいまい検索
89
+ * SQLで使える
90
+
91
+ = SQLで使える全文検索エンジン
92
+
93
+ * Mroonga
94
+ * MySQL・MariaDB用
95
+ * ((<URL:http://mroonga.org/ja/docs/install.html>))
96
+ * PGroonga
97
+ * PostgreSQL用
98
+ * ((<URL:https://pgroonga.github.io/ja/install/>))
99
+
100
+ = あいまい検索:表記ゆれ1
101
+
102
+ * 焼肉:全部漢字
103
+ * 焼き肉:送り仮名
104
+ * 焼きにく:まぜまぜ
105
+
106
+ = あいまい検索:表記ゆれ1対策
107
+
108
+ ヨミガナ検索
109
+
110
+ = ヨミガナ検索
111
+
112
+ * ヨミガナで検索
113
+ * 「焼肉」→「ヤキニク」
114
+ * 「焼きにく」→「ヤキニク」
115
+ * どちらも同じになる
116
+ * 人名(高と髙とか)にも使える
117
+ * ヨミガナ情報の取得が必要
118
+ * MeCabで自動化可能
119
+
120
+ = MeCabでヨミガナ化
121
+
122
+ # coderay console
123
+ % echo 焼肉と焼きにく | mecab | cut -d, -f8
124
+ ヤキニク
125
+
126
+ ヤキニク
127
+ EOS
128
+
129
+ = ヨミガナ検索:Mroonga:テーブル定義
130
+
131
+ # coderay sql
132
+ CREATE TABLE menus (
133
+ name varchar(255), -- 検索対象
134
+ FULLTEXT INDEX (name) -- ヨミガナ検索対応インデックス
135
+ COMMENT
136
+ 'tokenizer "TokenMecab(\'loose_reading\', true)"'
137
+ ) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
138
+
139
+ == スライドプロパティ
140
+
141
+ : groonga-product
142
+
143
+ mroonga
144
+
145
+ = ヨミガナ検索:Mroonga:データ例
146
+
147
+ # coderay sql
148
+ INSERT INTO menus
149
+ VALUES ('焼肉定食'),
150
+ ('焼きにく定食');
151
+
152
+ == スライドプロパティ
153
+
154
+ : groonga-product
155
+
156
+ mroonga
157
+
158
+ = ヨミガナ検索:Mroonga:検索
159
+
160
+ # coderay sql
161
+ SELECT name FROM menus
162
+ WHERE MATCH (name)
163
+ AGAINST ('*D+ 焼きにく' IN BOOLEAN MODE);
164
+ -- 焼肉定食
165
+ -- 焼きにく定食
166
+
167
+ == スライドプロパティ
168
+
169
+ : groonga-product
170
+
171
+ mroonga
172
+
173
+ = ヨミガナ検索:PGroonga:テーブル定義
174
+
175
+ # coderay sql
176
+ CREATE TABLE menus (
177
+ name text -- 検索対象
178
+ );
179
+
180
+ == スライドプロパティ
181
+
182
+ : groonga-product
183
+
184
+ pgroonga
185
+
186
+ = ヨミガナ検索:PGroonga:インデックス定義
187
+
188
+ # coderay sql
189
+ CREATE INDEX menus_search ON menus
190
+ USING PGroonga (name)
191
+ WITH (tokenizer='TokenMecab("loose_reading", true)');
192
+
193
+ == スライドプロパティ
194
+
195
+ : groonga-product
196
+
197
+ pgroonga
198
+
199
+ = ヨミガナ検索:PGroonga:データ例
200
+
201
+ # coderay sql
202
+ INSERT INTO menus
203
+ VALUES ('焼肉定食'),
204
+ ('焼きにく定食');
205
+
206
+ == スライドプロパティ
207
+
208
+ : groonga-product
209
+
210
+ pgroonga
211
+
212
+ = ヨミガナ検索:PGroonga:検索
213
+
214
+ # coderay sql
215
+ SELECT name FROM menus
216
+ WHERE name &@~ '焼きにく';
217
+ -- 焼肉定食
218
+ -- 焼きにく定食
219
+
220
+ == スライドプロパティ
221
+
222
+ : groonga-product
223
+
224
+ pgroonga
225
+
226
+ = あいまい検索:表記ゆれ2
227
+
228
+ 「ぼたん鍋」\n
229
+ と\n
230
+ 「猪鍋」\n
231
+ (別名)
232
+
233
+ = あいまい検索:表記ゆれ2対策
234
+
235
+ 同義語展開
236
+
237
+ = 同義語展開
238
+
239
+ * 実行前にクエリーを変換
240
+ * 「ぼたん鍋」→「ぼたん鍋 OR 猪鍋」
241
+ * どちらもヒット
242
+ * 変換ルールは事前に用意
243
+ * ある程度自動生成可能
244
+ * 例:NEologdやWikipediaを利用
245
+
246
+ = 同義語展開:Mroonga:テーブル定義
247
+
248
+ # coderay sql
249
+ CREATE TABLE synonyms (
250
+ term varchar(255), -- 展開対象の語
251
+ synonym varchar(255), -- 同義語
252
+ INDEX (term) -- 高速化と精度向上
253
+ COMMENT 'normalizer "NormalizerNFKC100"'
254
+ ) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
255
+
256
+ == スライドプロパティ
257
+
258
+ : groonga-product
259
+
260
+ mroonga
261
+
262
+ = 同義語展開:Mroonga:データ例
263
+
264
+ # coderay sql
265
+ INSERT INTO synonyms
266
+ -- 「ぼたん鍋」を「ぼたん鍋 OR 猪鍋」に展開
267
+ VALUES ('ぼたん鍋', 'ぼたん鍋'),
268
+ ('ぼたん鍋', '猪鍋'),
269
+ -- 「猪鍋」を「猪鍋 OR ぼたん鍋」に展開
270
+ ('猪鍋', '猪鍋'),
271
+ ('猪鍋', 'ぼたん鍋');
272
+
273
+ == スライドプロパティ
274
+
275
+ : groonga-product
276
+
277
+ mroonga
278
+
279
+ = 同義語展開:Mroonga:確認方法
280
+
281
+ # coderay sql
282
+
283
+ SELECT mroonga_query_expand(
284
+ 'synonyms', -- テーブル名
285
+ 'term', -- 展開対象のカラム名
286
+ 'synonym', -- 対応する同義語のカラム名
287
+ 'ランチ ぼたん鍋' -- クエリー
288
+ );
289
+ -- 'ランチ ((ぼたん鍋) OR (猪鍋))'
290
+
291
+ == スライドプロパティ
292
+
293
+ : groonga-product
294
+
295
+ mroonga
296
+
297
+ = 同義語展開:Mroonga:検索方法
298
+
299
+ # coderay sql
300
+ SELECT title FROM entries
301
+ WHERE
302
+ MATCH (title)
303
+ -- '*D+ ランチ OR ((ぼたん鍋) OR (猪鍋))'になる
304
+ AGAINST (mroonga_query_expand('synonyms',
305
+ 'term',
306
+ 'synonym',
307
+ '*D+ ランチ ぼたん鍋')
308
+ IN BOOLEAN MODE);
309
+
310
+ == スライドプロパティ
311
+
312
+ : groonga-product
313
+
314
+ mroonga
315
+
316
+ = 同義語展開:PGroonga:テーブル定義
317
+
318
+ # coderay sql
319
+ CREATE TABLE synonyms (
320
+ -- 展開対象の語
321
+ term text,
322
+ -- 同義語のリスト
323
+ -- term自身も含める
324
+ -- 含めない場合はtermが検索禁止語になる
325
+ terms text[]
326
+ );
327
+
328
+ == スライドプロパティ
329
+
330
+ : groonga-product
331
+
332
+ pgroonga
333
+
334
+ = 同義語展開:PGroonga:データ例
335
+
336
+ # coderay sql
337
+ INSERT INTO synonyms
338
+ VALUES ('ぼたん鍋', -- 「ぼたん鍋」を展開
339
+ ARRAY['ぼたん鍋', '猪鍋']),
340
+ ('猪鍋', -- 「猪鍋」を展開
341
+ ARRAY['猪鍋', 'ぼたん鍋']);
342
+
343
+ == スライドプロパティ
344
+
345
+ : groonga-product
346
+
347
+ pgroonga
348
+
349
+ = 同義語展開:PGroonga:インデックス定義
350
+
351
+ # coderay sql
352
+ CREATE INDEX synonym_search ON synonyms
353
+ USING PGroonga
354
+ -- ...text_term_search...
355
+ -- termで完全一致検索をするため
356
+ (term pgroonga_text_term_search_ops_v2);
357
+
358
+ == スライドプロパティ
359
+
360
+ : groonga-product
361
+
362
+ pgroonga
363
+
364
+ = 同義語展開:PGroonga:確認方法
365
+
366
+ # coderay sql
367
+
368
+ SELECT pgroonga_query_expand(
369
+ 'synonyms', -- テーブル名
370
+ 'term', -- 展開対象のカラム名
371
+ 'terms', -- 対応する同義語配列のカラム名
372
+ 'ランチ ぼたん鍋' -- クエリー
373
+ );
374
+ -- 'ランチ ((ぼたん鍋) OR (猪鍋))'
375
+
376
+ == スライドプロパティ
377
+
378
+ : groonga-product
379
+
380
+ pgroonga
381
+
382
+ = 同義語展開:PGroonga:検索方法
383
+
384
+ # coderay sql
385
+ SELECT title FROM entries
386
+ WHERE
387
+ -- title &@~ ランチ ((ぼたん鍋) OR (猪鍋))'になる
388
+ title &@~
389
+ pgroonga_query_expand('synonyms',
390
+ 'term',
391
+ 'terms',
392
+ 'ランチ ぼたん鍋');
393
+
394
+ == スライドプロパティ
395
+
396
+ : groonga-product
397
+
398
+ pgroonga
399
+
400
+ = あいまい検索:表記ゆれ3
401
+
402
+ * 090-1234-5678:ハイフン入り
403
+ * (090)1234-5678:カッコとハイフン入り
404
+ * 09012345678:区切りなし
405
+ * 090 1234 5678:空白区切り
406
+ * (090)1234ー5678:全角文字入り
407
+
408
+ = あいまい検索:表記ゆれ3対策
409
+
410
+ 電話番号検索
411
+
412
+ = 電話番号検索
413
+
414
+ * 文字を正規化
415
+ * 全角→半角
416
+ * ハイフンっぽい文字→ハイフン
417
+ * 長音っぽい文字→ハイフン
418
+ * 記号・空白を無視して検索
419
+ * 元クエリー:(090)1234 5678
420
+ * 実クエリー:09012345678
421
+
422
+ = 電話番号検索:Mroonga:テーブル定義
423
+
424
+ # coderay sql
425
+ CREATE TABLE people (
426
+ tel varchar(255), -- 検索対象
427
+ FULLTEXT INDEX (tel) COMMENT
428
+ -- 電話番号検索対応インデックス
429
+ 'normalizer "NormalizerNFKC100(
430
+ \'unify_hyphen_and_prolonged_sound_mark\', true)",
431
+ tokenizer "TokenNgram(\'loose_symbol\', true,
432
+ \'loose_blank\', true)"'
433
+ ) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
434
+
435
+ == スライドプロパティ
436
+
437
+ : groonga-product
438
+
439
+ mroonga
440
+
441
+ = 電話番号検索:Mroonga:データ例
442
+
443
+ # coderay sql
444
+ INSERT INTO people
445
+ VALUES ('090-1234-5678'),
446
+ ('(090)1234-5678'),
447
+ ('09012345678'),
448
+ ('090 1234 5678'),
449
+ ('(090)1234ー5678');
450
+
451
+ == スライドプロパティ
452
+
453
+ : groonga-product
454
+
455
+ mroonga
456
+
457
+ = 電話番号検索:Mroonga:検索
458
+
459
+ # coderay sql
460
+ SELECT tel FROM people
461
+ WHERE MATCH (tel)
462
+ AGAINST ('*D+ 090ー12345678' IN BOOLEAN MODE);
463
+ -- 090-1234-5678
464
+ -- (090)1234-5678
465
+ -- 09012345678
466
+ -- 090 1234 5678
467
+ -- (090)1234ー5678
468
+
469
+ == スライドプロパティ
470
+
471
+ : groonga-product
472
+
473
+ mroonga
474
+
475
+ = 電話番号検索:PGroonga:テーブル定義
476
+
477
+ # coderay sql
478
+ CREATE TABLE people (
479
+ tel text -- 検索対象
480
+ );
481
+
482
+ == スライドプロパティ
483
+
484
+ : groonga-product
485
+
486
+ pgroonga
487
+
488
+ = 電話番号検索:PGroonga:インデックス定義
489
+
490
+ # coderay sql
491
+ CREATE INDEX people_search ON people
492
+ USING PGroonga (tel)
493
+ WITH (normalizer='
494
+ NormalizerNFKC100("unify_hyphen_and_prolonged_sound_mark", true)',
495
+ tokenizer='TokenNgram("loose_symbol", true,
496
+ "loose_blank", true)');
497
+
498
+ == スライドプロパティ
499
+
500
+ : groonga-product
501
+
502
+ pgroonga
503
+
504
+ = 電話番号検索:PGroonga:データ例
505
+
506
+ # coderay sql
507
+ INSERT INTO people
508
+ VALUES ('090-1234-5678'),
509
+ ('(090)1234-5678'),
510
+ ('09012345678'),
511
+ ('090 1234 5678'),
512
+ ('(090)1234ー5678');
513
+
514
+ == スライドプロパティ
515
+
516
+ : groonga-product
517
+
518
+ pgroonga
519
+
520
+ = 電話番号検索:PGroonga:検索
521
+
522
+ # coderay sql
523
+ SELECT tel FROM people
524
+ WHERE tel &@~ '090ー12345678';
525
+ -- 090-1234-5678
526
+ -- (090)1234-5678
527
+ -- 09012345678
528
+ -- 090 1234 5678
529
+ -- (090)1234ー5678
530
+
531
+ == スライドプロパティ
532
+
533
+ : groonga-product
534
+
535
+ pgroonga
536
+
537
+ = あいまい検索:表記ゆれ4
538
+
539
+ (('note:sèvre-et-maine'))
540
+
541
+ * セーヴェル エ メーヌ\n
542
+ (('note:「ーヴェ」・空白区切り'))
543
+ * セブルエメーヌ\n
544
+ (('note:「ブ」・区切りなし'))
545
+ * セーブル・エ・メーヌ\n
546
+ (('note:「ーブ」・中点区切り'))
547
+ * セーヴル エメーヌ\n
548
+ (('note:「ーヴ」・片方だけ空白区切り'))
549
+
550
+ = あいまい検索:表記ゆれ4対策
551
+
552
+ ワイン名検索
553
+
554
+ = ワイン名検索
555
+
556
+ * 文字を正規化
557
+ * ヴ・ヴェ→ブ
558
+ * ハイフン・長音っぽい文字→ハイフン
559
+ * 中点っぽい文字→中点
560
+ * 記号・空白を無視して検索
561
+ * 元クエリー:セーヴェル・エメーヌ
562
+ * 実クエリー:セブルエメヌ
563
+
564
+ = ワイン名検索:Mroonga:テーブル定義
565
+
566
+ # coderay sql
567
+ CREATE TABLE wines (
568
+ name varchar(255), -- 検索対象
569
+ FULLTEXT INDEX (name) COMMENT
570
+ -- ワイン名検索対応インデックス
571
+ 'normalizer "NormalizerNFKC100(
572
+ \'unify_katakana_bu_sound\', true,
573
+ \'unify_hyphen_and_prolonged_sound_mark\', true,
574
+ \'unify_middle_dot\', true)",
575
+ tokenizer "TokenNgram(\'loose_symbol\', true,
576
+ \'loose_blank\', true)"'
577
+ ) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
578
+
579
+ == スライドプロパティ
580
+
581
+ : groonga-product
582
+
583
+ mroonga
584
+
585
+ = ワイン名検索:Mroonga:データ例
586
+
587
+ # coderay sql
588
+ INSERT INTO wines
589
+ VALUES ('セーヴェル エ メーヌ'),
590
+ ('セブルエメーヌ'),
591
+ ('セーブル・エ・メーヌ'),
592
+ ('セーヴル エメーヌ');
593
+
594
+ == スライドプロパティ
595
+
596
+ : groonga-product
597
+
598
+ mroonga
599
+
600
+ = ワイン名検索:Mroonga:検索
601
+
602
+ # coderay sql
603
+ SELECT name FROM wines
604
+ WHERE MATCH (name)
605
+ AGAINST ('*D+ セーヴェルエメーヌ' IN BOOLEAN MODE);
606
+ -- セーヴェル エ メーヌ
607
+ -- セブルエメーヌ
608
+ -- セーブル・エ・メーヌ
609
+ -- セーヴル エメーヌ
610
+
611
+ == スライドプロパティ
612
+
613
+ : groonga-product
614
+
615
+ mroonga
616
+
617
+ = ワイン名検索:PGroonga:テーブル定義
618
+
619
+ # coderay sql
620
+ CREATE TABLE wines (
621
+ name text -- 検索対象
622
+ );
623
+
624
+ == スライドプロパティ
625
+
626
+ : groonga-product
627
+
628
+ pgroonga
629
+
630
+ = ワイン名検索:PGroonga:インデックス定義
631
+
632
+ # coderay sql
633
+ CREATE INDEX wines_search ON wines
634
+ USING PGroonga (name)
635
+ WITH (normalizer='NormalizerNFKC100(
636
+ "unify_katakana_bu_sound", true,
637
+ "unify_hyphen_and_prolonged_sound_mark", true,
638
+ "unify_middle_dot", true)',
639
+ tokenizer='TokenNgram("loose_symbol", true,
640
+ "loose_blank", true)');
641
+
642
+ == スライドプロパティ
643
+
644
+ : groonga-product
645
+
646
+ pgroonga
647
+
648
+ = ワイン名検索:PGroonga:データ例
649
+
650
+ # coderay sql
651
+ INSERT INTO wines
652
+ VALUES ('セーヴェル エ メーヌ'),
653
+ ('セブルエメーヌ'),
654
+ ('セーブル・エ・メーヌ'),
655
+ ('セーヴル エメーヌ');
656
+
657
+ == スライドプロパティ
658
+
659
+ : groonga-product
660
+
661
+ pgroonga
662
+
663
+ = ワイン名検索:PGroonga:検索
664
+
665
+ # coderay sql
666
+ SELECT name FROM wines
667
+ WHERE name &@~ 'セーヴェルエメーヌ';
668
+ -- セーヴェル エ メーヌ
669
+ -- セブルエメーヌ
670
+ -- セーブル・エ・メーヌ
671
+ -- セーヴル エメーヌ
672
+
673
+ == スライドプロパティ
674
+
675
+ : groonga-product
676
+
677
+ pgroonga
678
+
679
+ = 表記ゆれ:まとめ
680
+
681
+ * ヨミガナ検索
682
+ * 漢字・送り仮名の違いを吸収
683
+ * 同義語展開:別名をカバー
684
+ * 電話番号検索
685
+ * 半角全角・記号の有無・記号の違いを吸収
686
+ * ワイン名検索
687
+ * 外来語のカタカナ表記の違いを吸収
688
+
689
+ = 表記ゆれ:参考情報
690
+
691
+ 文字の正規化方法
692
+
693
+ = 正規化:かなの同一視
694
+
695
+ * (({unify_kana}))
696
+ * ひらがなとカタカナを区別しない
697
+ * ↓は同じ
698
+ * あいうえお
699
+ * アイウエオ
700
+
701
+ = 正規化:濁点の同一視
702
+
703
+ * (({unify_sound_mark}))
704
+ * 濁点・半濁点の有無を区別しない
705
+ * ↓は同じ
706
+ * はひふへほ
707
+ * ばびぶべぼ
708
+ * ぱぴぷぺぽ
709
+
710
+ = 正規化:大文字・小文字の同一視
711
+
712
+ * (({unify_kana_case}))
713
+ * 大文字・小文字を区別しない
714
+ * ↓は同じ
715
+ * やゆよ
716
+ * ゃゅょ
717
+
718
+ = 正規化:ハイフンっぽい文字の同一視
719
+
720
+ * (({unify_hyphen}))
721
+ * ハイフンっぽい文字をハイフンへ
722
+ * ハイフン:U+002D
723
+ * ハイフンっぽい文字:
724
+ * -˗֊‐‑‒–⁃⁻₋−
725
+
726
+ = 正規化:長音記号っぽい文字の同一視
727
+
728
+ * (({unify_prolonged_sound_mark}))
729
+ * 長音記号っぽい文字を長音記号へ
730
+ * 長音記号:U+30FC
731
+ * 長音記号っぽい文字:
732
+ * ー—―─━ー
733
+
734
+ = 正規化:ハイフン・長音記号っぽい文字
735
+
736
+ * (({unify_hyphen_and_prolonged_sound_mark}))
737
+ * ハイフン・長音記号っぽい文字を\n
738
+ ハイフン(U+002D)へ
739
+ * ハイフンっぽい文字:
740
+ * -˗֊‐‑‒–⁃⁻₋−
741
+ * 長音記号っぽい文字:
742
+ * ー—―─━ー
743
+
744
+ = 正規化:中点っぽい文字の同一視
745
+
746
+ * (({unify_middle_dot}))
747
+ * 中点っぽい文字を中点へ
748
+ * 中点:U+00B7
749
+ * 中点っぽい文字
750
+ * ·ᐧ•∙⋅⸱・・
751
+
752
+ = 正規化:ヴァ→バ
753
+
754
+ * (({unify_katakana_v_sounds}))
755
+ * ヴァ行をバ行へ
756
+ * ↓は同じ
757
+ * ヴァヴィヴヴェヴォ
758
+ * バビブベボ
759
+
760
+ = 正規化:ヴァ行→ブ
761
+
762
+ * (({unify_katakana_bu_sound}))
763
+ * ヴァ行をブへ
764
+ * ↓は同じ
765
+ * ヴァヴィヴヴェヴォ
766
+ * ブブブブブ
767
+
768
+ = 正規化:MySQL 8.0
769
+
770
+ * 日本語用COLLATIONを追加
771
+ * (({utf8mb4_ja_0900_as_cs}))
772
+ * COLLATION:文字の順序のルール
773
+ * 順序なので等価比較機能もある
774
+ * 最新Mroongaは対応済み
775
+
776
+ = あいまい検索:typo
777
+
778
+ テノクロジー
779
+
780
+ = あいまい検索:typo対策
781
+
782
+ fuzzy検索
783
+
784
+ = fuzzy検索
785
+
786
+ * 似ている文字列を検索
787
+ * 似ている=編集距離が小さい
788
+ * インデックスを使って検索
789
+
790
+ = 編集距離
791
+
792
+ * Aを何回編集するとBになるか
793
+ * 編集:
794
+ * 挿入・削除・置換
795
+ * 置換を禁止するケースもある
796
+ * 編集回数が距離
797
+
798
+ = 編集距離例:置換あり
799
+
800
+ * A:テノクロジー
801
+ * 置換:ク↔ノ
802
+ * B:テクノロジー
803
+
804
+ (('tag:center'))
805
+ (('tag:x-large'))
806
+ 編集距離:1
807
+
808
+ = 編集距離例:置換なし
809
+
810
+ * A:テノクロジー
811
+ * 削除:ク:テノロジー
812
+ * 挿入:ノ:テク((*ノ*))ロジー
813
+ * B:テクノロジー
814
+
815
+ (('tag:center'))
816
+ (('tag:x-large'))
817
+ 編集距離:2
818
+
819
+ = fuzzy検索:Mroonga:テーブル定義
820
+
821
+ # coderay sql
822
+ CREATE TABLE tags (
823
+ name varchar(255), -- 検索対象
824
+ FULLTEXT INDEX (name) -- fuzzy検索対応インデックス
825
+ COMMENT 'tokenizer "none"'
826
+ ) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
827
+
828
+ == スライドプロパティ
829
+
830
+ : groonga-product
831
+
832
+ mroonga
833
+
834
+ = fuzzy検索:Mroonga:データ例
835
+
836
+ # coderay sql
837
+ INSERT INTO tags
838
+ VALUES ('テクノロジー'),
839
+ ('テクニカル');
840
+
841
+ == スライドプロパティ
842
+
843
+ : groonga-product
844
+
845
+ mroonga
846
+
847
+ = fuzzy検索:Mroonga:検索
848
+
849
+ # coderay sql
850
+ SELECT name,
851
+ MATCH(name) AGAINST(...↓と同じ内容...) AS score
852
+ FROM tags
853
+ WHERE MATCH (name)
854
+ AGAINST (CONCAT('*SS fuzzy_search(name, ',
855
+ mroonga_escape('テノクロジー' AS script),
856
+ ', ',
857
+ '{"with_transposition": true,
858
+ "max_distance": 4})')
859
+ IN BOOLEAN MODE);
860
+ -- テクノロジー | 4
861
+ -- テクニカル | 1
862
+
863
+ == スライドプロパティ
864
+
865
+ : groonga-product
866
+
867
+ mroonga
868
+
869
+ = fuzzy検索:PGroonga:テーブル定義
870
+
871
+ # coderay sql
872
+ CREATE TABLE tags (
873
+ name text -- 検索対象
874
+ );
875
+
876
+ == スライドプロパティ
877
+
878
+ : groonga-product
879
+
880
+ pgroonga
881
+
882
+ = fuzzy検索:PGroonga:インデックス定義
883
+
884
+ # coderay sql
885
+ CREATE INDEX tags_search ON tags
886
+ USING PGroonga (name)
887
+ WITH (tokenizer='');
888
+
889
+ == スライドプロパティ
890
+
891
+ : groonga-product
892
+
893
+ pgroonga
894
+
895
+ = fuzzy検索:PGroonga:データ例
896
+
897
+ # coderay sql
898
+ INSERT INTO tags
899
+ VALUES ('テクノロジー'),
900
+ ('テクニカル');
901
+
902
+ == スライドプロパティ
903
+
904
+ : groonga-product
905
+
906
+ pgroonga
907
+
908
+ = fuzzy検索:PGroonga:検索
909
+
910
+ # coderay sql
911
+ SELECT name, pgroonga_score(tableoid, ctid)
912
+ FROM tags
913
+ WHERE name &`
914
+ ('fuzzy_search(name, ' ||
915
+ pgroonga_escape('テノクロジー') || ',
916
+ {"with_transposition": true,
917
+ "max_distance": 4})');
918
+ -- テクノロジー | 4
919
+ -- テクニカル | 1
920
+
921
+ == スライドプロパティ
922
+
923
+ : groonga-product
924
+
925
+ pgroonga
926
+
927
+ = まとめ:あいまいな情報
928
+
929
+ * 人が用意した情報はあいまい
930
+ * クエリーも検索対象も
931
+ * あいまいでも必要な文書を見つける
932
+ * 人よりも機械ががんばる
933
+
934
+ = まとめ:あいまいな検索
935
+
936
+ * 全文検索エンジンを活用して実現
937
+ * あいまい検索機能を提供しているはず
938
+
939
+ = まとめ:全文検索エンジン
940
+
941
+ * 普通の全文検索エンジン
942
+ * 独自の使い方
943
+ * Mroonga・PGroonga
944
+ * ((*SQL*))で使える→開発しやすい
945
+
946
+ = まとめ:ヨミガナ検索
947
+
948
+ * 漢字・送り仮名の違いを吸収
949
+ * 焼肉・焼き肉・焼きにく
950
+ * 高橋・髙橋
951
+ * MeCabで自動化できる
952
+ * 辞書により失敗することはある
953
+ * 同義語には対応できない
954
+ * 同義語展開と併用
955
+
956
+ = まとめ:同義語展開
957
+
958
+ * 別名に対応:「ぼたん鍋」と「猪鍋」
959
+ * なにを同義語とするかが難しい
960
+ * システム依存度が高い
961
+ * ある程度は自動化できる
962
+ * 手動でのメンテナンスも必要
963
+
964
+ = まとめ:電話番号検索
965
+
966
+ * 半角全角・記号有無・記号違いを吸収
967
+ * 🐀注意🐀
968
+ * どんな検索対象でもゆるくてよいわけではない
969
+ * 誤ヒットも増えてしまう
970
+ * 電話番号ならここまでゆるくてもOKというだけ
971
+
972
+ = まとめ:ワイン名検索
973
+
974
+ * 外来語のカタカナ表記の違いを吸収
975
+ * 🐀注意🐀
976
+ * どんな検索対象でもゆるくてよいわけではない
977
+ * 誤ヒットも増えてしまう
978
+ * ワイン名ならここまでゆるくてもOKというだけ
979
+
980
+ = まとめ:fuzzy検索
981
+
982
+ * typoしても本来のキーワードを推測
983
+ * 活用方法:
984
+ * ヒットしなかったときの「もしかして」の実装
985
+ * 入力補完候補
986
+
987
+ = 参考情報:リッチな全文検索システム
988
+
989
+ # image
990
+ # src = https://slide.rabbit-shocker.org/authors/kou/db-tech-showcase-tokyo-2017/mysql-postgresql-rich-full-text-search-system.pdf
991
+ # page = 1
992
+ # relative_height = 90
993
+
994
+ (('tag:xx-small'))
995
+ (('tag:center'))
996
+ ((<URL:https://slide.rabbit-shocker.org/authors/kou/db-tech-showcase-tokyo-2017/>))
997
+
998
+ = 扱わなかったあいまい検索
999
+
1000
+ * 近傍検索\n
1001
+ (('note:指定したキーワード間に違う単語が含まれていてもマッチ'))
1002
+ * 「みそラーメン」で検索:
1003
+ * 「みそバターラーメン」:マッチ
1004
+ * quorumマッチ\n
1005
+ (('note:閾値以上の要素がマッチしたらマッチ'))
1006
+ * 閾値2と「MySQL MariaDB Percona」で検索:
1007
+ * 「MySQLとMariaDBの比較」:マッチ
1008
+ * 「MySQLとPostgreSQLの比較」:マッチしない
1009
+
1010
+ = 扱わなかった話題
1011
+
1012
+ * 運用について
1013
+ * 障害対策・レプリケーション
1014
+ * チューニング
1015
+
1016
+ = サポートサービス紹介
1017
+
1018
+ * 導入支援(('note:(設計支援・性能検証・移行支援・…)'))
1019
+ * 開発支援(('note:(サンプルコード提供・問い合わせ対応・…)'))
1020
+ * 運用支援(('note:(障害対応・チューニング支援・…)'))
1021
+
1022
+ 問い合わせ先:
1023
+
1024
+ (('tag:x-small'))
1025
+ ((<URL:https://www.clear-code.com/contact/?type=groonga>))
@@ -0,0 +1,3 @@
1
+ @title_slide_title_font_size = @normal_font_size
2
+
3
+ include_theme("groonga")
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rabbit-slide-kou-db-tech-showcase-tokyo-2018
3
+ version: !ruby/object:Gem::Version
4
+ version: 2018.9.20.0
5
+ platform: ruby
6
+ authors:
7
+ - 須藤功平
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-09-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rabbit
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: rabbit-theme-groonga
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: |-
42
+ ナイーブな全文検索は単なる中間一致検索です。しかし、現実に人が入力するテキストは揺れまくっているので単なる中間一致検索では必要な情報を見つけられません。たとえば、「(090)1234-5678」も「090ー1234ー5678」も「09012345678」もすべて同じ電話番号として扱いたいのが現実です。
43
+
44
+ MySQLとPostgreSQLの全文検索機能ではこのようにゆるい全文検索を高速に実現することができません。そこでMroonga・PGroongaです。Mroonga・PGroongaを使ってMySQL・PostgreSQLだけで高速にゆるく全文検索する方法を紹介します。
45
+ email:
46
+ - kou@clear-code.com
47
+ executables: []
48
+ extensions: []
49
+ extra_rdoc_files: []
50
+ files:
51
+ - ".rabbit"
52
+ - README.rd
53
+ - Rakefile
54
+ - config.yaml
55
+ - mysql-postgresql-fast-fuzzy-full-text-search-system.rab
56
+ - pdf/db-tech-showcase-tokyo-2018-mysql-postgresql-fast-fuzzy-full-text-search-system.pdf
57
+ - theme.rb
58
+ homepage: http://slide.rabbit-shocker.org/authors/kou/db-tech-showcase-tokyo-2018/
59
+ licenses:
60
+ - CC-BY-SA-4.0
61
+ - CC-BY-3.0
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 3.0.0.beta1
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: MySQL・PostgreSQLだけで作る高速あいまい全文検索システム
83
+ test_files: []