rabbit-slide-komainu8-postgresql-conference-japan-2021 1.0.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.
- checksums.yaml +7 -0
- data/.rabbit +1 -0
- data/README.rd +42 -0
- data/Rakefile +17 -0
- data/config.yaml +31 -0
- data/images/normalizer.png +0 -0
- data/images/precision-expression.png +0 -0
- data/images/precision-hight-recall-low.png +0 -0
- data/images/precision-low-recall-hight.png +0 -0
- data/images/precision-recall-1.png +0 -0
- data/images/recall-expression.png +0 -0
- data/images/search-result-01.png +0 -0
- data/images/self-introduction.png +0 -0
- data/images/tokenizer-tokenmecab.png +0 -0
- data/images/tokenizer.png +0 -0
- data/improve-search-result-with-pgroonga-overview.rab +520 -0
- data/improve-search-result-with-pgroonga.rab +797 -0
- data/pdf/postgresql-conference-japan-2021-improve-search-result-with-pgroonga.pdf +0 -0
- data/theme.rb +5 -0
- metadata +86 -0
@@ -0,0 +1,797 @@
|
|
1
|
+
= PGroongaを使って\n全文検索結果を\nより良くする方法
|
2
|
+
|
3
|
+
: author
|
4
|
+
堀本 泰弘
|
5
|
+
: institution
|
6
|
+
株式会社クリアコード
|
7
|
+
: content-source
|
8
|
+
PostgreSQL Conference Japan 2021
|
9
|
+
: date
|
10
|
+
2021-11-12
|
11
|
+
: allotted-time
|
12
|
+
45m
|
13
|
+
: start-time
|
14
|
+
2021-11-12T16:10:00+09:00
|
15
|
+
: end-time
|
16
|
+
2021-11-12T16:55:00+09:00
|
17
|
+
: theme
|
18
|
+
.
|
19
|
+
|
20
|
+
= 自己紹介
|
21
|
+
|
22
|
+
# image
|
23
|
+
# src = images/self-introduction.png
|
24
|
+
# relative_height = 107
|
25
|
+
|
26
|
+
= 今日のテーマ
|
27
|
+
|
28
|
+
検索結果の改善
|
29
|
+
|
30
|
+
= 目次
|
31
|
+
|
32
|
+
(1) 検索結果の評価指標
|
33
|
+
(2) PGrooongaで検索結果の改善
|
34
|
+
|
35
|
+
= 検索結果の評価指標
|
36
|
+
|
37
|
+
よく検索結果が\n
|
38
|
+
((*いまいち*))だ...\n
|
39
|
+
という話を\n聞きます
|
40
|
+
|
41
|
+
= 検索結果の評価指標
|
42
|
+
|
43
|
+
# image
|
44
|
+
# src = images/search-result-01.png
|
45
|
+
# relative_height = 100
|
46
|
+
|
47
|
+
= いまいちな検索結果
|
48
|
+
|
49
|
+
* 😞検索漏れ
|
50
|
+
* 😞ノイズが多い
|
51
|
+
* 😞有用な情報を探し出せない
|
52
|
+
|
53
|
+
= 検索結果の評価指標
|
54
|
+
|
55
|
+
(1) 適合率
|
56
|
+
(2) 再現率
|
57
|
+
(3) ランキング
|
58
|
+
|
59
|
+
= 適合率
|
60
|
+
|
61
|
+
# image
|
62
|
+
# src = images/precision-expression.png
|
63
|
+
# relative_height = 55
|
64
|
+
|
65
|
+
= 再現率
|
66
|
+
|
67
|
+
# image
|
68
|
+
# src = images/recall-expression.png
|
69
|
+
# relative_height = 60
|
70
|
+
|
71
|
+
= 適合率と再現率
|
72
|
+
|
73
|
+
具体例
|
74
|
+
|
75
|
+
= 適合率と再現率
|
76
|
+
|
77
|
+
Wikipediaで\n"キログラムの\n定義"を調べる
|
78
|
+
|
79
|
+
= 適合率と再現率
|
80
|
+
|
81
|
+
# coderay sql
|
82
|
+
|
83
|
+
SELECT title FROM wikipedia where text &@~ 'キログラム 定義';
|
84
|
+
title
|
85
|
+
--------------------------------------------------------
|
86
|
+
水
|
87
|
+
力
|
88
|
+
国際単位系
|
89
|
+
.
|
90
|
+
.
|
91
|
+
.
|
92
|
+
キログラム
|
93
|
+
.
|
94
|
+
.
|
95
|
+
.
|
96
|
+
(229 rows)
|
97
|
+
|
98
|
+
= 適合率と再現率
|
99
|
+
|
100
|
+
適合率\n
|
101
|
+
2/229=0.87%
|
102
|
+
|
103
|
+
= 適合率と再現率
|
104
|
+
|
105
|
+
*ヒットしなかったけど\n欲しかった記事
|
106
|
+
|
107
|
+
* SI基本単位の再定義
|
108
|
+
* 国際キログラム原器
|
109
|
+
|
110
|
+
= 適合率と再現率
|
111
|
+
|
112
|
+
再現率\n
|
113
|
+
2/4=50.0%
|
114
|
+
|
115
|
+
= 適合率と再現率の重要度
|
116
|
+
|
117
|
+
Web検索\n
|
118
|
+
適合率 > 再現率
|
119
|
+
|
120
|
+
= 適合率と再現率の重要度
|
121
|
+
|
122
|
+
特許検索\n
|
123
|
+
適合率 < 再現率
|
124
|
+
|
125
|
+
= ランキング
|
126
|
+
|
127
|
+
検索結果の順序
|
128
|
+
|
129
|
+
= ランキング
|
130
|
+
|
131
|
+
ユーザーは\n((*上位数件*))\nしか見ない
|
132
|
+
|
133
|
+
= PGroongaで検索結果の改善
|
134
|
+
|
135
|
+
* PGroongaで適合率/再現率改善
|
136
|
+
|
137
|
+
* ノーマライザーを使う
|
138
|
+
* トークナイザーを使う
|
139
|
+
* ステミングを使う
|
140
|
+
* fuzzy検索を使う
|
141
|
+
* 同義語展開を使う
|
142
|
+
|
143
|
+
= PGroongaで検索結果の改善
|
144
|
+
|
145
|
+
* PGroongaでランキング改善
|
146
|
+
|
147
|
+
* スコアラーを使う
|
148
|
+
|
149
|
+
= ノーマライズ
|
150
|
+
|
151
|
+
ノーマライズ\n(正規化)とは?
|
152
|
+
|
153
|
+
= ノーマライズ
|
154
|
+
|
155
|
+
# image
|
156
|
+
# src = images/normalizer.png
|
157
|
+
# relative_height = 90
|
158
|
+
|
159
|
+
= ノーマライズ
|
160
|
+
|
161
|
+
例) カタカナをひらがなに正規化
|
162
|
+
|
163
|
+
* きろぐらむ -> きろぐらむ
|
164
|
+
* キログラム -> きろぐらむ
|
165
|
+
|
166
|
+
= PGroongaのノーマライザー\n(デフォルト)
|
167
|
+
|
168
|
+
# coderay sql
|
169
|
+
|
170
|
+
CREATE TABLE normalizer_test (
|
171
|
+
id integer,
|
172
|
+
content text
|
173
|
+
);
|
174
|
+
|
175
|
+
CREATE INDEX pgroonga_content_index ON normalizer_test USING pgroonga (content);
|
176
|
+
|
177
|
+
INSERT INTO normalizer_test VALUES (1, 'キログラム');
|
178
|
+
INSERT INTO normalizer_test VALUES (2, 'きろぐらむ');
|
179
|
+
INSERT INTO normalizer_test VALUES (3, '㌕');
|
180
|
+
INSERT INTO normalizer_test VALUES (4, 'キログラム');
|
181
|
+
INSERT INTO normalizer_test VALUES (5, 'kiroguramu');
|
182
|
+
INSERT INTO normalizer_test VALUES (6, 'kiroguramu');
|
183
|
+
|
184
|
+
SELECT * FROM normalizer_test WHERE content &@ 'kiroguramu';
|
185
|
+
|
186
|
+
= PGroongaのノーマライザー\n(デフォルト)
|
187
|
+
|
188
|
+
# coderay sql
|
189
|
+
|
190
|
+
SELECT * FROM normalizer_test WHERE content &@ 'kiroguramu';
|
191
|
+
id | content
|
192
|
+
----+----------------------
|
193
|
+
5 | kiroguramu
|
194
|
+
6 | kiroguramu
|
195
|
+
(2 rows)
|
196
|
+
|
197
|
+
= PGroongaのノーマライザー\n(デフォルト)
|
198
|
+
|
199
|
+
* kiroguramu
|
200
|
+
↓
|
201
|
+
* kiroguramu
|
202
|
+
|
203
|
+
= PGroongaのノーマライザー\n(デフォルト)
|
204
|
+
|
205
|
+
* NFKCを使った正規化
|
206
|
+
* テキストエンコードがUTF-8の場合
|
207
|
+
|
208
|
+
= PostgreSQLのノーマライザー\n(デフォルト)
|
209
|
+
|
210
|
+
# coderay sql
|
211
|
+
|
212
|
+
SELECT * FROM normalizer_test
|
213
|
+
WHERE content = (SELECT normalize('kiroguramu', NFKC));
|
214
|
+
id | content
|
215
|
+
----+------------
|
216
|
+
5 | kiroguramu
|
217
|
+
(1 row)
|
218
|
+
|
219
|
+
= ノーマライザーの変更
|
220
|
+
|
221
|
+
適合率/再現率を上げたい
|
222
|
+
|
223
|
+
= PGroongaのノーマライザー\n(NormalizerNFKC130)
|
224
|
+
|
225
|
+
# coderay sql
|
226
|
+
|
227
|
+
DROP INDEX pgroonga_content_index;
|
228
|
+
|
229
|
+
CREATE INDEX pgroonga_content_index
|
230
|
+
ON normalizer_test
|
231
|
+
USING pgroonga (content)
|
232
|
+
WITH (normalizers='NormalizerNFKC130("unify_to_romaji", true)');
|
233
|
+
|
234
|
+
SELECT * FROM normalizer_test WHERE content &@ 'kiroguramu';
|
235
|
+
|
236
|
+
= PGroongaのノーマライザー\n(NormalizerNFKC130)
|
237
|
+
|
238
|
+
# coderay sql
|
239
|
+
|
240
|
+
SELECT * FROM normalizer_test WHERE content &@ 'kiroguramu';
|
241
|
+
id | content
|
242
|
+
----+----------------------
|
243
|
+
1 | キログラム
|
244
|
+
2 | きろぐらむ
|
245
|
+
3 | ㌕
|
246
|
+
4 | キログラム
|
247
|
+
5 | kiroguramu
|
248
|
+
6 | kiroguramu
|
249
|
+
(6 rows)
|
250
|
+
|
251
|
+
= PGroongaのノーマライザー\n(NormalizerNFKC130)
|
252
|
+
|
253
|
+
* unify_to_romaji
|
254
|
+
|
255
|
+
* ローマ字に正規化\nローマ字で読んだときに同じ語は同一視する
|
256
|
+
* (e.g. 「kiroguramu」と「きろぐらむ」を同一視。ローマ字読みが同じだから)
|
257
|
+
|
258
|
+
= オプションの指定方法
|
259
|
+
|
260
|
+
# coderay sql
|
261
|
+
|
262
|
+
CREATE INDEX pgroonga_content_index
|
263
|
+
ON normalizer_test
|
264
|
+
USING pgroonga (content)
|
265
|
+
WITH (normalizers='NormalizerNFKC130("unify_to_romaji", true)');
|
266
|
+
|
267
|
+
= 複数オプションの指定方法
|
268
|
+
|
269
|
+
# coderay sql
|
270
|
+
|
271
|
+
CREATE INDEX pgroonga_content_index
|
272
|
+
ON normalizer_test
|
273
|
+
USING pgroonga (content)
|
274
|
+
WITH (normalizers='NormalizerNFKC130("unify_to_romaji", true,
|
275
|
+
"unify_hyphen", true)');
|
276
|
+
|
277
|
+
= 指定可能オプション一覧
|
278
|
+
|
279
|
+
* NormalizerNFKC130の\nオプション一覧
|
280
|
+
* ((<URL:https://groonga.org/ja/docs/reference/normalizers/normalizer_nfkc130.html#syntax>))
|
281
|
+
|
282
|
+
= トークナイズ
|
283
|
+
|
284
|
+
# image
|
285
|
+
# src = images/tokenizer.png
|
286
|
+
# relative_height = 80
|
287
|
+
|
288
|
+
= PGroongaのトークナイザー\n(デフォルト)
|
289
|
+
|
290
|
+
# coderay sql
|
291
|
+
|
292
|
+
CREATE TABLE tokenizer_test (
|
293
|
+
title text
|
294
|
+
);
|
295
|
+
CREATE INDEX pgroonga_content_index ON tokenizer_test USING pgroonga (title);
|
296
|
+
|
297
|
+
INSERT INTO tokenizer_test VALUES ('京都府 1日目 金閣寺');
|
298
|
+
INSERT INTO tokenizer_test VALUES ('京都府 2日目 嵐山');
|
299
|
+
INSERT INTO tokenizer_test VALUES ('京都府 3日目 天橋立');
|
300
|
+
INSERT INTO tokenizer_test VALUES ('東京都 1日目 スカイツリー');
|
301
|
+
INSERT INTO tokenizer_test VALUES ('東京都 2日目 浅草寺');
|
302
|
+
INSERT INTO tokenizer_test VALUES ('北海道 1日目 函館');
|
303
|
+
INSERT INTO tokenizer_test VALUES ('北海道 2日目 トマム');
|
304
|
+
INSERT INTO tokenizer_test VALUES ('北海道 3日目 富良野');
|
305
|
+
INSERT INTO tokenizer_test VALUES ('北海道 4日目 美瑛');
|
306
|
+
INSERT INTO tokenizer_test VALUES ('北海道 5日目 旭川');
|
307
|
+
|
308
|
+
SELECT * FROM tokenizer_test WHERE title &@~ '京都';
|
309
|
+
|
310
|
+
= PGroongaのトークナイザー\n(デフォルト)
|
311
|
+
|
312
|
+
# coderay sql
|
313
|
+
|
314
|
+
SELECT * FROM tokenizer_test WHERE title &@~ '京都';
|
315
|
+
title
|
316
|
+
--------------------------------------
|
317
|
+
京都府 1日目 金閣寺
|
318
|
+
京都府 2日目 嵐山
|
319
|
+
京都府 3日目 天橋立
|
320
|
+
東京都 1日目 スカイツリー
|
321
|
+
東京都 2日目 浅草寺
|
322
|
+
(5 rows)
|
323
|
+
|
324
|
+
= トークナイザーの変更
|
325
|
+
|
326
|
+
適合率を上げたい
|
327
|
+
|
328
|
+
= PGroongaのトークナイザー\n(TokenMecab)
|
329
|
+
|
330
|
+
# coderay sql
|
331
|
+
|
332
|
+
CREATE INDEX pgroonga_content_index
|
333
|
+
ON tokenizer_test
|
334
|
+
USING pgroonga (title)
|
335
|
+
WITH (tokenizer='TokenMecab');
|
336
|
+
|
337
|
+
SELECT * FROM tokenizer_test WHERE title &@~ '京都';
|
338
|
+
|
339
|
+
= PGroongaのトークナイザー\n(TokenMecab)
|
340
|
+
|
341
|
+
# coderay sql
|
342
|
+
|
343
|
+
SELECT * FROM tokenizer_test WHERE title &@~ '京都';
|
344
|
+
title
|
345
|
+
--------------------------------------
|
346
|
+
京都府 1日目 金閣寺
|
347
|
+
京都府 2日目 嵐山
|
348
|
+
京都府 3日目 天橋立
|
349
|
+
(3 rows)
|
350
|
+
|
351
|
+
= PGroongaのトークナイザー\n(TokenMecab)
|
352
|
+
|
353
|
+
# image
|
354
|
+
# src = images/tokenizer-tokenmecab.png
|
355
|
+
# relative_height = 80
|
356
|
+
|
357
|
+
= トークナイザーの指定方法
|
358
|
+
|
359
|
+
# coderay sql
|
360
|
+
|
361
|
+
CREATE INDEX pgroonga_content_index
|
362
|
+
ON tokenizer_test
|
363
|
+
USING pgroonga (title)
|
364
|
+
WITH (tokenizer='TokenMecab');
|
365
|
+
|
366
|
+
= 指定可能トークナイザー一覧
|
367
|
+
|
368
|
+
* 使用可能なトークナイザー
|
369
|
+
* ((<URL:https://groonga.org/ja/docs/reference/tokenizers.html>))
|
370
|
+
|
371
|
+
= ステミング(語幹処理)
|
372
|
+
|
373
|
+
意味は同じだが\n語の形が変わる\n(語形変化)
|
374
|
+
|
375
|
+
= ステミング(語幹処理)
|
376
|
+
|
377
|
+
例えば
|
378
|
+
|
379
|
+
* develop(原形)
|
380
|
+
* developed(過去形)
|
381
|
+
* developing(進行形)
|
382
|
+
|
383
|
+
意味は同じだが語形は異なる
|
384
|
+
|
385
|
+
= ステミング(語幹処理)
|
386
|
+
|
387
|
+
語幹:単語の変化しない部分
|
388
|
+
|
389
|
+
= ステミング(語幹処理)
|
390
|
+
|
391
|
+
(('tag:left'))
|
392
|
+
((*develop*))\n
|
393
|
+
((*develop*))ed\n
|
394
|
+
((*develop*))ing
|
395
|
+
|
396
|
+
= ステミング(語幹処理)
|
397
|
+
|
398
|
+
語幹で検索\n
|
399
|
+
->語形変化後の語も検索できる
|
400
|
+
|
401
|
+
= PGroongaのステミング\n(未使用)
|
402
|
+
|
403
|
+
# coderay sql
|
404
|
+
|
405
|
+
CREATE TABLE steming_test (
|
406
|
+
title text
|
407
|
+
);
|
408
|
+
CREATE INDEX pgroonga_content_index ON steming_test USING pgroonga (title);
|
409
|
+
|
410
|
+
INSERT INTO steming_test VALUES ('I develop Groonga');
|
411
|
+
INSERT INTO steming_test VALUES ('I am developing Groonga');
|
412
|
+
INSERT INTO steming_test VALUES ('I developed Groonga');
|
413
|
+
|
414
|
+
SELECT * FROM steming_test WHERE title &@~ 'develop';
|
415
|
+
|
416
|
+
= PGroongaのステミング\n(未使用)
|
417
|
+
|
418
|
+
# coderay sql
|
419
|
+
|
420
|
+
SELECT * FROM steming_test WHERE title &@~ 'develop';
|
421
|
+
title
|
422
|
+
-------------------
|
423
|
+
I develop Groonga
|
424
|
+
(1 row)
|
425
|
+
|
426
|
+
= PGroongaのステミング
|
427
|
+
|
428
|
+
# coderay sql
|
429
|
+
|
430
|
+
CREATE TABLE steming_test (
|
431
|
+
title text
|
432
|
+
);
|
433
|
+
CREATE INDEX pgroonga_content_index
|
434
|
+
ON steming_test
|
435
|
+
USING pgroonga (title)
|
436
|
+
WITH (plugins='token_filters/stem',
|
437
|
+
token_filters='TokenFilterStem');
|
438
|
+
|
439
|
+
INSERT INTO steming_test VALUES ('I develop Groonga');
|
440
|
+
INSERT INTO steming_test VALUES ('I am developing Groonga');
|
441
|
+
INSERT INTO steming_test VALUES ('I developed Groonga');
|
442
|
+
|
443
|
+
SELECT * FROM steming_test WHERE title &@~ 'develop';
|
444
|
+
|
445
|
+
= PGroongaのステミング
|
446
|
+
|
447
|
+
# coderay sql
|
448
|
+
|
449
|
+
SELECT * FROM steming_test WHERE title &@~ 'develop';
|
450
|
+
title
|
451
|
+
-------------------------
|
452
|
+
I develop Groonga
|
453
|
+
I am developing Groonga
|
454
|
+
I developed Groonga
|
455
|
+
(3 rows)
|
456
|
+
|
457
|
+
= 高度な話題
|
458
|
+
|
459
|
+
処理順序
|
460
|
+
|
461
|
+
(1) ノーマライズ
|
462
|
+
(2) トークナイズ
|
463
|
+
(3) トークンフィルター
|
464
|
+
|
465
|
+
= 高度な話題
|
466
|
+
|
467
|
+
処理順序が問題になることがある
|
468
|
+
|
469
|
+
= 高度な話題
|
470
|
+
|
471
|
+
TokenMecab と unify_kana
|
472
|
+
|
473
|
+
= 高度な話題
|
474
|
+
|
475
|
+
* 「ワールドカップ」->\n「わーるどかっぷ」
|
476
|
+
|
477
|
+
= 高度な話題
|
478
|
+
|
479
|
+
* 「ワールドカップ」 ->\n「ワールドカップ」
|
480
|
+
* 「わーるどかっぷ」 ->\n「わ/ー/る/ど/かっぷ」
|
481
|
+
|
482
|
+
= 高度な話題
|
483
|
+
|
484
|
+
処理順序
|
485
|
+
|
486
|
+
(1) ノーマライズ
|
487
|
+
(2) トークナイズ
|
488
|
+
(3) ((*トークンフィルター*))
|
489
|
+
|
490
|
+
= 高度な話題
|
491
|
+
|
492
|
+
TokenFilterNFKC100を使う
|
493
|
+
|
494
|
+
= 高度な話題
|
495
|
+
|
496
|
+
* TokenFilterNFKC100
|
497
|
+
* 働きは、NormalizerNFKC100と同じ
|
498
|
+
* トークナイズ後にノーマライズしたいときに使う
|
499
|
+
|
500
|
+
= 同義語
|
501
|
+
|
502
|
+
同義語:同じ意味を持つ別の語
|
503
|
+
|
504
|
+
= 同義語
|
505
|
+
|
506
|
+
例えば\n
|
507
|
+
「ミルク」と\n「牛乳」
|
508
|
+
|
509
|
+
= 同義語
|
510
|
+
|
511
|
+
意味が同じものはヒットしてほしい
|
512
|
+
|
513
|
+
= 同義語展開
|
514
|
+
|
515
|
+
ミルク -> \n
|
516
|
+
ミルク OR 牛乳
|
517
|
+
|
518
|
+
= PGroongaの同義語展開
|
519
|
+
|
520
|
+
# coderay sql
|
521
|
+
|
522
|
+
CREATE TABLE synonyms (
|
523
|
+
term text PRIMARY KEY,
|
524
|
+
synonyms text[]
|
525
|
+
);
|
526
|
+
|
527
|
+
CREATE INDEX synonyms_search ON synonyms USING pgroonga (term pgroonga.text_term_search_ops_v2);
|
528
|
+
|
529
|
+
INSERT INTO synonyms (term, synonyms) VALUES ('ミルク', ARRAY['ミルク', '牛乳']);
|
530
|
+
INSERT INTO synonyms (term, synonyms) VALUES ('牛乳', ARRAY['牛乳', 'ミルク']);
|
531
|
+
|
532
|
+
CREATE TABLE memos (
|
533
|
+
id integer,
|
534
|
+
content text
|
535
|
+
);
|
536
|
+
|
537
|
+
INSERT INTO memos VALUES (1, '牛乳石鹸');
|
538
|
+
INSERT INTO memos VALUES (2, 'ミルクジャム');
|
539
|
+
INSERT INTO memos VALUES (3, 'ストロベリー');
|
540
|
+
|
541
|
+
CREATE INDEX pgroonga_content_index ON memos USING pgroonga (content);
|
542
|
+
|
543
|
+
SELECT * FROM memos
|
544
|
+
WHERE
|
545
|
+
content &@~
|
546
|
+
pgroonga_query_expand('synonyms', 'term', 'synonyms', '牛乳');
|
547
|
+
|
548
|
+
= 同義語展開
|
549
|
+
|
550
|
+
# coderay sql
|
551
|
+
|
552
|
+
SELECT * FROM memos
|
553
|
+
WHERE
|
554
|
+
content &@~
|
555
|
+
pgroonga_query_expand('synonyms', 'term', 'synonyms', '牛乳');
|
556
|
+
|
557
|
+
id | content
|
558
|
+
----+--------------------
|
559
|
+
1 | 牛乳石鹸
|
560
|
+
2 | ミルクジャム
|
561
|
+
(2 rows)
|
562
|
+
|
563
|
+
= fuzzy検索
|
564
|
+
|
565
|
+
typo対策
|
566
|
+
|
567
|
+
= fuzzy検索
|
568
|
+
|
569
|
+
* 似たような語ならヒットする
|
570
|
+
(完全一致じゃなくてもヒットする)
|
571
|
+
|
572
|
+
= fuzzy検索
|
573
|
+
|
574
|
+
「テノクロジー」で\n
|
575
|
+
「テクノロジー」がヒット
|
576
|
+
|
577
|
+
= fuzzy検索\n編集距離
|
578
|
+
|
579
|
+
* Aを何回操作するとBになるか
|
580
|
+
* 操作とは?
|
581
|
+
|
582
|
+
* 文字の挿入・削除・置換・隣接文字交換
|
583
|
+
|
584
|
+
* 操作回数を距離とする
|
585
|
+
|
586
|
+
= fuzzy検索\n編集距離
|
587
|
+
|
588
|
+
* A:テ((*ノク*))ロジー
|
589
|
+
* 隣接文字交換:((*ク*))⇔((*ノ*))
|
590
|
+
* B:テ((*クノ*))ロジー
|
591
|
+
|
592
|
+
(('tag:center'))
|
593
|
+
(('tag:x-large'))
|
594
|
+
編集距離:1
|
595
|
+
|
596
|
+
= PGroongaのfuzzy検索
|
597
|
+
|
598
|
+
# coderay sql
|
599
|
+
|
600
|
+
CREATE TABLE tags (
|
601
|
+
name text
|
602
|
+
);
|
603
|
+
|
604
|
+
CREATE INDEX tags_search ON tags USING pgroonga(name) WITH (tokenizer='');
|
605
|
+
INSERT INTO tags VALUES ('テクノロジー');
|
606
|
+
INSERT INTO tags VALUES ('テクニカル');
|
607
|
+
|
608
|
+
SELECT name FROM tags
|
609
|
+
WHERE
|
610
|
+
name &`
|
611
|
+
('fuzzy_search(name, ' || pgroonga_escape('テノクロジー') || ',
|
612
|
+
{"with_transposition": true,
|
613
|
+
"max_distance": 1})');
|
614
|
+
|
615
|
+
= fuzzy検索
|
616
|
+
|
617
|
+
# coderay sql
|
618
|
+
|
619
|
+
SELECT name FROM tags
|
620
|
+
WHERE
|
621
|
+
name &`
|
622
|
+
('fuzzy_search(name, ' || pgroonga_escape('テノクロジー') || ',
|
623
|
+
{"with_transposition": true,
|
624
|
+
"max_distance": 1})');
|
625
|
+
name
|
626
|
+
--------------------
|
627
|
+
テクノロジー
|
628
|
+
(1 row)
|
629
|
+
|
630
|
+
= PGroongaでランキング改善
|
631
|
+
|
632
|
+
何を基準に\nランキングを\n決めるのか
|
633
|
+
|
634
|
+
= PGroongaのスコアリング
|
635
|
+
|
636
|
+
* TF(デフォルト)
|
637
|
+
* TF-IDF
|
638
|
+
* TF at Most
|
639
|
+
|
640
|
+
= PGroongaのスコアリング\nTF(デフォルト)
|
641
|
+
|
642
|
+
単語の((*出現数*))\nが大事
|
643
|
+
|
644
|
+
= PGroongaのスコアリング\nTF(デフォルト)
|
645
|
+
|
646
|
+
* 検索キーワードが文書内に多く含まれる文書のスコアーが高くなる
|
647
|
+
|
648
|
+
= PGroongaのスコアリング\nTF(デフォルト)
|
649
|
+
|
650
|
+
# coderay sql
|
651
|
+
|
652
|
+
CREATE TABLE memos (
|
653
|
+
title text,
|
654
|
+
content text
|
655
|
+
);
|
656
|
+
|
657
|
+
CREATE INDEX pgroonga_memos_index
|
658
|
+
ON memos
|
659
|
+
USING pgroonga (content);
|
660
|
+
INSERT INTO memos VALUES ('PostgreSQL', 'PostgreSQLはリレーショナル・データベース管理システムです。');
|
661
|
+
INSERT INTO memos VALUES ('Groonga', 'Groongaは日本語対応の高速な全文検索エンジンです。');
|
662
|
+
INSERT INTO memos VALUES ('PGroonga', 'PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。');
|
663
|
+
INSERT INTO memos VALUES ('PGroonga1', 'PGroongaは全文検索エンジンGroongaを使っています。');
|
664
|
+
INSERT INTO memos VALUES ('PGroonga2', 'Groonga、Groonga、Groonga、Groonga、Groonga');
|
665
|
+
|
666
|
+
= PGroongaのスコアリング\nTF(デフォルト)
|
667
|
+
|
668
|
+
# coderay sql
|
669
|
+
|
670
|
+
SELECT *, pgroonga_score(tableoid, ctid) AS score
|
671
|
+
FROM memos
|
672
|
+
WHERE content &@~ 'Groonga'
|
673
|
+
ORDER BY score DESC;
|
674
|
+
|
675
|
+
title | content | score
|
676
|
+
-----------+---------------------------------------------------------------------------+-------
|
677
|
+
PGroonga2 | Groonga、Groonga、Groonga、Groonga、Groonga | 5
|
678
|
+
Groonga | Groongaは日本語対応の高速な全文検索エンジンです。 | 1
|
679
|
+
PGroonga | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。 | 1
|
680
|
+
PGroonga1 | PGroongaは全文検索エンジンGroongaを使っています。 | 1
|
681
|
+
(4 rows)
|
682
|
+
|
683
|
+
= PGroongaのスコアリング\nTF-IDF
|
684
|
+
|
685
|
+
単語の((*レア度*))\nが大事
|
686
|
+
|
687
|
+
= PGroongaのスコアリング\nTF-IDF
|
688
|
+
|
689
|
+
* 文書に出てくる頻度が高い\n(レア度低い)
|
690
|
+
* 文書に出てくる頻度が低い\n(レア度高い)
|
691
|
+
|
692
|
+
= PGroongaのスコアリング\nTF-IDF
|
693
|
+
|
694
|
+
# coderay sql
|
695
|
+
|
696
|
+
SELECT *, pgroonga_score(tableoid, ctid) AS score
|
697
|
+
FROM memos
|
698
|
+
WHERE content &@~
|
699
|
+
('Groonga OR 全文検索',
|
700
|
+
ARRAY[1],
|
701
|
+
ARRAY['scorer_tf_idf($index)'],
|
702
|
+
'pgroonga_memos_index')::pgroonga_full_text_search_condition_with_scorers
|
703
|
+
ORDER BY score DESC;
|
704
|
+
|
705
|
+
title | content | score
|
706
|
+
-----------+---------------------------------------------------------------------------+-------
|
707
|
+
Groonga | Groongaは日本語対応の高速な全文検索エンジンです。 | 2
|
708
|
+
PGroonga1 | PGroongaは全文検索エンジンGroongaを使っています。 | 2
|
709
|
+
PGroonga | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。 | 1
|
710
|
+
PGroonga2 | Groonga、Groonga、Groonga、Groonga、Groonga | 1
|
711
|
+
(4 rows)
|
712
|
+
|
713
|
+
= PGroongaのスコアリング\nTF at Most
|
714
|
+
|
715
|
+
スコアーの\n((*最大値*))を制限
|
716
|
+
|
717
|
+
= PGroongaのスコアリング\nTF at Most
|
718
|
+
|
719
|
+
# coderay sql
|
720
|
+
|
721
|
+
SELECT *, pgroonga_score(tableoid, ctid) AS score
|
722
|
+
FROM memos
|
723
|
+
WHERE content &@~ 'Groonga OR PostgreSQL'
|
724
|
+
ORDER BY score DESC;
|
725
|
+
|
726
|
+
title | content | score
|
727
|
+
------------+---------------------------------------------------------------------------+-------
|
728
|
+
PGroonga2 | Groonga、Groonga、Groonga、Groonga、Groonga | 5
|
729
|
+
PGroonga | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。 | 2
|
730
|
+
Groonga | Groongaは日本語対応の高速な全文検索エンジンです。 | 1
|
731
|
+
PGroonga1 | PGroongaは全文検索エンジンGroongaを使っています。 | 1
|
732
|
+
PostgreSQL | PostgreSQLはリレーショナル・データベース管理システムです。 | 1
|
733
|
+
(5 rows)
|
734
|
+
|
735
|
+
= PGroongaのスコアリング\nTF at Most
|
736
|
+
|
737
|
+
# coderay sql
|
738
|
+
|
739
|
+
SELECT *, pgroonga_score(tableoid, ctid) AS score
|
740
|
+
FROM memos
|
741
|
+
WHERE content &@~
|
742
|
+
('Groonga OR 全文検索',
|
743
|
+
ARRAY[1],
|
744
|
+
ARRAY['scorer_tf_at_most($index, 1)'],
|
745
|
+
'pgroonga_memos_index')::pgroonga_full_text_search_condition_with_scorers
|
746
|
+
ORDER BY score DESC;
|
747
|
+
|
748
|
+
title | content | score
|
749
|
+
-----------+---------------------------------------------------------------------------+-------
|
750
|
+
Groonga | Groongaは日本語対応の高速な全文検索エンジンです。 | 2
|
751
|
+
PGroonga1 | PGroongaは全文検索エンジンGroongaを使っています。 | 2
|
752
|
+
PGroonga | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。 | 1
|
753
|
+
PGroonga2 | Groonga、Groonga、Groonga、Groonga、Groonga | 1
|
754
|
+
(4 rows)
|
755
|
+
|
756
|
+
= 参考資料
|
757
|
+
|
758
|
+
* PGroonga自体の解説
|
759
|
+
|
760
|
+
* ((<URL:https://www.slideshare.net/kou/postgresql-conference-japan-2017>))
|
761
|
+
|
762
|
+
= 参考資料
|
763
|
+
|
764
|
+
* ノーマライザーのオプション一覧
|
765
|
+
|
766
|
+
* ((<URL:https://groonga.org/ja/docs/reference/normalizers/normalizer_nfkc130.html#parameters>))
|
767
|
+
|
768
|
+
= 参考資料
|
769
|
+
|
770
|
+
* 使用可能なトークナイザー一覧
|
771
|
+
|
772
|
+
* ((<URL:https://groonga.org/ja/docs/reference/tokenizers.html>))
|
773
|
+
|
774
|
+
= 参考資料
|
775
|
+
|
776
|
+
* ステミングの使用方法
|
777
|
+
|
778
|
+
* ((<URL:https://pgroonga.github.io/ja/reference/create-index-using-pgroonga.html>))
|
779
|
+
|
780
|
+
= 参考資料
|
781
|
+
|
782
|
+
* 同義語検索の方法
|
783
|
+
|
784
|
+
* ((<URL:https://pgroonga.github.io/ja/how-to/synonyms.html>))
|
785
|
+
|
786
|
+
= 参考資料
|
787
|
+
|
788
|
+
* 使用可能なスコアラー一覧
|
789
|
+
|
790
|
+
* ((<URL:https://groonga.org/ja/docs/reference/scorer.html#built-in-scorers>))
|
791
|
+
|
792
|
+
= 参考資料
|
793
|
+
|
794
|
+
* スコアラーの設定方法
|
795
|
+
|
796
|
+
* ((<URL:https://pgroonga.github.io/ja/reference/operators/query-v2.html>))
|
797
|
+
|