SlideShare a Scribd company logo
1 of 42
Download to read offline
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
Mroongaと
PGroonga導入方法例
須藤功平 クリアコード
MySQLとPostgreSQLと日本語全文検索
2016-09-29
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
Mroonga・PGroonga
Mroonga(むるんが)
MySQLに
高速日本語全文検索機能を追加する
プロダクト
PGroonga(ぴーじーるんが)
PostgreSQLに
高速日本語全文検索機能を追加する
プロダクト
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
高速?
Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索 Powered by Rabbit 2.1.9
速さ:検索1
キーワード:テレビアニメ
(ヒット数:約2万3千件)
InnoDB ngram 3m2s
InnoDB MeCab 6m20s
Mroonga:1 0.11s
pg_bigm 4s
PGroonga:2 0.29s
詳細は第1回の資料を参照
http://slide.rabbit-shocker.org/authors/kou/mysql-and-
postgresql-and-japanese-full-text-search/
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
導入方法例
既存システムへの導入方法を紹介
Redmine
チケット管理システム
Ruby on Railsを使用
Zulip
チャットツール
Djangoを使用
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
Redmine
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
全文検索プラグイン
GitHub: okkez/redmine_full_text_search
MySQL・PostgreSQL両方対応
MySQLのときはMroongaを利用
PostgreSQLのときはPGroongaを利用
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
速さ
MySQL + Mroongaのケース
プラグイン チケット数 時間
なし 約3000件 467ms
あり 約3000件 93ms
あり 約200万件 380ms
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
速さ:コメント
https://twitter.com/akahane92/status/733832496945594368
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
使いどころ
Mroonga
速さが欲しい
トランザクションはいらない
PGroonga
機能が欲しい
トランザクションも欲しい
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
Redmine
トランザクション必須
Mroongaを使うときは一工夫必要
PGroongaはそのままで大丈夫
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
Redmine+Mroonga:方針
チケットテーブルは変えない
全文検索用テーブルを別途作成
全文検索用テーブルから
チケットテーブルを参照
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
マイグレーション
def up
create_table(:fts_issues, # 全文検索用テーブル作成
id: false, # idは有効・無効どっちでも可
options: "ENGINE=Mroonga") do |t|
t.belongs_to :issue, index: true, null: false
t.string :subject, default: "", null: false
t.text :description, limit: 65535, null: false
end
execute("INSERT INTO " + # データをコピー
"fts_issues(issue_id, subject, description) " +
"SELECT id, subject, description FROM issues;")
add_index(:fts_issues, [:subject, :description],
type: "fulltext") # 静的インデックス構築(速い)
end
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
モデル
class FtsIssue < ActiveRecord::Base
# 実際はissue_idカラムは主キーではない。
# 主キーなしのテーブルなので
# Active Recordをごまかしているだけ。
self.primary_key = :issue_id
belongs_to :issue
end
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
保存
class Issue
# この後にロールバックされることがあるのでカンペキではない
# 再度同じチケットを更新するかデータを入れ直せば直る
after_save do |record|
fts_record =
FtsIssue.find_or_initialize_by(issue_id: record.id)
fts_record.subject = record.subject
fts_record.description = record.description
fts_record.save!
end
end
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
全文検索
issue.
joins(:fts_issue).
where(["MATCH(fts_issues.subject, " +
"fts_issues.description) " +
"AGAINST (? IN BOOLEAN MODE)",
# ↓デフォルトANDで全文検索
"*D+ #{keywords.join(', ')}"])
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
Redmine+Mroonga:まとめ
トランザクション必須
元テーブルを置き換えない
全文検索用テーブルを作成
データ
アプリが複数テーブルに保存
全文検索
JOINしてMATCH AGAINST
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
Redmine+PGroonga:方針
全文検索用インデックス作成
インデックスに主キーを含める
検索スコアーを取得するため
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
マイグレーション
def up
enable_extension("pgroonga")
add_index(:issues,
[:id, :subject, :description],
using: "pgroonga")
end
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
モデル
追加・変更なし
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
保存
追加・変更なし
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
全文検索
issue.
# 検索対象のカラムごとに
# クエリーを指定
where(["subject @@ ? OR " +
"description @@ ?",
keywords.join(", "),
keywords.join(", ")])
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
Redmine+PGroonga:まとめ
インデックス追加のみでOK
トランザクション対応
データ保存も変更なし
全文検索
カラム1 @@ 'クエリー' OR
カラム2 @@ 'クエリー' OR ...
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
Redmine:まとめ
速い!
Mroonga
全文検索用テーブルで実現
PGroonga
全文検索用インデックスで実現
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
Zulip
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
Zulipの全文検索機能
現在:textsearch
PostgreSQL標準機能
英語のみ対応
NEW!:PGroonga
オプション(=PGroongaに切替可)
全言語対応(日本語を含む)
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
Zulip+PGroonga:方針
書き込み速度を落とさない
チャットは書き込みが遅いと微妙
インデックスは裏で更新
PGroongaならリアルタイム更新でも大丈夫かも
詳細:https://github.com/zulip/zulip/pull/700/files
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
マイグレーション
migrations.RunSQL("""
ALTER ROLE zulip SET search_path
TO zulip,public,pgroonga,pg_catalog;
ALTER TABLE zerver_message
ADD COLUMN search_pgroonga text;
UPDATE zerver_message SET search_pgroonga =
subject || ' ' || rendered_content;
CREATE INDEX pgrn_index ON zerver_message
USING pgroonga(search_pgroonga);
""", "...")
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
遅延インデックス更新
メッセージ追加・更新時にログ
別プロセスでログを監視
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
追加・更新時にログ
CREATE FUNCTION append_to_fts_update_log()
RETURNS trigger
LANGUAGE plpgsql AS $$
BEGIN
INSERT INTO fts_update_log (message_id)
VALUES (NEW.id);
RETURN NEW;
END
$$;
CREATE TRIGGER update_fts_index_async
BEFORE INSERT OR UPDATE OF
subject, rendered_content ON zerver_message
FOR EACH ROW
EXECUTE PROCEDURE append_to_fts_update_log();
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
別プロセスに通知
CREATE FUNCTION do_notify_fts_update_log()
RETURNS trigger
LANGUAGE plpgsql AS $$
BEGIN
NOTIFY fts_update_log;
RETURN NEW;
END
$$;
CREATE TRIGGER fts_update_log_notify
AFTER INSERT ON fts_update_log
FOR EACH STATEMENT
EXECUTE PROCEDURE do_notify_fts_update_log();
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
インデックス更新プロセス
import psycopg2
conn = psycopg2.connect("user=zulip")
cursor = conn.cursor
cursor.execute("LISTEN fts_update_log;")
while True:
if select.select([conn], [], [], 30) != ([], [], []):
conn.poll()
while conn.notifies:
conn.notifies.pop()
update_fts_columns(cursor)
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
インデックス更新
def update_fts_columns(cursor):
cursor.execute("SELECT id, message_id "
"FROM fts_update_log;")
ids = []
for (id, message_id) in cursor.fetchall():
cursor.execute("UPDATE zerver_message SET "
"search_pgroonga = "
"subject || ' ' || rendered_content "
"WHERE id = %s", (message_id,))
ids.append(id)
cursor.execute("DELETE FROM fts_update_log "
"WHERE id = ANY(%s)", (ids,))
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
全文検索
from sqlalchemy.sql import column
def _by_search_pgroonga(self, query, operand):
# WHERE search_pgroonga @@ 'クエリー'
target = column("search_pgroonga")
condition = target.op("@@")(operand)
return query.where(condition)
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
ハイライト
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
ハイライト:SQL
SELECT
pgroonga.match_positions_byte(
rendered_content,
pgroonga.query_extract_keywords('クエリー'))
AS content_matches,
pgroonga.match_positions_byte(
subject,
pgroonga.query_extract_keywords('クエリー'))
AS subject_matches
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
ハイライト:SQLAlchemy
from sqlalchemy import func
def _by_search_pgroonga(self, query, operand):
match_positions_byte = func.pgroonga.match_positions_byte
query_extract_keywords = func.pgroonga.query_extract_keywords
keywords = query_extract_keywords(operand)
query = query.column(
match_positions_byte(column("rendered_content"),
keywords).label("content_matches"))
query = query.column(
match_positions_byte(column("subject"),
keywords).label("subject_matches"))
# ...
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
ハイライト:Python
def highlight_string_bytes_offsets(text, locs):
# type: (AnyStr, Iterable[Tuple[int, int]]) -> text_type
string = text.encode('utf-8')
highlight_start = b'<span class="highlight">'
highlight_stop = b'</span>'
pos = 0
result = b''
for loc in locs:
(offset, length) = loc
result += string[pos:offset]
result += highlight_start
result += string[offset:offset + length]
result += highlight_stop
pos = offset + length
result += string[pos:]
return result.decode('utf-8')
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
ハイライト:補足
通常はハイライト関数で十分
pgroonga.highlight_html
ただしts_headlineでは不十分
HTML出力に使えない
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
ハイライト:ts_headline
SELECT
ts_headline('english',
'PostgreSQL <is> great!',
to_tsquery('PostgreSQL'),
'HighlightAll=TRUE');
-- ts_headline
-- -------------------------------
-- <b>PostgreSQL</b> <is> great!
-- (1 row) 不正なHTML↑
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
ハイライト:
pgroonga.highlight_html
SELECT
pgroonga.highlight_html(
'PostgreSQL <is> great!',
pgroonga.query_extract_keywords('PostgreSQL'));
-- highlight_html
-- ----------------------------------------
-- <span class="keyword">PostgreSQL</span>
-- &lt;is&gt; great!
-- ↑ ↑HTMLエスケープされている
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
Zulip:まとめ
全言語対応全文検索
textsearch(1言語のみ)→
PGroonga(全言語)
書き込み性能は維持
遅延インデックス更新
Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0
まとめ
Mroonga・PGroongaの
導入方法を実例ベースで紹介
Redmine:チケット管理システム
Zulip:チャットツール
トランザクション必須の場合
Mroonga:別テーブル作成
PGroonga:インデックス追加

More Related Content

What's hot

初心者向けMroonga・PGroonga情報
初心者向けMroonga・PGroonga情報初心者向けMroonga・PGroonga情報
初心者向けMroonga・PGroonga情報Kouhei Sutou
 
MySQL 8.0でMroonga
MySQL 8.0でMroongaMySQL 8.0でMroonga
MySQL 8.0でMroongaKouhei Sutou
 
MroongaとPGroonga
MroongaとPGroongaMroongaとPGroonga
MroongaとPGroongaKouhei Sutou
 
Mroongaの高速全文検索機能でWordPress内のコンテンツを有効活用!
Mroongaの高速全文検索機能でWordPress内のコンテンツを有効活用!Mroongaの高速全文検索機能でWordPress内のコンテンツを有効活用!
Mroongaの高速全文検索機能でWordPress内のコンテンツを有効活用!Kouhei Sutou
 
Mroonga開発者が来たぞ!
Mroonga開発者が来たぞ!Mroonga開発者が来たぞ!
Mroonga開発者が来たぞ!Kouhei Sutou
 
いろいろ考えると日本語の全文検索もMySQLがいいね!
いろいろ考えると日本語の全文検索もMySQLがいいね!いろいろ考えると日本語の全文検索もMySQLがいいね!
いろいろ考えると日本語の全文検索もMySQLがいいね!Kouhei Sutou
 
RubyもApache Arrowでデータ処理言語の仲間入り
RubyもApache Arrowでデータ処理言語の仲間入りRubyもApache Arrowでデータ処理言語の仲間入り
RubyもApache Arrowでデータ処理言語の仲間入りKouhei Sutou
 
[Postgre sql9.4新機能]レプリケーション・スロットの活用
[Postgre sql9.4新機能]レプリケーション・スロットの活用[Postgre sql9.4新機能]レプリケーション・スロットの活用
[Postgre sql9.4新機能]レプリケーション・スロットの活用Kosuke Kida
 
PostgreSQLレプリケーション(pgcon17j_t4)
PostgreSQLレプリケーション(pgcon17j_t4)PostgreSQLレプリケーション(pgcon17j_t4)
PostgreSQLレプリケーション(pgcon17j_t4)Kosuke Kida
 
MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」
MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」
MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」Kentaro Yoshida
 
pg_bigm(ピージー・バイグラム)を用いた全文検索のしくみ(後編)
pg_bigm(ピージー・バイグラム)を用いた全文検索のしくみ(後編)pg_bigm(ピージー・バイグラム)を用いた全文検索のしくみ(後編)
pg_bigm(ピージー・バイグラム)を用いた全文検索のしくみ(後編)Masahiko Sawada
 
20120405 setsunaセミナー
20120405 setsunaセミナー20120405 setsunaセミナー
20120405 setsunaセミナーTakahiro Iwase
 
Spark Streaming と Spark GraphX を使用したTwitter解析による レコメンドサービス例
Spark Streaming と Spark GraphX を使用したTwitter解析による レコメンドサービス例Spark Streaming と Spark GraphX を使用したTwitter解析による レコメンドサービス例
Spark Streaming と Spark GraphX を使用したTwitter解析による レコメンドサービス例Junichi Noda
 
20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫
20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫
20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫Insight Technology, Inc.
 
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜Takahiro Inoue
 
MongoDBのはじめての運用テキスト
MongoDBのはじめての運用テキストMongoDBのはじめての運用テキスト
MongoDBのはじめての運用テキストAkihiro Kuwano
 

What's hot (20)

初心者向けMroonga・PGroonga情報
初心者向けMroonga・PGroonga情報初心者向けMroonga・PGroonga情報
初心者向けMroonga・PGroonga情報
 
MySQL 8.0でMroonga
MySQL 8.0でMroongaMySQL 8.0でMroonga
MySQL 8.0でMroonga
 
MroongaとPGroonga
MroongaとPGroongaMroongaとPGroonga
MroongaとPGroonga
 
Mroongaの高速全文検索機能でWordPress内のコンテンツを有効活用!
Mroongaの高速全文検索機能でWordPress内のコンテンツを有効活用!Mroongaの高速全文検索機能でWordPress内のコンテンツを有効活用!
Mroongaの高速全文検索機能でWordPress内のコンテンツを有効活用!
 
PGroongaの実装
PGroongaの実装PGroongaの実装
PGroongaの実装
 
Groonga族2015
Groonga族2015Groonga族2015
Groonga族2015
 
Mroonga開発者が来たぞ!
Mroonga開発者が来たぞ!Mroonga開発者が来たぞ!
Mroonga開発者が来たぞ!
 
いろいろ考えると日本語の全文検索もMySQLがいいね!
いろいろ考えると日本語の全文検索もMySQLがいいね!いろいろ考えると日本語の全文検索もMySQLがいいね!
いろいろ考えると日本語の全文検索もMySQLがいいね!
 
RubyもApache Arrowでデータ処理言語の仲間入り
RubyもApache Arrowでデータ処理言語の仲間入りRubyもApache Arrowでデータ処理言語の仲間入り
RubyもApache Arrowでデータ処理言語の仲間入り
 
Groonga族2016
Groonga族2016Groonga族2016
Groonga族2016
 
[Postgre sql9.4新機能]レプリケーション・スロットの活用
[Postgre sql9.4新機能]レプリケーション・スロットの活用[Postgre sql9.4新機能]レプリケーション・スロットの活用
[Postgre sql9.4新機能]レプリケーション・スロットの活用
 
PostgreSQLレプリケーション(pgcon17j_t4)
PostgreSQLレプリケーション(pgcon17j_t4)PostgreSQLレプリケーション(pgcon17j_t4)
PostgreSQLレプリケーション(pgcon17j_t4)
 
MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」
MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」
MySQL Casual Talks Vol.4 「MySQL-5.6で始める全文検索 〜InnoDB FTS編〜」
 
pg_bigm(ピージー・バイグラム)を用いた全文検索のしくみ(後編)
pg_bigm(ピージー・バイグラム)を用いた全文検索のしくみ(後編)pg_bigm(ピージー・バイグラム)を用いた全文検索のしくみ(後編)
pg_bigm(ピージー・バイグラム)を用いた全文検索のしくみ(後編)
 
JSONBはPostgreSQL9.5でいかに改善されたのか
JSONBはPostgreSQL9.5でいかに改善されたのかJSONBはPostgreSQL9.5でいかに改善されたのか
JSONBはPostgreSQL9.5でいかに改善されたのか
 
20120405 setsunaセミナー
20120405 setsunaセミナー20120405 setsunaセミナー
20120405 setsunaセミナー
 
Spark Streaming と Spark GraphX を使用したTwitter解析による レコメンドサービス例
Spark Streaming と Spark GraphX を使用したTwitter解析による レコメンドサービス例Spark Streaming と Spark GraphX を使用したTwitter解析による レコメンドサービス例
Spark Streaming と Spark GraphX を使用したTwitter解析による レコメンドサービス例
 
20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫
20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫
20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫
 
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜
 
MongoDBのはじめての運用テキスト
MongoDBのはじめての運用テキストMongoDBのはじめての運用テキスト
MongoDBのはじめての運用テキスト
 

Similar to Mroonga・PGroonga導入方法

Droongaのはじめかた
DroongaのはじめかたDroongaのはじめかた
DroongaのはじめかたKouhei Sutou
 
はじめてのPython
はじめてのPythonはじめてのPython
はじめてのPythonKatsumi Honda
 
仕事で使うちょっとしたコードをOSSとして開発メンテしていく - Django Redshift Backend の開発 - PyCon JP 2016
仕事で使うちょっとしたコードをOSSとして開発メンテしていく- Django Redshift Backend の開発 - PyCon JP 2016仕事で使うちょっとしたコードをOSSとして開発メンテしていく- Django Redshift Backend の開発 - PyCon JP 2016
仕事で使うちょっとしたコードをOSSとして開発メンテしていく - Django Redshift Backend の開発 - PyCon JP 2016Takayuki Shimizukawa
 
Sohu邮箱的python经验
Sohu邮箱的python经验Sohu邮箱的python经验
Sohu邮箱的python经验Ryan Poy
 
Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Kenta Oono
 
Prometheus入門から運用まで徹底解説
Prometheus入門から運用まで徹底解説Prometheus入門から運用まで徹底解説
Prometheus入門から運用まで徹底解説貴仁 大和屋
 
ジャパネットQB GPars
ジャパネットQB GParsジャパネットQB GPars
ジャパネットQB GParsTakahiro Sugiura
 
Pycon2014 django performance
Pycon2014 django performancePycon2014 django performance
Pycon2014 django performancehirokiky
 
Amebaにおけるレコメンデーションシステムの紹介
Amebaにおけるレコメンデーションシステムの紹介Amebaにおけるレコメンデーションシステムの紹介
Amebaにおけるレコメンデーションシステムの紹介cyberagent
 
blogサービスの全文検索の話 - #groonga を囲む夕べ
blogサービスの全文検索の話 - #groonga を囲む夕べblogサービスの全文検索の話 - #groonga を囲む夕べ
blogサービスの全文検索の話 - #groonga を囲む夕べMasahiro Nagano
 
03 piggyback -by-simple-code-public
03 piggyback -by-simple-code-public03 piggyback -by-simple-code-public
03 piggyback -by-simple-code-publicSmz Nbys
 
株式会社インタースペース 清水様 登壇資料
株式会社インタースペース 清水様 登壇資料株式会社インタースペース 清水様 登壇資料
株式会社インタースペース 清水様 登壇資料leverages_event
 
Twitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackTwitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackkimukou_26 Kimukou
 
Anaconda & NumbaPro 使ってみた
Anaconda & NumbaPro 使ってみたAnaconda & NumbaPro 使ってみた
Anaconda & NumbaPro 使ってみたYosuke Onoue
 
機械学習プロジェクトにおける Cloud AI Platform の使い方 (2018-11-19)
機械学習プロジェクトにおける Cloud AI Platform の使い方 (2018-11-19)機械学習プロジェクトにおける Cloud AI Platform の使い方 (2018-11-19)
機械学習プロジェクトにおける Cloud AI Platform の使い方 (2018-11-19)Yaboo Oyabu
 
はじめてのDroonga
はじめてのDroongaはじめてのDroonga
はじめてのDroongaHiroshi Yuki
 
Redmineosaka 20 talk_crosspoints
Redmineosaka 20 talk_crosspointsRedmineosaka 20 talk_crosspoints
Redmineosaka 20 talk_crosspointsShinji Tamura
 

Similar to Mroonga・PGroonga導入方法 (20)

Droongaのはじめかた
DroongaのはじめかたDroongaのはじめかた
Droongaのはじめかた
 
はじめてのPython
はじめてのPythonはじめてのPython
はじめてのPython
 
仕事で使うちょっとしたコードをOSSとして開発メンテしていく - Django Redshift Backend の開発 - PyCon JP 2016
仕事で使うちょっとしたコードをOSSとして開発メンテしていく- Django Redshift Backend の開発 - PyCon JP 2016仕事で使うちょっとしたコードをOSSとして開発メンテしていく- Django Redshift Backend の開発 - PyCon JP 2016
仕事で使うちょっとしたコードをOSSとして開発メンテしていく - Django Redshift Backend の開発 - PyCon JP 2016
 
Sohu邮箱的python经验
Sohu邮箱的python经验Sohu邮箱的python经验
Sohu邮箱的python经验
 
Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)Introduction to Chainer (LL Ring Recursive)
Introduction to Chainer (LL Ring Recursive)
 
Prometheus入門から運用まで徹底解説
Prometheus入門から運用まで徹底解説Prometheus入門から運用まで徹底解説
Prometheus入門から運用まで徹底解説
 
ジャパネットQB GPars
ジャパネットQB GParsジャパネットQB GPars
ジャパネットQB GPars
 
pg_bigmを用いた全文検索のしくみ(前編)
pg_bigmを用いた全文検索のしくみ(前編)pg_bigmを用いた全文検索のしくみ(前編)
pg_bigmを用いた全文検索のしくみ(前編)
 
Pycon2014 django performance
Pycon2014 django performancePycon2014 django performance
Pycon2014 django performance
 
Groongaの特徴
Groongaの特徴Groongaの特徴
Groongaの特徴
 
Amebaにおけるレコメンデーションシステムの紹介
Amebaにおけるレコメンデーションシステムの紹介Amebaにおけるレコメンデーションシステムの紹介
Amebaにおけるレコメンデーションシステムの紹介
 
blogサービスの全文検索の話 - #groonga を囲む夕べ
blogサービスの全文検索の話 - #groonga を囲む夕べblogサービスの全文検索の話 - #groonga を囲む夕べ
blogサービスの全文検索の話 - #groonga を囲む夕べ
 
03 piggyback -by-simple-code-public
03 piggyback -by-simple-code-public03 piggyback -by-simple-code-public
03 piggyback -by-simple-code-public
 
株式会社インタースペース 清水様 登壇資料
株式会社インタースペース 清水様 登壇資料株式会社インタースペース 清水様 登壇資料
株式会社インタースペース 清水様 登壇資料
 
Twitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hackTwitter sphere of #twitter4j #twtr_hack
Twitter sphere of #twitter4j #twtr_hack
 
Anaconda & NumbaPro 使ってみた
Anaconda & NumbaPro 使ってみたAnaconda & NumbaPro 使ってみた
Anaconda & NumbaPro 使ってみた
 
R -> Python
R -> PythonR -> Python
R -> Python
 
機械学習プロジェクトにおける Cloud AI Platform の使い方 (2018-11-19)
機械学習プロジェクトにおける Cloud AI Platform の使い方 (2018-11-19)機械学習プロジェクトにおける Cloud AI Platform の使い方 (2018-11-19)
機械学習プロジェクトにおける Cloud AI Platform の使い方 (2018-11-19)
 
はじめてのDroonga
はじめてのDroongaはじめてのDroonga
はじめてのDroonga
 
Redmineosaka 20 talk_crosspoints
Redmineosaka 20 talk_crosspointsRedmineosaka 20 talk_crosspoints
Redmineosaka 20 talk_crosspoints
 

More from Kouhei Sutou

RubyKaigi 2022 - Fast data processing with Ruby and Apache Arrow
RubyKaigi 2022 - Fast data processing with Ruby and Apache ArrowRubyKaigi 2022 - Fast data processing with Ruby and Apache Arrow
RubyKaigi 2022 - Fast data processing with Ruby and Apache ArrowKouhei Sutou
 
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021Kouhei Sutou
 
RubyKaigi Takeout 2021 - Red Arrow - Ruby and Apache Arrow
RubyKaigi Takeout 2021 - Red Arrow - Ruby and Apache ArrowRubyKaigi Takeout 2021 - Red Arrow - Ruby and Apache Arrow
RubyKaigi Takeout 2021 - Red Arrow - Ruby and Apache ArrowKouhei Sutou
 
Rubyと仕事と自由なソフトウェア
Rubyと仕事と自由なソフトウェアRubyと仕事と自由なソフトウェア
Rubyと仕事と自由なソフトウェアKouhei Sutou
 
Apache Arrowフォーマットはなぜ速いのか
Apache Arrowフォーマットはなぜ速いのかApache Arrowフォーマットはなぜ速いのか
Apache Arrowフォーマットはなぜ速いのかKouhei Sutou
 
Apache Arrow 1.0 - A cross-language development platform for in-memory data
Apache Arrow 1.0 - A cross-language development platform for in-memory dataApache Arrow 1.0 - A cross-language development platform for in-memory data
Apache Arrow 1.0 - A cross-language development platform for in-memory dataKouhei Sutou
 
Redmine検索の未来像
Redmine検索の未来像Redmine検索の未来像
Redmine検索の未来像Kouhei Sutou
 
Apache Arrow - A cross-language development platform for in-memory data
Apache Arrow - A cross-language development platform for in-memory dataApache Arrow - A cross-language development platform for in-memory data
Apache Arrow - A cross-language development platform for in-memory dataKouhei Sutou
 
Better CSV processing with Ruby 2.6
Better CSV processing with Ruby 2.6Better CSV processing with Ruby 2.6
Better CSV processing with Ruby 2.6Kouhei Sutou
 
Apache Arrow - データ処理ツールの次世代プラットフォーム
Apache Arrow - データ処理ツールの次世代プラットフォームApache Arrow - データ処理ツールの次世代プラットフォーム
Apache Arrow - データ処理ツールの次世代プラットフォームKouhei Sutou
 
PGroonga 2 – Make PostgreSQL rich full text search system backend!
PGroonga 2 – Make PostgreSQL rich full text search system backend!PGroonga 2 – Make PostgreSQL rich full text search system backend!
PGroonga 2 – Make PostgreSQL rich full text search system backend!Kouhei Sutou
 
Improve extension API: C++ as better language for extension
Improve extension API: C++ as better language for extensionImprove extension API: C++ as better language for extension
Improve extension API: C++ as better language for extensionKouhei Sutou
 
全文検索でRedmineをさらに活用!
全文検索でRedmineをさらに活用!全文検索でRedmineをさらに活用!
全文検索でRedmineをさらに活用!Kouhei Sutou
 
株式会社クリアコード
株式会社クリアコード株式会社クリアコード
株式会社クリアコードKouhei Sutou
 

More from Kouhei Sutou (20)

RubyKaigi 2022 - Fast data processing with Ruby and Apache Arrow
RubyKaigi 2022 - Fast data processing with Ruby and Apache ArrowRubyKaigi 2022 - Fast data processing with Ruby and Apache Arrow
RubyKaigi 2022 - Fast data processing with Ruby and Apache Arrow
 
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021
 
RubyKaigi Takeout 2021 - Red Arrow - Ruby and Apache Arrow
RubyKaigi Takeout 2021 - Red Arrow - Ruby and Apache ArrowRubyKaigi Takeout 2021 - Red Arrow - Ruby and Apache Arrow
RubyKaigi Takeout 2021 - Red Arrow - Ruby and Apache Arrow
 
Rubyと仕事と自由なソフトウェア
Rubyと仕事と自由なソフトウェアRubyと仕事と自由なソフトウェア
Rubyと仕事と自由なソフトウェア
 
Apache Arrowフォーマットはなぜ速いのか
Apache Arrowフォーマットはなぜ速いのかApache Arrowフォーマットはなぜ速いのか
Apache Arrowフォーマットはなぜ速いのか
 
Apache Arrow 1.0 - A cross-language development platform for in-memory data
Apache Arrow 1.0 - A cross-language development platform for in-memory dataApache Arrow 1.0 - A cross-language development platform for in-memory data
Apache Arrow 1.0 - A cross-language development platform for in-memory data
 
Apache Arrow 2019
Apache Arrow 2019Apache Arrow 2019
Apache Arrow 2019
 
Redmine検索の未来像
Redmine検索の未来像Redmine検索の未来像
Redmine検索の未来像
 
Apache Arrow - A cross-language development platform for in-memory data
Apache Arrow - A cross-language development platform for in-memory dataApache Arrow - A cross-language development platform for in-memory data
Apache Arrow - A cross-language development platform for in-memory data
 
Better CSV processing with Ruby 2.6
Better CSV processing with Ruby 2.6Better CSV processing with Ruby 2.6
Better CSV processing with Ruby 2.6
 
Apache Arrow
Apache ArrowApache Arrow
Apache Arrow
 
Apache Arrow - データ処理ツールの次世代プラットフォーム
Apache Arrow - データ処理ツールの次世代プラットフォームApache Arrow - データ処理ツールの次世代プラットフォーム
Apache Arrow - データ処理ツールの次世代プラットフォーム
 
Apache Arrow
Apache ArrowApache Arrow
Apache Arrow
 
My way with Ruby
My way with RubyMy way with Ruby
My way with Ruby
 
Red Data Tools
Red Data ToolsRed Data Tools
Red Data Tools
 
PGroonga 2 – Make PostgreSQL rich full text search system backend!
PGroonga 2 – Make PostgreSQL rich full text search system backend!PGroonga 2 – Make PostgreSQL rich full text search system backend!
PGroonga 2 – Make PostgreSQL rich full text search system backend!
 
Improve extension API: C++ as better language for extension
Improve extension API: C++ as better language for extensionImprove extension API: C++ as better language for extension
Improve extension API: C++ as better language for extension
 
PGroonga & Zulip
PGroonga & ZulipPGroonga & Zulip
PGroonga & Zulip
 
全文検索でRedmineをさらに活用!
全文検索でRedmineをさらに活用!全文検索でRedmineをさらに活用!
全文検索でRedmineをさらに活用!
 
株式会社クリアコード
株式会社クリアコード株式会社クリアコード
株式会社クリアコード
 

Recently uploaded

TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 

Recently uploaded (9)

TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 

Mroonga・PGroonga導入方法

  • 1. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 Mroongaと PGroonga導入方法例 須藤功平 クリアコード MySQLとPostgreSQLと日本語全文検索 2016-09-29
  • 2. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 Mroonga・PGroonga Mroonga(むるんが) MySQLに 高速日本語全文検索機能を追加する プロダクト PGroonga(ぴーじーるんが) PostgreSQLに 高速日本語全文検索機能を追加する プロダクト
  • 3. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 高速? Mroonga と PGroonga - Groongaを使って MySQLとPostgreSQLで日本語全文検索 Powered by Rabbit 2.1.9 速さ:検索1 キーワード:テレビアニメ (ヒット数:約2万3千件) InnoDB ngram 3m2s InnoDB MeCab 6m20s Mroonga:1 0.11s pg_bigm 4s PGroonga:2 0.29s 詳細は第1回の資料を参照 http://slide.rabbit-shocker.org/authors/kou/mysql-and- postgresql-and-japanese-full-text-search/
  • 4. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 導入方法例 既存システムへの導入方法を紹介 Redmine チケット管理システム Ruby on Railsを使用 Zulip チャットツール Djangoを使用
  • 5. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 Redmine
  • 6. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 全文検索プラグイン GitHub: okkez/redmine_full_text_search MySQL・PostgreSQL両方対応 MySQLのときはMroongaを利用 PostgreSQLのときはPGroongaを利用
  • 7. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 速さ MySQL + Mroongaのケース プラグイン チケット数 時間 なし 約3000件 467ms あり 約3000件 93ms あり 約200万件 380ms
  • 8. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 速さ:コメント https://twitter.com/akahane92/status/733832496945594368
  • 9. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 使いどころ Mroonga 速さが欲しい トランザクションはいらない PGroonga 機能が欲しい トランザクションも欲しい
  • 10. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 Redmine トランザクション必須 Mroongaを使うときは一工夫必要 PGroongaはそのままで大丈夫
  • 11. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 Redmine+Mroonga:方針 チケットテーブルは変えない 全文検索用テーブルを別途作成 全文検索用テーブルから チケットテーブルを参照
  • 12. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 マイグレーション def up create_table(:fts_issues, # 全文検索用テーブル作成 id: false, # idは有効・無効どっちでも可 options: "ENGINE=Mroonga") do |t| t.belongs_to :issue, index: true, null: false t.string :subject, default: "", null: false t.text :description, limit: 65535, null: false end execute("INSERT INTO " + # データをコピー "fts_issues(issue_id, subject, description) " + "SELECT id, subject, description FROM issues;") add_index(:fts_issues, [:subject, :description], type: "fulltext") # 静的インデックス構築(速い) end
  • 13. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 モデル class FtsIssue < ActiveRecord::Base # 実際はissue_idカラムは主キーではない。 # 主キーなしのテーブルなので # Active Recordをごまかしているだけ。 self.primary_key = :issue_id belongs_to :issue end
  • 14. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 保存 class Issue # この後にロールバックされることがあるのでカンペキではない # 再度同じチケットを更新するかデータを入れ直せば直る after_save do |record| fts_record = FtsIssue.find_or_initialize_by(issue_id: record.id) fts_record.subject = record.subject fts_record.description = record.description fts_record.save! end end
  • 15. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 全文検索 issue. joins(:fts_issue). where(["MATCH(fts_issues.subject, " + "fts_issues.description) " + "AGAINST (? IN BOOLEAN MODE)", # ↓デフォルトANDで全文検索 "*D+ #{keywords.join(', ')}"])
  • 16. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 Redmine+Mroonga:まとめ トランザクション必須 元テーブルを置き換えない 全文検索用テーブルを作成 データ アプリが複数テーブルに保存 全文検索 JOINしてMATCH AGAINST
  • 17. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 Redmine+PGroonga:方針 全文検索用インデックス作成 インデックスに主キーを含める 検索スコアーを取得するため
  • 18. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 マイグレーション def up enable_extension("pgroonga") add_index(:issues, [:id, :subject, :description], using: "pgroonga") end
  • 19. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 モデル 追加・変更なし
  • 20. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 保存 追加・変更なし
  • 21. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 全文検索 issue. # 検索対象のカラムごとに # クエリーを指定 where(["subject @@ ? OR " + "description @@ ?", keywords.join(", "), keywords.join(", ")])
  • 22. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 Redmine+PGroonga:まとめ インデックス追加のみでOK トランザクション対応 データ保存も変更なし 全文検索 カラム1 @@ 'クエリー' OR カラム2 @@ 'クエリー' OR ...
  • 23. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 Redmine:まとめ 速い! Mroonga 全文検索用テーブルで実現 PGroonga 全文検索用インデックスで実現
  • 24. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 Zulip
  • 25. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 Zulipの全文検索機能 現在:textsearch PostgreSQL標準機能 英語のみ対応 NEW!:PGroonga オプション(=PGroongaに切替可) 全言語対応(日本語を含む)
  • 26. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 Zulip+PGroonga:方針 書き込み速度を落とさない チャットは書き込みが遅いと微妙 インデックスは裏で更新 PGroongaならリアルタイム更新でも大丈夫かも 詳細:https://github.com/zulip/zulip/pull/700/files
  • 27. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 マイグレーション migrations.RunSQL(""" ALTER ROLE zulip SET search_path TO zulip,public,pgroonga,pg_catalog; ALTER TABLE zerver_message ADD COLUMN search_pgroonga text; UPDATE zerver_message SET search_pgroonga = subject || ' ' || rendered_content; CREATE INDEX pgrn_index ON zerver_message USING pgroonga(search_pgroonga); """, "...")
  • 28. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 遅延インデックス更新 メッセージ追加・更新時にログ 別プロセスでログを監視
  • 29. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 追加・更新時にログ CREATE FUNCTION append_to_fts_update_log() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN INSERT INTO fts_update_log (message_id) VALUES (NEW.id); RETURN NEW; END $$; CREATE TRIGGER update_fts_index_async BEFORE INSERT OR UPDATE OF subject, rendered_content ON zerver_message FOR EACH ROW EXECUTE PROCEDURE append_to_fts_update_log();
  • 30. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 別プロセスに通知 CREATE FUNCTION do_notify_fts_update_log() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN NOTIFY fts_update_log; RETURN NEW; END $$; CREATE TRIGGER fts_update_log_notify AFTER INSERT ON fts_update_log FOR EACH STATEMENT EXECUTE PROCEDURE do_notify_fts_update_log();
  • 31. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 インデックス更新プロセス import psycopg2 conn = psycopg2.connect("user=zulip") cursor = conn.cursor cursor.execute("LISTEN fts_update_log;") while True: if select.select([conn], [], [], 30) != ([], [], []): conn.poll() while conn.notifies: conn.notifies.pop() update_fts_columns(cursor)
  • 32. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 インデックス更新 def update_fts_columns(cursor): cursor.execute("SELECT id, message_id " "FROM fts_update_log;") ids = [] for (id, message_id) in cursor.fetchall(): cursor.execute("UPDATE zerver_message SET " "search_pgroonga = " "subject || ' ' || rendered_content " "WHERE id = %s", (message_id,)) ids.append(id) cursor.execute("DELETE FROM fts_update_log " "WHERE id = ANY(%s)", (ids,))
  • 33. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 全文検索 from sqlalchemy.sql import column def _by_search_pgroonga(self, query, operand): # WHERE search_pgroonga @@ 'クエリー' target = column("search_pgroonga") condition = target.op("@@")(operand) return query.where(condition)
  • 34. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 ハイライト
  • 35. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 ハイライト:SQL SELECT pgroonga.match_positions_byte( rendered_content, pgroonga.query_extract_keywords('クエリー')) AS content_matches, pgroonga.match_positions_byte( subject, pgroonga.query_extract_keywords('クエリー')) AS subject_matches
  • 36. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 ハイライト:SQLAlchemy from sqlalchemy import func def _by_search_pgroonga(self, query, operand): match_positions_byte = func.pgroonga.match_positions_byte query_extract_keywords = func.pgroonga.query_extract_keywords keywords = query_extract_keywords(operand) query = query.column( match_positions_byte(column("rendered_content"), keywords).label("content_matches")) query = query.column( match_positions_byte(column("subject"), keywords).label("subject_matches")) # ...
  • 37. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 ハイライト:Python def highlight_string_bytes_offsets(text, locs): # type: (AnyStr, Iterable[Tuple[int, int]]) -> text_type string = text.encode('utf-8') highlight_start = b'<span class="highlight">' highlight_stop = b'</span>' pos = 0 result = b'' for loc in locs: (offset, length) = loc result += string[pos:offset] result += highlight_start result += string[offset:offset + length] result += highlight_stop pos = offset + length result += string[pos:] return result.decode('utf-8')
  • 38. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 ハイライト:補足 通常はハイライト関数で十分 pgroonga.highlight_html ただしts_headlineでは不十分 HTML出力に使えない
  • 39. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 ハイライト:ts_headline SELECT ts_headline('english', 'PostgreSQL <is> great!', to_tsquery('PostgreSQL'), 'HighlightAll=TRUE'); -- ts_headline -- ------------------------------- -- <b>PostgreSQL</b> <is> great! -- (1 row) 不正なHTML↑
  • 40. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 ハイライト: pgroonga.highlight_html SELECT pgroonga.highlight_html( 'PostgreSQL <is> great!', pgroonga.query_extract_keywords('PostgreSQL')); -- highlight_html -- ---------------------------------------- -- <span class="keyword">PostgreSQL</span> -- &lt;is&gt; great! -- ↑ ↑HTMLエスケープされている
  • 41. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 Zulip:まとめ 全言語対応全文検索 textsearch(1言語のみ)→ PGroonga(全言語) 書き込み性能は維持 遅延インデックス更新
  • 42. Mroonga と PGroonga - 導入方法例 Powered by Rabbit 2.2.0 まとめ Mroonga・PGroongaの 導入方法を実例ベースで紹介 Redmine:チケット管理システム Zulip:チャットツール トランザクション必須の場合 Mroonga:別テーブル作成 PGroonga:インデックス追加