PostgreSQL Conference Japan 2017の資料です。
PostgreSQLが苦手な全文検索機能を強力に補完する拡張機能PGroongaの最新情報を紹介します。PGroongaは単なる全文検索モジュールではありません。PostgreSQLで簡単にリッチな全文検索システムを実現するための機能一式を提供します。PGroongaは最新PostgreSQLへの対応も積極的です。例としてロジカルレプリケーションと組み合わせた活用方法も紹介します。
PostgreSQL Conference Japan 2017の資料です。
PostgreSQLが苦手な全文検索機能を強力に補完する拡張機能PGroongaの最新情報を紹介します。PGroongaは単なる全文検索モジュールではありません。PostgreSQLで簡単にリッチな全文検索システムを実現するための機能一式を提供します。PGroongaは最新PostgreSQLへの対応も積極的です。例としてロジカルレプリケーションと組み合わせた活用方法も紹介します。
9. Lucene Disk Java Application Hits Document Document Document Field Field Field インデックス作成 QueryParser Document Document Document 検索 Analyzer Query Lucene Index IndexReader IndexWriter Analyzer IndexSearcher
10. Luc andra Cassandra Java Application Hits Document Document Document Field Field Field インデックス作成 QueryParser Document Document Document 検索 Analyzer Query Lucene Index IndexReader IndexWriter Analyzer IndexSearcher
11. Index 構成 Keyspace : Lucandra ColumnFamily : Document Key : インデックス名のハッシュ + ドキュメント ID Column Name : フィールド名 Value : フールド値 SuperColumnFamily : TermInfo Key :( インデックス名 + フィールド名 ) のハッシュ + フィールド名 + 単語 SuperColumn : ドキュメント ID Column Name :Frequencies Value : 当該文書中の当該単語の出現頻度 Column Name :Norms Value : 当該単語における文書のノルム Column Name :Offsets Value : 当該文書中の当該単語のバイト位置オフセット Column Name :Position Value : 当該文書中の当該単語の出現位置
13. README より 1 Real-Time indexing (documents become available almost immediately) 2 No optimizing 3 Search 4 Sort 5 Range Queries 6 Delete 7 Wildcards and other Lucene magic 8 Faceting/Highlighting 4,5,7 -> RandomPartitioner では不可
14. 現状できないこと You can't walk the documents with index reader. 現状遅いこと Indexes with many documents and very dense terms.
17. ビルド 下記より tar ball を DL します http://github.com/tjake/Lucandra ant で lucandra.jar をビルドします 対応バージョン Lucene-2.9.1, Cassandra-0.6 $ tar xztf ls tjake-Lucandra-c632677.tar.gz $ cd tjake-Lucandra-c632677 $ ant lucandra.jar
23. サンプルデータ 某飲食店検索 API を使ってこの近辺のデータを 980 件、 TSV にしておく id docID, INDEX, STORE name INDEX(ANALYZED), STORE url STORE address INDEX(ANALYZED), STORE tel INDEX(ANALYZED), STORE budget INDEX, STORE
25. サンプル実行 $ ./run_shop.sh -index data.tsv $ ./run_shop.sh -search name: 丸の内 Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8 12:08:03,436 INFO CassandraProxyClient:145 - Connected to cassandra at 127.0.0.1:9160 name:" 丸の の内 " 12:08:03,863 DEBUG LucandraTermEnum:237 - Found 2 keys in range:OxSo2Td8name 丸の to in 95ms 12:08:03,863 DEBUG LucandraTermEnum:246 - name 丸の has 115 12:08:03,869 DEBUG LucandraTermEnum:246 - name 丸ノ has 10 12:08:03,871 DEBUG LucandraTermEnum:285 - loadTerms: OxSo2Td8name 丸の (3) took 103ms 12:08:03,872 INFO IndexReader:153 - docFreq() took: 232ms 12:08:03,872 INFO IndexReader:153 - docFreq() took: 232ms 12:08:03,916 DEBUG LucandraTermEnum:237 - Found 2 keys in range:OxSo2Td8name の内 to in 43ms 12:08:03,916 DEBUG LucandraTermEnum:246 - name の内 has 115 12:08:03,925 DEBUG LucandraTermEnum:246 - name の勘 has 2
26. サンプル実行 12:08:03,927 DEBUG LucandraTermEnum:285 - loadTerms: OxSo2Td8name の内 (3) took 54ms 12:08:03,927 INFO IndexReader:153 - docFreq() took: 54ms 12:08:03,947 DEBUG LucandraTermEnum:176 - Found OxSo2Td8name 丸の in cache 12:08:03,953 DEBUG LucandraTermEnum:176 - Found OxSo2Td8name の内 in cache Search matched: 0 item(s) あれ? ヒットしない。。。 (途中まではいい感じにみえるけど)
36. $ ./run_shop.sh -search name: 丸の内 Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8 12:08:03,436 INFO CassandraProxyClient:145 - Connected to cassandra at 127.0.0.1:9160 +name: 丸の +name: の内 18:03:39,127 DEBUG LucandraTermEnum:237 - Found 2 keys in range:OxSo2Td8name 丸の to in 109ms 18:03:39,127 DEBUG LucandraTermEnum:246 - name 丸の has 115 18:03:39,128 DEBUG LucandraTermEnum:246 - name 丸ノ has 10 18:03:39,130 DEBUG LucandraTermEnum:285 - loadTerms: OxSo2Td8name 丸の (3) took 112ms 18:03:39,131 INFO IndexReader:153 - docFreq() took: 222ms 18:03:39,189 DEBUG LucandraTermEnum:237 - Found 2 keys in range:OxSo2Td8name の内 to in 57ms 18:03:39,189 DEBUG LucandraTermEnum:246 - name の内 has 115 18:03:39,190 DEBUG LucandraTermEnum:246 - name の勘 has 2 18:03:39,190 DEBUG LucandraTermEnum:285 - loadTerms: OxSo2Td8name の内 (3) took 58ms 18:03:39,190 INFO IndexReader:153 - docFreq() took: 59ms 18:03:39,196 DEBUG LucandraTermEnum:176 - Found OxSo2Td8name 丸の in cache 18:03:39,202 DEBUG LucandraTermEnum:176 - Found OxSo2Td8name の内 in cache
53. ということでソースを追いかけ ... TermInfo (転置インデックス)に Position (単語の出現位置)がないと PhraseQuery が機能しない ことがわかりました。 ※ Position を記録するには、インデクシング時に 指定する必要がある。 ※ 本家 Lucene はなくてもいけるのに ...
54. Index 構成(前回資料より抜粋) Keyspace : Lucandra ColumnFamily : Document Key : インデックス名のハッシュ + ドキュメント ID Column Name : フィールド名 Value : フールド値 SuperColumnFamily : TermInfo Key :( インデックス名 + フィールド名 ) のハッシュ + フィールド名 + 単語 SuperColumn : ドキュメント ID Column Name :Frequencies Value : 当該文書中の当該単語の出現頻度 Column Name :Norms Value : 当該単語における文書のノルム Column Name :Offsets Value : 当該文書中の当該単語のバイト位置オフセット Column Name :Position Value : 当該文書中の当該単語の出現位置 コレ