rabbit-slide-komainu8-postgresql-conference-japan-2025 1.0.1
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 +2 -0
- data/README.md +47 -0
- data/Rakefile +17 -0
- data/config.yaml +23 -0
- data/images/after-clustering.png +0 -0
- data/images/before-clustering.png +0 -0
- data/images/convert-text-to-vector-with-pgroonga.png +0 -0
- data/images/distance.png +0 -0
- data/images/ivf.png +0 -0
- data/images/keyword-search-dic-register.png +0 -0
- data/images/keyword-search-dic.png +0 -0
- data/images/keyword-search-issue.png +0 -0
- data/images/keyword-search-new-dic.png +0 -0
- data/images/keyword-search-new-record.png +0 -0
- data/images/median-values.png +0 -0
- data/images/number-of-dimensions.png +0 -0
- data/images/pgroonga-insert.png +0 -0
- data/images/pgvector-insert.png +0 -0
- data/images/reduction.png +0 -0
- data/images/semantic-search-advantage.png +0 -0
- data/images/semantic-search.png +0 -0
- data/images/text-to-vector.png +0 -0
- data/images/vector-similarity.png +0 -0
- data/pdf/postgresql-conference-japan-2025-pgroonga-with-semantic-search.pdf +0 -0
- data/pgroonga-with-semantic-search-for-print.pdf +0 -0
- data/pgroonga-with-semantic-search.rab +498 -0
- data/theme.rb +6 -0
- metadata +88 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 1ce798f8170b0d2c5c4a55d082065256e2a4df0f777436699c5f2d4f12df8c26
|
|
4
|
+
data.tar.gz: f789708e81691db020c4f916579eb4c443f38ba8e81300d065076ce2cceb13a4
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: e4392255042f4cd331d3f144038abbd1c9e0dec828177c3d2f27f1d9869d70df2354f3c2f1b3c2db7dc06b3c0e5acdbc5340dc56fb9a8d416c993149645a363f
|
|
7
|
+
data.tar.gz: c93b9d762674ce030b89b900599fc3613085bd9c1373cf046f4684588d5aac82212a0f55a62391c3f38347ef3f62846984274723eb8470336267de2e4262fe3a
|
data/.rabbit
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# PostgreSQLでのセマンティックサーチへの挑戦
|
|
2
|
+
|
|
3
|
+
従来のキーワード検索は同義語や曖昧表現に弱く、必要な情報を見落としがちです。
|
|
4
|
+
本講演ではこの課題に対し、意味的な近さで探せるセマンティックサーチに挑戦します。
|
|
5
|
+
量子化と補正で軽量・高速な近似距離計算を実現するRaBitQをGroongaに実装し、PGroongaを通してPostgreSQLから利用可能にしました。
|
|
6
|
+
その仕組みと導入手順、FAQ/ナレッジ検索での活用例を交え、検索が使えるようになるまでの流れを紹介します。
|
|
7
|
+
|
|
8
|
+
## ライセンス
|
|
9
|
+
|
|
10
|
+
### スライド
|
|
11
|
+
|
|
12
|
+
CC BY-SA 4.0
|
|
13
|
+
|
|
14
|
+
原著作者:堀本 泰弘/阿部 智晃
|
|
15
|
+
|
|
16
|
+
### PGroongaのロゴ
|
|
17
|
+
|
|
18
|
+
CC BY 3.0
|
|
19
|
+
|
|
20
|
+
原著作者:Groongaプロジェクト
|
|
21
|
+
|
|
22
|
+
### PostgreSQL 日本語マニュアルのデータ
|
|
23
|
+
|
|
24
|
+
The PostgreSQL Licence
|
|
25
|
+
|
|
26
|
+
原著作者:PostgreSQL Global Development Group/The Regents of the University of California
|
|
27
|
+
|
|
28
|
+
## 作者向け
|
|
29
|
+
|
|
30
|
+
### 表示
|
|
31
|
+
|
|
32
|
+
rake
|
|
33
|
+
|
|
34
|
+
### 公開
|
|
35
|
+
|
|
36
|
+
rake publish
|
|
37
|
+
|
|
38
|
+
## 閲覧者向け
|
|
39
|
+
|
|
40
|
+
### インストール
|
|
41
|
+
|
|
42
|
+
gem install rabbit-slide--postgresql-conference-japan-2025
|
|
43
|
+
|
|
44
|
+
### 表示
|
|
45
|
+
|
|
46
|
+
rabbit rabbit-slide--postgresql-conference-japan-2025.gem
|
|
47
|
+
|
data/Rakefile
ADDED
|
@@ -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-YOUR-THEME")
|
|
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
|
data/config.yaml
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: postgresql-conference-japan-2025
|
|
3
|
+
base_name: pgroonga-with-semantic-search
|
|
4
|
+
tags: [rabbit, postgresql, groonga, pgroonga, pgcon25j, fts]
|
|
5
|
+
presentation_date: 2025-11-21
|
|
6
|
+
presentation_start_time:
|
|
7
|
+
presentation_end_time:
|
|
8
|
+
version: 1.0.1
|
|
9
|
+
licenses: [CC-BY-SA-4.0, CC-BY-3.0, The PostgreSQL Licence]
|
|
10
|
+
slideshare_id:
|
|
11
|
+
speaker_deck_id:
|
|
12
|
+
vimeo_id:
|
|
13
|
+
youtube_id:
|
|
14
|
+
width: 1920
|
|
15
|
+
height: 1080
|
|
16
|
+
source_code_uri:
|
|
17
|
+
author:
|
|
18
|
+
markup_language: :rd
|
|
19
|
+
name: Horimoto Yasuhiro
|
|
20
|
+
email: horimoto@clear-code.com
|
|
21
|
+
rubygems_user: komainu8
|
|
22
|
+
slideshare_user:
|
|
23
|
+
speaker_deck_user:
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/images/distance.png
ADDED
|
Binary file
|
data/images/ivf.png
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
= PostgreSQLでの\nセマンティックサーチへの挑戦
|
|
2
|
+
|
|
3
|
+
: author
|
|
4
|
+
堀本 泰弘\n阿部 智晃
|
|
5
|
+
: institution
|
|
6
|
+
株式会社クリアコード
|
|
7
|
+
: content-source
|
|
8
|
+
PostgreSQL Conference Japan 2025
|
|
9
|
+
: date
|
|
10
|
+
2025-11-21
|
|
11
|
+
: start-time
|
|
12
|
+
2025-11-21T16:20:00+09:00
|
|
13
|
+
: end-time
|
|
14
|
+
2025-11-21T17:10:00+09:00
|
|
15
|
+
: theme
|
|
16
|
+
.
|
|
17
|
+
|
|
18
|
+
= 本日のゴール
|
|
19
|
+
|
|
20
|
+
PostgreSQLで簡単に\nセマンティックサーチが使えることを\n実感してもらう
|
|
21
|
+
|
|
22
|
+
= 本日の内容
|
|
23
|
+
|
|
24
|
+
(1) キーワード検索とセマンティックサーチの\n比較
|
|
25
|
+
(2) セマンティックサーチを実現するために
|
|
26
|
+
(3) PostgreSQLでセマンティクサーチ
|
|
27
|
+
(4) 性能とユースケース
|
|
28
|
+
|
|
29
|
+
= 本日の内容
|
|
30
|
+
|
|
31
|
+
(1) ((*キーワード検索とセマンティックサーチの\n比較*))
|
|
32
|
+
(2) セマンティックサーチを実現するために
|
|
33
|
+
(3) PostgreSQLでセマンティクサーチ
|
|
34
|
+
(4) 性能とユースケース
|
|
35
|
+
|
|
36
|
+
= キーワード検索の利点と課題
|
|
37
|
+
|
|
38
|
+
# image
|
|
39
|
+
# src = images/keyword-search-issue.png
|
|
40
|
+
|
|
41
|
+
= キーワード検索の利点と課題
|
|
42
|
+
|
|
43
|
+
# image
|
|
44
|
+
# src = images/keyword-search-dic.png
|
|
45
|
+
|
|
46
|
+
= キーワード検索の利点と課題
|
|
47
|
+
|
|
48
|
+
# image
|
|
49
|
+
# src = images/keyword-search-new-record.png
|
|
50
|
+
|
|
51
|
+
= キーワード検索の利点と課題
|
|
52
|
+
|
|
53
|
+
# image
|
|
54
|
+
# src = images/keyword-search-dic-register.png
|
|
55
|
+
|
|
56
|
+
= キーワード検索の利点と課題
|
|
57
|
+
|
|
58
|
+
# image
|
|
59
|
+
# src = images/keyword-search-new-dic.png
|
|
60
|
+
|
|
61
|
+
= セマンティックサーチの利点と課題
|
|
62
|
+
|
|
63
|
+
# image
|
|
64
|
+
# src = images/semantic-search-advantage.png
|
|
65
|
+
|
|
66
|
+
= 本日の内容
|
|
67
|
+
|
|
68
|
+
(1) キーワード検索とセマンティックサーチの\n比較
|
|
69
|
+
(2) ((*セマンティックサーチを実現するために*))
|
|
70
|
+
(3) PostgreSQLでセマンティクサーチ
|
|
71
|
+
(4) 性能とユースケース
|
|
72
|
+
|
|
73
|
+
= セマンティックサーチに必要な技術
|
|
74
|
+
|
|
75
|
+
(1) テキスト -> ベクトルデータへの変換
|
|
76
|
+
(2) ベクトルデータの類似度の計算
|
|
77
|
+
(3) ベクトルデータの効率的な検索
|
|
78
|
+
(4) ベクトルデータの圧縮
|
|
79
|
+
|
|
80
|
+
= テキスト -> ベクトルデータへの変換
|
|
81
|
+
|
|
82
|
+
意味で検索するとは?
|
|
83
|
+
|
|
84
|
+
= テキスト -> ベクトルデータへの変換
|
|
85
|
+
|
|
86
|
+
# image
|
|
87
|
+
# src = images/text-to-vector.png
|
|
88
|
+
|
|
89
|
+
= テキスト -> ベクトルデータへの変換
|
|
90
|
+
|
|
91
|
+
意味を((*ベクトル*))\nとして表現できる
|
|
92
|
+
|
|
93
|
+
= テキスト -> ベクトルデータへの変換
|
|
94
|
+
|
|
95
|
+
ベクトルは\n((*距離を計算*))できる
|
|
96
|
+
|
|
97
|
+
= ベクトルデータの類似度の計算
|
|
98
|
+
|
|
99
|
+
どれだけ似ているか\n
|
|
100
|
+
|
|
101
|
+
- ベクトル間の距離が近い = 似ている\n
|
|
102
|
+
- ベクトル間の距離が遠い = 似ていない
|
|
103
|
+
|
|
104
|
+
= ベクトルデータの類似度の計算
|
|
105
|
+
|
|
106
|
+
# image
|
|
107
|
+
# src = images/distance.png
|
|
108
|
+
|
|
109
|
+
= ベクトルデータの類似度の計算
|
|
110
|
+
|
|
111
|
+
# image
|
|
112
|
+
# src = images/vector-similarity.png
|
|
113
|
+
|
|
114
|
+
= ベクトルデータの効率的な検索
|
|
115
|
+
|
|
116
|
+
全てのベクトルと類似度を計算するのか?
|
|
117
|
+
|
|
118
|
+
= ベクトルデータの効率的な検索
|
|
119
|
+
|
|
120
|
+
線形探索は\n現実的ではない
|
|
121
|
+
|
|
122
|
+
= ベクトルデータの効率的な検索
|
|
123
|
+
|
|
124
|
+
一部のベクトルデータだけを検索
|
|
125
|
+
|
|
126
|
+
= ベクトルデータの効率的な検索(イメージ)
|
|
127
|
+
|
|
128
|
+
# image
|
|
129
|
+
# src = images/before-clustering.png
|
|
130
|
+
|
|
131
|
+
= ベクトルデータの効率的な検索(イメージ)
|
|
132
|
+
|
|
133
|
+
# image
|
|
134
|
+
# src = images/after-clustering.png
|
|
135
|
+
|
|
136
|
+
= ベクトルデータの効率的な検索(イメージ)
|
|
137
|
+
|
|
138
|
+
# image
|
|
139
|
+
# src = images/median-values.png
|
|
140
|
+
|
|
141
|
+
= ベクトルデータの効率的な検索(イメージ)
|
|
142
|
+
|
|
143
|
+
# image
|
|
144
|
+
# src = images/ivf.png
|
|
145
|
+
|
|
146
|
+
= ベクトルデータの圧縮
|
|
147
|
+
|
|
148
|
+
自然言語を変換した\nベクトルデータは\n((*大きい*))
|
|
149
|
+
|
|
150
|
+
= ベクトルデータの圧縮
|
|
151
|
+
|
|
152
|
+
次元数:大 \n
|
|
153
|
+
▶データサイズ:大 \n
|
|
154
|
+
▶メモリーに乗らない \n
|
|
155
|
+
▶ 性能劣化
|
|
156
|
+
|
|
157
|
+
= ベクトルデータの圧縮
|
|
158
|
+
|
|
159
|
+
データ量の削減が必要
|
|
160
|
+
|
|
161
|
+
= 圧縮方法
|
|
162
|
+
|
|
163
|
+
主な圧縮方法
|
|
164
|
+
|
|
165
|
+
(1) ベクトルの次元を削減
|
|
166
|
+
(2) ベクトルの量子化
|
|
167
|
+
|
|
168
|
+
= 圧縮方法
|
|
169
|
+
|
|
170
|
+
どちらの方法も\n
|
|
171
|
+
圧縮前のベクトルの\n
|
|
172
|
+
((*特徴をなるべく維持*))\n
|
|
173
|
+
して圧縮
|
|
174
|
+
|
|
175
|
+
= 本日の内容
|
|
176
|
+
|
|
177
|
+
(1) キーワード検索とセマンティックサーチの\n比較
|
|
178
|
+
(2) セマンティックサーチを実現するために
|
|
179
|
+
(3) ((*PostgreSQLでセマンティクサーチ*))
|
|
180
|
+
(4) 性能とユースケース
|
|
181
|
+
|
|
182
|
+
= PostgreSQLのセマンティクサーチ
|
|
183
|
+
|
|
184
|
+
セマンティックサーチを使うには?
|
|
185
|
+
|
|
186
|
+
* pgvectorを使う
|
|
187
|
+
* PGroongaを使う
|
|
188
|
+
|
|
189
|
+
= pgvectorとは?
|
|
190
|
+
|
|
191
|
+
* 類似したベクトルデータを検索する機能を提供するPostgreSQLの拡張機能
|
|
192
|
+
* 類似度の計算方法が多数提供されている
|
|
193
|
+
* インデックスを使用して検索を高速化できる
|
|
194
|
+
|
|
195
|
+
= PGroonga(ぴーじーるんが)とは?
|
|
196
|
+
|
|
197
|
+
* 全言語対応の超高速全文検索機能を提供する拡張
|
|
198
|
+
* PostgreSQLのインデックスとして使える
|
|
199
|
+
|
|
200
|
+
= PGroonga(ぴーじーるんが)とは?
|
|
201
|
+
|
|
202
|
+
* PostgreSQLのデータを使って全文検索する \n= ゼロETLで利用できる
|
|
203
|
+
* PostgreSQLの構文をほぼそのまま使える \n= 学習コストが低い
|
|
204
|
+
* ((*4.0.5からセマンティックサーチが使える*))
|
|
205
|
+
|
|
206
|
+
= pgvectorとPGroongaの違い
|
|
207
|
+
|
|
208
|
+
# image
|
|
209
|
+
# src = images/pgvector-insert.png
|
|
210
|
+
|
|
211
|
+
= pgvectorとPGroongaの違い
|
|
212
|
+
|
|
213
|
+
# image
|
|
214
|
+
# src = images/pgroonga-insert.png
|
|
215
|
+
|
|
216
|
+
= テキスト -> ベクトルデータへの変換
|
|
217
|
+
|
|
218
|
+
# image
|
|
219
|
+
# src = images/convert-text-to-vector-with-pgroonga.png
|
|
220
|
+
|
|
221
|
+
= pgvectorのメリット
|
|
222
|
+
|
|
223
|
+
* ベクトルデータへ変換するサービスは複数あるので、用途に合わせた組み合わせができる
|
|
224
|
+
* ベクトルデータ変換と検索でリソースを分割できる
|
|
225
|
+
|
|
226
|
+
= pgvectorのデメリット
|
|
227
|
+
|
|
228
|
+
* 変換したベクトルデータをシステム間でやりとりする必要がある
|
|
229
|
+
|
|
230
|
+
= PGroongaのメリット
|
|
231
|
+
|
|
232
|
+
* ベクトルデータをシステム間でやりとりする必要がない
|
|
233
|
+
* RaBitQというアルゴリズムを使って、データサイズを少なくできる
|
|
234
|
+
|
|
235
|
+
= PGroongaのデメリット
|
|
236
|
+
|
|
237
|
+
* ベクトルデータへの変換は固定的
|
|
238
|
+
* ベクトルデータ変換と検索でリソースが同一
|
|
239
|
+
|
|
240
|
+
= RaBitQとは?
|
|
241
|
+
|
|
242
|
+
ベクトルデータの\n量子化手法の一つ
|
|
243
|
+
|
|
244
|
+
= RaBitQを採用した理由
|
|
245
|
+
|
|
246
|
+
データ量を大幅に\n少なく出来る
|
|
247
|
+
|
|
248
|
+
= データ量を大幅に少なく出来る
|
|
249
|
+
|
|
250
|
+
各32bit浮動少数点数を1ビットで表現
|
|
251
|
+
|
|
252
|
+
= データ量を大幅に少なく出来る
|
|
253
|
+
|
|
254
|
+
単純にデータサイズは1/32になる
|
|
255
|
+
|
|
256
|
+
= pgvectorとPGroongaでデータ登録と検索
|
|
257
|
+
|
|
258
|
+
= pgvectorのデータ登録と検索
|
|
259
|
+
|
|
260
|
+
# coderay sql
|
|
261
|
+
|
|
262
|
+
CREATE EXTENSION IF NOT EXISTS vector;
|
|
263
|
+
|
|
264
|
+
CREATE TABLE contents_for_pgvector (
|
|
265
|
+
content text,
|
|
266
|
+
content_embedding vector(384)
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
= pgvectorのデータ登録と検索
|
|
270
|
+
|
|
271
|
+
# coderay sql
|
|
272
|
+
|
|
273
|
+
INSERT INTO contents_for_pgvector (content, content_embedding)
|
|
274
|
+
SELECT 'I am a boy', (pgroonga_language_model_vectorize(
|
|
275
|
+
'hf:///groonga/all-MiniLM-L6-v2-Q4_K_M-GGUF',
|
|
276
|
+
'I am a boy'));
|
|
277
|
+
|
|
278
|
+
INSERT INTO contents_for_pgvector (content, content_embedding)
|
|
279
|
+
SELECT 'I am a dog', (pgroonga_language_model_vectorize(
|
|
280
|
+
'hf:///groonga/all-MiniLM-L6-v2-Q4_K_M-GGUF',
|
|
281
|
+
'I am a dog'));
|
|
282
|
+
|
|
283
|
+
INSERT INTO contents_for_pgvector (content, content_embedding)
|
|
284
|
+
SELECT 'I am a king', (pgroonga_language_model_vectorize(
|
|
285
|
+
'hf:///groonga/all-MiniLM-L6-v2-Q4_K_M-GGUF',
|
|
286
|
+
'I am a king'));
|
|
287
|
+
|
|
288
|
+
= pgvectorのデータ登録と検索
|
|
289
|
+
|
|
290
|
+
# coderay sql
|
|
291
|
+
|
|
292
|
+
SELECT * FROM contents_for_pgvector;
|
|
293
|
+
-- I am a boy | [-0.05031514,0.10813845,...,-0.12843993]
|
|
294
|
+
-- I am a dog | [-0.03515085,-0.0059523215,...,-0.024966048]
|
|
295
|
+
-- I am a king | [-0.030026972,0.057919234,...,-0.09476562]
|
|
296
|
+
-- (3 行)
|
|
297
|
+
|
|
298
|
+
= pgvectorのデータ登録と検索
|
|
299
|
+
|
|
300
|
+
# coderay sql
|
|
301
|
+
|
|
302
|
+
SELECT contents_for_pgvector.content,
|
|
303
|
+
(contents_for_pgvector.content_embedding <#> query_embedding.query) * -1 AS inner_product
|
|
304
|
+
FROM contents_for_pgvector,
|
|
305
|
+
(
|
|
306
|
+
SELECT CAST(pgroonga_language_model_vectorize(
|
|
307
|
+
'hf:///groonga/all-MiniLM-L6-v2-Q4_K_M-GGUF',
|
|
308
|
+
'boy') AS vector) AS query
|
|
309
|
+
) query_embedding
|
|
310
|
+
ORDER BY inner_product DESC;
|
|
311
|
+
-- content | inner_product
|
|
312
|
+
-- -------------+--------------------
|
|
313
|
+
-- I am a boy | 0.5909400582313538
|
|
314
|
+
-- I am a dog | 0.2753480076789856
|
|
315
|
+
-- I am a king | 0.1733587086200714
|
|
316
|
+
-- (3 行)
|
|
317
|
+
|
|
318
|
+
= PGroongaのインデックス登録
|
|
319
|
+
|
|
320
|
+
# coderay sql
|
|
321
|
+
|
|
322
|
+
DROP INDEX IF EXISTS pgroonga_content_semantic_search_index;
|
|
323
|
+
CREATE INDEX pgroonga_content_semantic_search_index ON contents_for_pgroonga
|
|
324
|
+
USING pgroonga (content pgroonga_text_semantic_search_ops_v2)
|
|
325
|
+
WITH (plugins = 'language_model/knn',
|
|
326
|
+
model = 'hf:///groonga/multilingual-e5-large-Q4_K_M-GGUF');
|
|
327
|
+
|
|
328
|
+
= PGroongaのデータ登録と検索
|
|
329
|
+
|
|
330
|
+
# coderay sql
|
|
331
|
+
|
|
332
|
+
CREATE EXTENSION IF NOT EXISTS pgroonga;
|
|
333
|
+
|
|
334
|
+
CREATE TABLE contents_for_pgroonga (
|
|
335
|
+
content text
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
= PGroongaのデータ登録と検索
|
|
339
|
+
|
|
340
|
+
# coderay sql
|
|
341
|
+
|
|
342
|
+
INSERT INTO contents_for_pgroonga VALUES ('I am a boy');
|
|
343
|
+
INSERT INTO contents_for_pgroonga VALUES ('I am a dog');
|
|
344
|
+
INSERT INTO contents_for_pgroonga VALUES ('I am a king');
|
|
345
|
+
SELECT * FROM contents_for_pgroonga;
|
|
346
|
+
-- content
|
|
347
|
+
-- -------------
|
|
348
|
+
-- I am a boy
|
|
349
|
+
-- I am a dog
|
|
350
|
+
-- I am a king
|
|
351
|
+
-- (3 行)
|
|
352
|
+
|
|
353
|
+
= PGroongaのデータ登録と検索
|
|
354
|
+
|
|
355
|
+
# coderay sql
|
|
356
|
+
|
|
357
|
+
SELECT content, pgroonga_score(tableoid, ctid)
|
|
358
|
+
FROM contents_for_pgroonga
|
|
359
|
+
WHERE content &@* pgroonga_condition('boy');
|
|
360
|
+
-- content | pgroonga_score
|
|
361
|
+
-- -------------+--------------------
|
|
362
|
+
-- I am a boy | 0.8671597838401794
|
|
363
|
+
-- I am a king | 0.5496522784233093
|
|
364
|
+
-- I am a dog | 0.5450347065925598
|
|
365
|
+
-- (3 行)
|
|
366
|
+
|
|
367
|
+
= PGroongaのデータ登録と検索
|
|
368
|
+
|
|
369
|
+
PGroongaが内部で保持している\nベクトルデータ
|
|
370
|
+
|
|
371
|
+
# coderay sql
|
|
372
|
+
|
|
373
|
+
-- [1,1,"I am a boy","mjctvB1JDj5pur67C/ ... ICPMFQi7wSL8q9"],
|
|
374
|
+
-- [2,2,"I am a dog","BwGXu4YNUj2Yi5k9j+ ... nDPPL4ijySlqy7"],
|
|
375
|
+
-- [3,3,"I am a king","1lklOxiXvj2rSB69VG ... tbvVHmDr1wSFK9"]
|
|
376
|
+
|
|
377
|
+
= 本日の内容
|
|
378
|
+
|
|
379
|
+
(1) キーワード検索とセマンティックサーチの比較
|
|
380
|
+
(2) PostgreSQLでセマンティクサーチ
|
|
381
|
+
(3) セマンティックサーチを実現するために
|
|
382
|
+
(4) ((*性能とユースケース*))
|
|
383
|
+
|
|
384
|
+
= 測定環境
|
|
385
|
+
|
|
386
|
+
* GPUなし
|
|
387
|
+
* PostgreSQL 18
|
|
388
|
+
* PGroonga mainブランチ
|
|
389
|
+
* pgvector v0.8.1
|
|
390
|
+
* IVFFlatインデックス
|
|
391
|
+
|
|
392
|
+
= 測定に使ったデータ
|
|
393
|
+
|
|
394
|
+
* Wikipediaのタイトル
|
|
395
|
+
* 1,477,194 件
|
|
396
|
+
|
|
397
|
+
= 測定項目
|
|
398
|
+
|
|
399
|
+
* 検索速度
|
|
400
|
+
* ベクトルデータのサイズ
|
|
401
|
+
* インデックス作成時間
|
|
402
|
+
|
|
403
|
+
= 検索速度: PGroonga
|
|
404
|
+
|
|
405
|
+
検証用のクエリ:
|
|
406
|
+
|
|
407
|
+
# coderay sql
|
|
408
|
+
|
|
409
|
+
SET enable_seqscan = off;
|
|
410
|
+
|
|
411
|
+
SELECT COUNT(title) FROM wikipedia
|
|
412
|
+
ORDER BY title <&@*> pgroonga_condition('異世界転生して無双したよ')
|
|
413
|
+
LIMIT 5;
|
|
414
|
+
|
|
415
|
+
= 検索速度: pgvector
|
|
416
|
+
|
|
417
|
+
検証用のクエリ:
|
|
418
|
+
|
|
419
|
+
# coderay sql
|
|
420
|
+
|
|
421
|
+
SET enable_seqscan = off;
|
|
422
|
+
|
|
423
|
+
SELECT COUNT(title) FROM wikipedia
|
|
424
|
+
ORDER BY embedding <-> '['異世界転生して無双したよ'のベクトル]'
|
|
425
|
+
LIMIT 5;
|
|
426
|
+
|
|
427
|
+
= 検索速度: 結果: PGroonga
|
|
428
|
+
|
|
429
|
+
5回実行した中央値: 108.868 ms
|
|
430
|
+
|
|
431
|
+
ベクトルの生成も含む
|
|
432
|
+
|
|
433
|
+
= 検索速度: 結果: pgvector
|
|
434
|
+
|
|
435
|
+
5回実行した中央値: 12.166 ms
|
|
436
|
+
|
|
437
|
+
ベクトルの生成は含まず
|
|
438
|
+
|
|
439
|
+
= ベクトルデータサイズ
|
|
440
|
+
|
|
441
|
+
* float4の384次元のベクトルデータ:\n
|
|
442
|
+
4バイト * 384 = 1,536バイト
|
|
443
|
+
|
|
444
|
+
= PGroongaのベクトルデータサイズ
|
|
445
|
+
|
|
446
|
+
* PGroongaではfloat4の384次元のベクトルデータを量子化
|
|
447
|
+
* 「iJDX5WFlJ7wwvR ... +sHiH0KxDv1PoHT8=」という64バイトのバイナリーで保持
|
|
448
|
+
* 64文字 = 64バイト
|
|
449
|
+
|
|
450
|
+
= PGroongaのインデックス作成時間
|
|
451
|
+
|
|
452
|
+
* PGroongaの場合インデックスの作成時間は「ベクトル化 + インデックスの作成時間」
|
|
453
|
+
* ベクトル化がすごく遅い
|
|
454
|
+
* ただ、GPUの有無や、使う言語モデルによっても大きく速度が変わる
|
|
455
|
+
|
|
456
|
+
= ユースケース:\nPostgreSQLのドキュメントを検索
|
|
457
|
+
|
|
458
|
+
テーブルを消す\nクエリを検索
|
|
459
|
+
|
|
460
|
+
= キーワード検索:結果
|
|
461
|
+
|
|
462
|
+
# coderay sql
|
|
463
|
+
|
|
464
|
+
SELECT title, SUBSTRING(content FROM 0 FOR 10)
|
|
465
|
+
FROM jpug_doc_contents
|
|
466
|
+
WHERE content LIKE '%テーブル%消す%'
|
|
467
|
+
LIMIT 5;
|
|
468
|
+
-- title | substring
|
|
469
|
+
-- -------------------+------------------
|
|
470
|
+
-- contrib | 付録F 追加で提供
|
|
471
|
+
-- ddl-priv | 5.8. 権限
|
|
472
|
+
-- ddl-schemas | 5.10. スキー
|
|
473
|
+
-- explicit-locking | 13.3. 明示的
|
|
474
|
+
-- extend-extensions | 36.17. 関連
|
|
475
|
+
-- (5 rows)
|
|
476
|
+
|
|
477
|
+
= セマンティックサーチ:結果
|
|
478
|
+
|
|
479
|
+
PGroongaだと直接テキストで検索できる
|
|
480
|
+
|
|
481
|
+
# coderay sql
|
|
482
|
+
|
|
483
|
+
SELECT title, SUBSTRING(content FROM 0 FOR 10)
|
|
484
|
+
FROM jpug_doc_contents
|
|
485
|
+
ORDER BY content <&@*> pgroonga_condition('テーブルを消す')
|
|
486
|
+
LIMIT 5;
|
|
487
|
+
-- title | substring
|
|
488
|
+
-- --------------------+---------------
|
|
489
|
+
-- tutorial-table | 2.3. 新しいテ
|
|
490
|
+
-- ddl-basics | 5.1. テーブル
|
|
491
|
+
-- ddl-alter | 5.7. テーブル
|
|
492
|
+
-- sql-delete | DELETEDEL
|
|
493
|
+
-- sql-droptablespace | DROP TABL
|
|
494
|
+
-- (5 rows)
|
|
495
|
+
|
|
496
|
+
= まとめ
|
|
497
|
+
|
|
498
|
+
PostgreSQLから簡単にセマンティックサーチを使えるようになりました!
|
data/theme.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rabbit-slide-komainu8-postgresql-conference-japan-2025
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Horimoto Yasuhiro
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2025-11-21 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rabbit
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 2.0.2
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 2.0.2
|
|
26
|
+
description: |-
|
|
27
|
+
従来のキーワード検索は同義語や曖昧表現に弱く、必要な情報を見落としがちです。
|
|
28
|
+
本講演ではこの課題に対し、意味的な近さで探せるセマンティックサーチに挑戦します。
|
|
29
|
+
量子化と補正で軽量・高速な近似距離計算を実現するRaBitQをGroongaに実装し、PGroongaを通してPostgreSQLから利用可能にしました。
|
|
30
|
+
その仕組みと導入手順、FAQ/ナレッジ検索での活用例を交え、検索が使えるようになるまでの流れを紹介します。
|
|
31
|
+
email:
|
|
32
|
+
- horimoto@clear-code.com
|
|
33
|
+
executables: []
|
|
34
|
+
extensions: []
|
|
35
|
+
extra_rdoc_files: []
|
|
36
|
+
files:
|
|
37
|
+
- ".rabbit"
|
|
38
|
+
- README.md
|
|
39
|
+
- Rakefile
|
|
40
|
+
- config.yaml
|
|
41
|
+
- images/after-clustering.png
|
|
42
|
+
- images/before-clustering.png
|
|
43
|
+
- images/convert-text-to-vector-with-pgroonga.png
|
|
44
|
+
- images/distance.png
|
|
45
|
+
- images/ivf.png
|
|
46
|
+
- images/keyword-search-dic-register.png
|
|
47
|
+
- images/keyword-search-dic.png
|
|
48
|
+
- images/keyword-search-issue.png
|
|
49
|
+
- images/keyword-search-new-dic.png
|
|
50
|
+
- images/keyword-search-new-record.png
|
|
51
|
+
- images/median-values.png
|
|
52
|
+
- images/number-of-dimensions.png
|
|
53
|
+
- images/pgroonga-insert.png
|
|
54
|
+
- images/pgvector-insert.png
|
|
55
|
+
- images/reduction.png
|
|
56
|
+
- images/semantic-search-advantage.png
|
|
57
|
+
- images/semantic-search.png
|
|
58
|
+
- images/text-to-vector.png
|
|
59
|
+
- images/vector-similarity.png
|
|
60
|
+
- pdf/postgresql-conference-japan-2025-pgroonga-with-semantic-search.pdf
|
|
61
|
+
- pgroonga-with-semantic-search-for-print.pdf
|
|
62
|
+
- pgroonga-with-semantic-search.rab
|
|
63
|
+
- theme.rb
|
|
64
|
+
homepage: https://slide.rabbit-shocker.org/authors/komainu8/postgresql-conference-japan-2025/
|
|
65
|
+
licenses:
|
|
66
|
+
- CC-BY-SA-4.0
|
|
67
|
+
- CC-BY-3.0
|
|
68
|
+
- The PostgreSQL Licence
|
|
69
|
+
metadata:
|
|
70
|
+
markup_language: rd
|
|
71
|
+
rdoc_options: []
|
|
72
|
+
require_paths:
|
|
73
|
+
- lib
|
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
75
|
+
requirements:
|
|
76
|
+
- - ">="
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: '0'
|
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
|
+
requirements:
|
|
81
|
+
- - ">="
|
|
82
|
+
- !ruby/object:Gem::Version
|
|
83
|
+
version: '0'
|
|
84
|
+
requirements: []
|
|
85
|
+
rubygems_version: 3.7.2
|
|
86
|
+
specification_version: 4
|
|
87
|
+
summary: PostgreSQLでのセマンティックサーチへの挑戦
|
|
88
|
+
test_files: []
|