rabbit-slide-kou-mysql-and-postgresql-and-japanese-full-text-search-3 2016.9.29.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3bc6d689060f78211a40d95c1205655a49bb908e
4
+ data.tar.gz: 6538eff06dc04f6ddb770b6d62dcf49e2886755a
5
+ SHA512:
6
+ metadata.gz: 8f940a73aa12fb0f0690bb01c9d87d2f5f2d7dce5f06d6d303083c231c4b6fd80452e56a3b5e750cf3f708f7b1255502d8ac5fde70c2df0b9b315dcd7cbd7049
7
+ data.tar.gz: 54ce10dcd062a0f535375f7ba9a00c3b67b92e81b7a8adb25d8d9d5a8a37fd04eed3aaccb379a5c5e1b1789efa6414fd8d85071f28e48c36f3a51de0b911063f
data/.rabbit ADDED
@@ -0,0 +1 @@
1
+ mroonga-and-pgroonga.rab
data/README.rd ADDED
@@ -0,0 +1,46 @@
1
+ = Mroonga・PGroonga利用方法
2
+
3
+ Mroonga・PGroongaをさわり始めた人向けにMroonga・PGroongaを利用する方法を具体的な事例を使いながら紹介します。
4
+
5
+ == ライセンス
6
+
7
+ === スライド
8
+
9
+ CC BY-SA 4.0
10
+
11
+ 原著作者名は以下の通りです。
12
+
13
+ * 須藤功平(またはKouhei Sutou)
14
+
15
+ === 画像
16
+
17
+ ==== Groonga・Mroonga・PGroongaのロゴ
18
+
19
+ CC BY 3.0
20
+
21
+ 原著作者名は以下の通りです。
22
+
23
+ * Groongaプロジェクト
24
+ * Mroongaプロジェクト
25
+ * PGroongaプロジェクト
26
+
27
+ == 作者向け
28
+
29
+ === 表示
30
+
31
+ rake
32
+
33
+ === 公開
34
+
35
+ rake publish
36
+
37
+ == 閲覧者向け
38
+
39
+ === インストール
40
+
41
+ gem install rabbit-slide-kou-mysql-and-postgresql-and-japanese-full-text-search-3
42
+
43
+ === 表示
44
+
45
+ rabbit rabbit-slide-kou-mysql-and-postgresql-and-japanese-full-text-search-3.gem
46
+
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("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,27 @@
1
+ ---
2
+ id: mysql-and-postgresql-and-japanese-full-text-search-3
3
+ base_name: mroonga-and-pgroonga
4
+ tags:
5
+ - rabbit
6
+ - mroonga
7
+ - mysql
8
+ - pgroonga
9
+ - postgresql
10
+ - full-text-search
11
+ presentation_date: 2016-09-29
12
+ version: 2016.9.29.0
13
+ licenses:
14
+ - CC BY 3.0
15
+ - CC BY-SA 4.0
16
+ slideshare_id: mysql-and-postgresql-and-japanese-full-text-search-3
17
+ speaker_deck_id:
18
+ ustream_id:
19
+ vimeo_id:
20
+ youtube_id:
21
+ author:
22
+ markup_language: :rd
23
+ name: 須藤功平
24
+ email: kou@clear-code.com
25
+ rubygems_user: kou
26
+ slideshare_user: kou
27
+ speaker_deck_user:
Binary file
@@ -0,0 +1,652 @@
1
+ = Mroonga\n(('note:と'))\nPGroonga
2
+
3
+ : subtitle
4
+ 導入方法例
5
+ : author
6
+ 須藤功平
7
+ : institution
8
+ クリアコード
9
+ : content-source
10
+ MySQLとPostgreSQLと日本語全文検索
11
+ : date
12
+ 2016-09-29
13
+ : allotted-time
14
+ 20m
15
+ : theme
16
+ groonga
17
+
18
+ = Mroonga・PGroonga
19
+
20
+ * Mroonga(むるんが)
21
+ * (('wait'))MySQLに\n
22
+ 高速日本語全文検索機能を追加する\n
23
+ プロダクト
24
+ * PGroonga(ぴーじーるんが)
25
+ * (('wait'))PostgreSQLに\n
26
+ 高速日本語全文検索機能を追加する\n
27
+ プロダクト
28
+
29
+ = 高速?
30
+
31
+ # image
32
+ # src = http://slide.rabbit-shocker.org/authors/kou/mysql-and-postgresql-and-japanese-full-text-search/mroonga-and-pgroonga.pdf
33
+ # page = 6
34
+ # relative_height = 80
35
+
36
+ (('tag:center'))
37
+ (('note:詳細は第1回の資料を参照'))\n
38
+ (('note:http://slide.rabbit-shocker.org/authors/kou/mysql-and-postgresql-and-japanese-full-text-search/'))
39
+
40
+ = 導入方法例
41
+
42
+ 既存システムへの導入方法を紹介
43
+
44
+ * Redmine
45
+ * チケット管理システム
46
+ * Ruby on Redmineを使用
47
+ * Zulip
48
+ * チャットツール
49
+ * Djangoを使用
50
+
51
+ = Redmine
52
+
53
+ # image
54
+ # src = images/redmine-full-text-search-form.png
55
+ # relative_width = 100
56
+
57
+ = 全文検索プラグイン
58
+
59
+ GitHub: (('tag:x-small:okkez/redmine_full_text_search'))
60
+
61
+ * MySQL・PostgreSQL両方対応
62
+ * MySQLのときはMroongaを利用
63
+ * PostgreSQLのときはPGroongaを利用
64
+
65
+ = 速さ
66
+
67
+ (('tag:center'))
68
+ MySQL + Mroongaのケース
69
+
70
+ # RT
71
+ delimiter = [|]
72
+
73
+ プラグイン | チケット数 | 時間
74
+
75
+ なし | 約3000件 | 467ms
76
+ あり | 約3000件 | 93ms
77
+ あり | 約200万件 | 380ms
78
+
79
+ == スライドプロパティ
80
+
81
+ : groonga-product
82
+
83
+ mroonga
84
+
85
+ = 速さ:コメント
86
+
87
+ # image
88
+ # src = images/redmine-full-text-search-plugin-report.png
89
+ # relative_height = 85
90
+
91
+ (('note:https://twitter.com/akahane92/status/733832496945594368'))
92
+
93
+ == スライドプロパティ
94
+
95
+ : groonga-product
96
+
97
+ mroonga
98
+
99
+ = 使いどころ
100
+
101
+ * Mroonga
102
+ * (('wait'))速さが欲しい
103
+ * (('wait'))トランザクションはいらない
104
+ * PGroonga
105
+ * (('wait'))機能が欲しい
106
+ * (('wait'))トランザクションも欲しい
107
+
108
+ = Redmine
109
+
110
+ * トランザクション必須
111
+ * Mroongaを使うときは一工夫必要
112
+ * PGroongaはそのままで大丈夫
113
+
114
+ = Redmine+Mroonga:方針
115
+
116
+ * (('wait'))チケットテーブルは変えない
117
+ * (('wait'))全文検索用テーブルを別途作成
118
+ * (('wait'))全文検索用テーブルから\n
119
+ チケットテーブルを参照
120
+
121
+ == スライドプロパティ
122
+
123
+ : groonga-product
124
+
125
+ mroonga
126
+
127
+ = マイグレーション
128
+
129
+ # coderay ruby
130
+
131
+ def up
132
+ create_table(:fts_issues, # 全文検索用テーブル作成
133
+ id: false, # idは有効・無効どっちでも可
134
+ options: "ENGINE=Mroonga") do |t|
135
+ t.belongs_to :issue, index: true, null: false
136
+ t.string :subject, default: "", null: false
137
+ t.text :description, limit: 65535, null: false
138
+ end
139
+ execute("INSERT INTO " + # データをコピー
140
+ "fts_issues(issue_id, subject, description) " +
141
+ "SELECT id, subject, description FROM issues;")
142
+ add_index(:fts_issues, [:subject, :description],
143
+ type: "fulltext") # 静的インデックス構築(速い)
144
+ end
145
+
146
+ == スライドプロパティ
147
+
148
+ : groonga-product
149
+
150
+ mroonga
151
+
152
+ = モデル
153
+
154
+ # coderay ruby
155
+
156
+ class FtsIssue < ActiveRecord::Base
157
+ # 実際はissue_idカラムは主キーではない。
158
+ # 主キーなしのテーブルなので
159
+ # Active Recordをごまかしているだけ。
160
+ self.primary_key = :issue_id
161
+ belongs_to :issue
162
+ end
163
+
164
+ == スライドプロパティ
165
+
166
+ : groonga-product
167
+
168
+ mroonga
169
+
170
+ = 保存
171
+
172
+ # coderay ruby
173
+
174
+ class Issue
175
+ # この後にロールバックされることがあるのでカンペキではない
176
+ # 再度同じチケットを更新するかデータを入れ直せば直る
177
+ after_safe do |record|
178
+ fts_record =
179
+ FtsIssue.find_or_initialize_by(issue_id: record.id)
180
+ fts_record.subject = record.subject
181
+ fts_record.description = record.description
182
+ fts_record.save!
183
+ end
184
+ end
185
+
186
+ == スライドプロパティ
187
+
188
+ : groonga-product
189
+
190
+ mroonga
191
+
192
+ = 全文検索
193
+
194
+ # coderay ruby
195
+
196
+ issue.
197
+ joins(:fts_issue).
198
+ where(["MATCH(fts_issues.subject, " +
199
+ "fts_issues.description) " +
200
+ "AGAINST (? IN BOOLEAN MODE)",
201
+ # ↓デフォルトANDで全文検索
202
+ "*D+ #{keywords.join(', ')}"])
203
+
204
+ == スライドプロパティ
205
+
206
+ : groonga-product
207
+
208
+ mroonga
209
+
210
+ = Redmine+Mroonga:まとめ
211
+
212
+ * (('wait'))トランザクション必須
213
+ * 元テーブルを置き換えない
214
+ * 全文検索用テーブルを作成
215
+ * (('wait'))データ
216
+ * アプリが複数テーブルに保存
217
+ * (('wait'))全文検索
218
+ * ((*JOIN*))して((*MATCH AGAINST*))
219
+
220
+ == スライドプロパティ
221
+
222
+ : groonga-product
223
+
224
+ mroonga
225
+
226
+ = Redmine+PGroonga:方針
227
+
228
+ * (('wait'))全文検索用インデックス作成
229
+ * (('wait'))インデックスに主キーを含める
230
+ * 検索スコアーを取得するため
231
+
232
+ == スライドプロパティ
233
+
234
+ : groonga-product
235
+
236
+ pgroonga
237
+
238
+ = マイグレーション
239
+
240
+ # coderay ruby
241
+
242
+ def up
243
+ enable_extension("pgroonga")
244
+ add_index(:issues,
245
+ [:id, :subject, :description],
246
+ using: "pgroonga")
247
+ end
248
+
249
+ == スライドプロパティ
250
+
251
+ : groonga-product
252
+
253
+ pgroonga
254
+
255
+ = モデル
256
+
257
+ 追加・変更なし
258
+
259
+ == スライドプロパティ
260
+
261
+ : groonga-product
262
+
263
+ pgroonga
264
+
265
+ = 保存
266
+
267
+ 追加・変更なし
268
+
269
+ == スライドプロパティ
270
+
271
+ : groonga-product
272
+
273
+ pgroonga
274
+
275
+ = 全文検索
276
+
277
+ # coderay ruby
278
+
279
+ issue.
280
+ # 検索対象のカラムごとに
281
+ # クエリーを指定
282
+ where(["subject @@ ? OR " +
283
+ "description @@ ?",
284
+ keywords.join(", "),
285
+ keywords.join(", ")])
286
+
287
+ == スライドプロパティ
288
+
289
+ : groonga-product
290
+
291
+ pgroonga
292
+
293
+ = Redmine+PGroonga:まとめ
294
+
295
+ * (('wait'))インデックス追加のみでOK
296
+ * トランザクション対応
297
+ * データ保存も変更なし
298
+ * (('wait'))全文検索
299
+
300
+ # coderay sql
301
+ カラム1 @@ 'クエリー' OR
302
+ カラム2 @@ 'クエリー' OR ...
303
+
304
+ == スライドプロパティ
305
+
306
+ : groonga-product
307
+
308
+ pgroonga
309
+
310
+ = Redmine:まとめ
311
+
312
+ * (('wait'))速い!
313
+ * (('wait'))Mroonga
314
+ * 全文検索用テーブルで実現
315
+ * (('wait'))PGroonga
316
+ * 全文検索用インデックスで実現
317
+
318
+ = Zulip
319
+
320
+ # image
321
+ # src = images/zulip-full-text-search-form.png
322
+ # relative_height = 95
323
+
324
+ = Zulipの全文検索機能
325
+
326
+ * (('wait'))現在:textsearch
327
+ * PostgreSQL標準機能
328
+ * 英語のみ対応
329
+ * (('wait'))NEW!:PGroonga
330
+ * オプション(=PGroongaに切替可)
331
+ * 全言語対応(日本語を含む)
332
+
333
+ == スライドプロパティ
334
+
335
+ : groonga-product
336
+
337
+ pgroonga
338
+
339
+ = Zulip+PGroonga:方針
340
+
341
+ * 書き込み速度を落とさない
342
+ * チャットは書き込みが遅いと微妙
343
+ * インデックスは裏で更新\n
344
+ (('note:PGroongaならリアルタイム更新でも大丈夫かも'))
345
+
346
+ (('note:詳細:https://github.com/zulip/zulip/pull/700/files'))
347
+
348
+ == スライドプロパティ
349
+
350
+ : groonga-product
351
+
352
+ pgroonga
353
+
354
+ = マイグレーション
355
+
356
+ # coderay python
357
+
358
+ migrations.RunSQL("""
359
+ ALTER ROLE zulip SET search_path
360
+ TO zulip,public,pgroonga,pg_catalog;
361
+ ALTER TABLE zerver_message
362
+ ADD COLUMN search_pgroonga text;
363
+ UPDATE zerver_message SET search_pgroonga =
364
+ subject || ' ' || rendered_content;
365
+ CREATE INDEX pgrn_index ON zerver_message
366
+ USING pgroonga(search_pgroonga);
367
+ """, "...")
368
+
369
+ == スライドプロパティ
370
+
371
+ : groonga-product
372
+
373
+ pgroonga
374
+
375
+ = 遅延インデックス更新
376
+
377
+ * メッセージ追加・更新時にログ
378
+ * 別プロセスでログを監視
379
+
380
+ == スライドプロパティ
381
+
382
+ : groonga-product
383
+
384
+ pgroonga
385
+
386
+ = 追加・更新時にログ
387
+
388
+ # coderay sql
389
+
390
+ CREATE FUNCTION append_to_fts_update_log()
391
+ RETURNS trigger
392
+ LANGUAGE plpgsql AS $$
393
+ BEGIN
394
+ INSERT INTO fts_update_log (message_id)
395
+ VALUES (NEW.id);
396
+ RETURN NEW;
397
+ END
398
+ $$;
399
+ CREATE TRIGGER update_fts_index_async
400
+ BEFORE INSERT OR UPDATE OF
401
+ subject, rendered_content ON zerver_message
402
+ FOR EACH ROW
403
+ EXECUTE PROCEDURE append_to_fts_update_log();
404
+
405
+ == スライドプロパティ
406
+
407
+ : groonga-product
408
+
409
+ pgroonga
410
+
411
+ = 別プロセスに通知
412
+
413
+ # coderay sql
414
+
415
+ CREATE FUNCTION do_notify_fts_update_log()
416
+ RETURNS trigger
417
+ LANGUAGE plpgsql AS $$
418
+ BEGIN
419
+ NOTIFY fts_update_log;
420
+ RETURN NEW;
421
+ END
422
+ $$;
423
+ CREATE TRIGGER fts_update_log_notify
424
+ AFTER INSERT ON fts_update_log
425
+ FOR EACH STATEMENT
426
+ EXECUTE PROCEDURE do_notify_fts_update_log();
427
+
428
+ == スライドプロパティ
429
+
430
+ : groonga-product
431
+
432
+ pgroonga
433
+
434
+ = インデックス更新プロセス
435
+
436
+ # coderay python
437
+
438
+ import psycopg2
439
+ conn = psycopg2.connect("user=zulip")
440
+ cursor = conn.cursor
441
+ cursor.execute("LISTEN fts_update_log;")
442
+ while True:
443
+ if select.select([conn], [], [], 30) != ([], [], []):
444
+ conn.poll()
445
+ while conn.notifies:
446
+ conn.notifies.pop()
447
+ update_fts_columns(cursor)
448
+
449
+ == スライドプロパティ
450
+
451
+ : groonga-product
452
+
453
+ pgroonga
454
+
455
+ = インデックス更新
456
+
457
+ # coderay python
458
+
459
+ def update_fts_columns(cursor):
460
+ cursor.execute("SELECT id, message_id "
461
+ "FROM fts_update_log;")
462
+ ids = []
463
+ for (id, message_id) in cursor.fetchall():
464
+ cursor.execute("UPDATE zerver_message SET "
465
+ "search_pgroonga = "
466
+ "subject || ' ' || rendered_content "
467
+ "WHERE id = %s", (message_id,))
468
+ ids.append(id)
469
+ cursor.execute("DELETE FROM fts_update_log "
470
+ "WHERE id = ANY(%s)", (ids,))
471
+
472
+ == スライドプロパティ
473
+
474
+ : groonga-product
475
+
476
+ pgroonga
477
+
478
+ = 全文検索
479
+
480
+ # coderay python
481
+
482
+ from sqlalchemy.sql import column
483
+ def _by_search_pgroonga(self, query, operand):
484
+ # WHERE search_pgroonga @@ 'クエリー'
485
+ target = column("search_pgroonga")
486
+ condition = target.op("@@")(operand)
487
+ return query.where(condition)
488
+
489
+ == スライドプロパティ
490
+
491
+ : groonga-product
492
+
493
+ pgroonga
494
+
495
+ = ハイライト
496
+
497
+ # image
498
+ # src = images/zulip-highlight.png
499
+ # relative_height = 95
500
+
501
+ == スライドプロパティ
502
+
503
+ : groonga-product
504
+
505
+ pgroonga
506
+
507
+ = ハイライト:SQL
508
+
509
+ # coderay sql
510
+
511
+ SELECT
512
+ pgroonga.match_positions_byte(
513
+ rendered_content,
514
+ pgroonga.query_extract_keywords('クエリー'))
515
+ AS content_matches,
516
+ pgroonga.match_positions_byte(
517
+ subject,
518
+ pgroonga.query_extract_keywords('クエリー'))
519
+ AS subject_matches
520
+
521
+ == スライドプロパティ
522
+
523
+ : groonga-product
524
+
525
+ pgroonga
526
+
527
+ = ハイライト:SQLAlchemy
528
+
529
+ # coderay python
530
+
531
+ from sqlalchemy import func
532
+ def _by_search_pgroonga(self, query, operand):
533
+ match_positions_byte = func.pgroonga.match_positions_byte
534
+ query_extract_keywords = func.pgroonga.query_extract_keywords
535
+ keywords = query_extract_keywords(operand)
536
+ query = query.column(
537
+ match_positions_byte(column("rendered_content"),
538
+ keywords).label("content_matches"))
539
+ query = query.column(
540
+ match_positions_byte(column("subject"),
541
+ keywords).label("subject_matches"))
542
+ # ...
543
+
544
+ == スライドプロパティ
545
+
546
+ : groonga-product
547
+
548
+ pgroonga
549
+
550
+ = ハイライト:Python
551
+
552
+ # coderay python
553
+
554
+ def highlight_string_bytes_offsets(text, locs):
555
+ # type: (AnyStr, Iterable[Tuple[int, int]]) -> text_type
556
+ string = text.encode('utf-8')
557
+ highlight_start = b'<span class="highlight">'
558
+ highlight_stop = b'</span>'
559
+ pos = 0
560
+ result = b''
561
+ for loc in locs:
562
+ (offset, length) = loc
563
+ result += string[pos:offset]
564
+ result += highlight_start
565
+ result += string[offset:offset + length]
566
+ result += highlight_stop
567
+ pos = offset + length
568
+ result += string[pos:]
569
+ return result.decode('utf-8')
570
+
571
+ == スライドプロパティ
572
+
573
+ : groonga-product
574
+
575
+ pgroonga
576
+
577
+ = ハイライト:補足
578
+
579
+ * 通常はハイライト関数で十分
580
+ * (({pgroonga.highlight_html}))
581
+ * ただし(({ts_headline}))では不十分
582
+ * HTML出力に使えない
583
+
584
+ == スライドプロパティ
585
+
586
+ : groonga-product
587
+
588
+ pgroonga
589
+
590
+ = ハイライト:ts_headline
591
+
592
+ # coderay sql
593
+
594
+ SELECT
595
+ ts_headline('english',
596
+ 'PostgreSQL <is> great!',
597
+ to_tsquery('PostgreSQL'),
598
+ 'HighlightAll=TRUE');
599
+ -- ts_headline
600
+ -- -------------------------------
601
+ -- <b>PostgreSQL</b> <is> great!
602
+ -- (1 row) 不正なHTML↑
603
+
604
+ == スライドプロパティ
605
+
606
+ : groonga-product
607
+
608
+ pgroonga
609
+
610
+ = ハイライト:pgroonga.highlight_html
611
+
612
+ # coderay sql
613
+
614
+ SELECT
615
+ pgroonga.highlight_html(
616
+ 'PostgreSQL <is> great!',
617
+ pgroonga.query_extract_keywords('PostgreSQL'));
618
+ -- highlight_html
619
+ -- ----------------------------------------
620
+ -- <span class="keyword">PostgreSQL</span>
621
+ -- &lt;is&gt; great!
622
+ -- ↑ ↑HTMLエスケープされている
623
+
624
+ == スライドプロパティ
625
+
626
+ : groonga-product
627
+
628
+ pgroonga
629
+
630
+ = Zulip:まとめ
631
+
632
+ * (('wait'))全言語対応全文検索
633
+ * textsearch(1言語のみ)→\n
634
+ PGroonga(全言語)
635
+ * (('wait'))書き込み性能は維持
636
+ * 遅延インデックス更新
637
+
638
+ == スライドプロパティ
639
+
640
+ : groonga-product
641
+
642
+ pgroonga
643
+
644
+ = まとめ
645
+
646
+ * (('wait'))Mroonga・PGroongaの\n
647
+ 導入方法を実例ベースで紹介
648
+ * Redmine:チケット管理システム
649
+ * Zulip:チャットツール
650
+ * (('wait'))トランザクション必須の場合
651
+ * Mroonga:別テーブル作成
652
+ * PGroonga:インデックス追加
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rabbit-slide-kou-mysql-and-postgresql-and-japanese-full-text-search-3
3
+ version: !ruby/object:Gem::Version
4
+ version: 2016.9.29.0
5
+ platform: ruby
6
+ authors:
7
+ - 須藤功平
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-29 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
+ description: Mroonga・PGroongaをさわり始めた人向けにMroonga・PGroongaを利用する方法を具体的な事例を使いながら紹介します。
28
+ email:
29
+ - kou@clear-code.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".rabbit"
35
+ - README.rd
36
+ - Rakefile
37
+ - config.yaml
38
+ - images/redmine-full-text-search-form.png
39
+ - images/redmine-full-text-search-plugin-report.png
40
+ - images/zulip-full-text-search-form.png
41
+ - images/zulip-highlight.png
42
+ - mroonga-and-pgroonga.rab
43
+ - pdf/mysql-and-postgresql-and-japanese-full-text-search-3-mroonga-and-pgroonga.pdf
44
+ homepage: http://slide.rabbit-shocker.org/authors/kou/mysql-and-postgresql-and-japanese-full-text-search-3/
45
+ licenses:
46
+ - CC BY 3.0
47
+ - CC BY-SA 4.0
48
+ metadata: {}
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 2.5.1
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: Mroonga・PGroonga利用方法
69
+ test_files: []