SlideShare a Scribd company logo
Lucandra を使ってみる 2010/6/25 佐藤 史彦
Agenda Lucandra ってなに? Lucandra の構成 できること 使ってみる まとめ
Lucandra ってなに?
A Cassandra-based Lucene backend Author : Jake Luciani
カサンドラベースのルシーンバックエンド 作者   :  ジェイク  ルシアーニ
Cassandra にインデックス機能を 追加する、というより Lucene/Solr のインデックスを リアルタイムに作成、かつ 手軽にスケールさせる目的で インデックスのストア先に Cassandra を採用したもの
実装例  http://sparse.ly/
Lucandra の構成
Lucene Disk Java Application Hits Document Document Document Field Field Field インデックス作成 QueryParser Document Document Document 検索 Analyzer Query Lucene Index IndexReader IndexWriter Analyzer IndexSearcher
Luc andra Cassandra Java Application Hits Document Document Document Field Field Field インデックス作成 QueryParser Document Document Document 検索 Analyzer Query Lucene Index IndexReader IndexWriter Analyzer IndexSearcher
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 : 当該文書中の当該単語の出現位置
できること
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 では不可
現状できないこと You can't walk the documents with index reader. 現状遅いこと Indexes with many documents and very dense terms.
使ってみる
環境 Cassandra は 0.6.2 ( 単体 )
ビルド 下記より 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
storage-conf.xml の差し替え storage-conf.xml を差し替えて Cassandra を立ち上げます ※ Cassandra のデータが空である前提 $ cp config/storage-conf.xml ¥  /usr/local/cassandra/conf/ $ /usr/local/cassandra/bin/cassandra
storage-conf.xml のポイント <Keyspace  Name=&quot;Lucandra&quot; > <ColumnFamily CompareWith=&quot;BytesType&quot;  Name=&quot;Documents&quot;  KeysCached=&quot;10%&quot; /> <ColumnFamily ColumnType=&quot;Super&quot; CompareWith=&quot;BytesType&quot;  CompareSubcolumnsWith=&quot;BytesType&quot; Name=&quot;TermInfo&quot; KeysCached=&quot;10%&quot; /> : : </Keyspace> <Partitioner> org.apache.cassandra.dht.OrderPreservingPartitioner </Partitioner> クラスタノードでは InitialToken も適切に設定すべき
Demo(BookmarksDemo) を試す Cassandra Bookmarks Demo Hits Document Document Document Field:url Field:title Field:tags -index QueryParser Document Document Document -search SimpleAnalyzer Query Lucene Index IndexReader IndexWriter SimpleAnalyzer IndexSearcher TSV File
動作確認 $ ./run_demo.sh -index bookmark.tsv $ ./run_demo.sh -search title:linu* Search matched: 5 item(s) 1. ZFS on FUSE/Linux http://zfs-on-fuse.blogspot.com/ 2. Set Up Postfix For Relaying Emails Through Another  Mailserver | HowtoForge - Linux Howtos and Tutorials http://www.howtoforge.com/postfix_relaying_through_ another_mailserver 3. Debian GNU/Linux System Administration Resources http://www.debian-administration.org/ 4. Linux Scalability http://www.cs.wisc.edu/condor/condorg/linux_scalabi lity.html 5. LinuxDevCenter.com -- Cache-Friendly Web Pages http://www.linuxdevcenter.com/pub/a/linux/2002/02/ 28/cachefriendly.html
ひとまず動作することが確認できたので、日本語のサンプルを作ってみる。
サンプルデータ 某飲食店検索 API を使ってこの近辺のデータを 980 件、 TSV にしておく id docID, INDEX, STORE name INDEX(ANALYZED), STORE url STORE address INDEX(ANALYZED), STORE tel INDEX(ANALYZED), STORE budget INDEX, STORE
サンプルプログラム BookmarksDemo をコピーして、 下記の変更を加えます * Analyzer を変更 SimpleAnalyzer -> CJKAnalyzer *  インデックス名を変更 bookmarks -> shopsearch *  ドキュメントフィールドを  サンプルデータにあわせて変更
サンプル実行 $ ./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:&quot; 丸の の内 &quot; 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
サンプル実行 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) あれ? ヒットしない。。。 (途中まではいい感じにみえるけど)
要因調査 CJKAnalyzer を使用した場合、 QueryParser.parse() は CJK 文字列を bi-gram に分割した Query を返却する name: 丸の内  ↓ name:&quot; 丸の の内 &quot;
要因調査 この際の Query は、 PhraseQuery の インスタンスになっている PhraseQuery が使用される場合、 LucandraTermDocs.nextPosition() が うまく機能しない (?) ためか、 Hit した ドキュメントが抽出できていない
要因調査 そこが問題のようだが、つっこんで 調査しないと影響範囲とか読めない ので、回避方法を検討。。。 解明しました。 詳細は付け足し資料 ( 補足編 ) にて。
回避方法 そもそもなぜ bi-gram が PhraseQuery として扱われるのかを調べていたら、 下記の情報がありました 関口宏司の Lucene ブログ http://lucene.jugem.jp/?cid=5
回避方法 これによると、 Lucene3.1 からは Analyzer により複数の単語が生成される場合、 PhraseQuery が生成される仕様を BooleanQuery に変えるべし と提案されており、 patch が提供されている
回避方法 このパッチを強引にも 2.9.1 にあてます $ tar xzf lucene-2.9.1.tar.gz $ cd lucene-2.9.1 $ curl -O https://issues.apache.org/jira/secure/attachment /12445136/LUCENE-2458.patch $ patch -b -p1 < LUCENE-2458.patch
回避方法 このままではビルドが通らないので 下記 2 ファイルを Lucene の レポジトリからとってきます org/apache/lucene/util/ Version.java VirtualMethod.java ※ メソッドのバージョニング関連クラスで  本処理にはあまり影響なさそう?
回避方法 パッチのあたったソースは Java5 以降の記述になっているため、 javac の オプションを変更してビルドします common-build.xml: 61:  <property name=&quot;javac.source&quot; value=&quot; 6 &quot;/> 62:  <property name=&quot;javac.target&quot; value=&quot; 6 &quot;/> 63: 64:  <property name=&quot;javadoc.link&quot; value=&quot;http://java.sun .com/ javase / 6 /docs/api/&quot;/> $ ant
回避方法 build/lucene-core-2.9.1-dev.jar を Lucandra の lib/lucene-core-2.9.1.jar と 差し替えます QueryParser のデフォルトオペレータを AND にして、再チャレンジ!! ShopSearchDemo.java: QueryParser qp =  new QueryParser(Version.LUCENE_CURRENT, &quot;name&quot;, analyzer); qp.setDefaultOperator( Operator.AND );
$ ./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
Search matched: 115 item(s) 09:52:16,739 DEBUG IndexReader:293 - Document read took: 10ms 1.  Luxor 丸の内 http://r.gnavi.co.jp/g763393/ ¥9000 09:52:16,741 DEBUG IndexReader:293 - Document read took: 1ms 2.  the Pantry 丸の内店 http://r.gnavi.co.jp/g763381/ ¥1300 09:52:16,743 DEBUG IndexReader:293 - Document read took: 1ms 3.  MAISON・BARSAC 丸の内 http://r.gnavi.co.jp/g763375/ ¥5500 09:52:16,750 DEBUG IndexReader:293 - Document read took: 2ms 4.  丸の内 やんも http://r.gnavi.co.jp/g763373/ ¥8000 09:52:16,751 DEBUG IndexReader:293 - Document read took: 1ms 5.  Vinpicoeur ~丸の内~ http://r.gnavi.co.jp/g763372/ ¥3500 09:52:16,753 DEBUG IndexReader:293 - Document read took: 1ms 6.  DEAN&DELUCA ~丸の内~ http://r.gnavi.co.jp/g763365/ ¥1500 09:52:16,755 DEBUG IndexReader:293 - Document read took: 2ms 7.  S.Stefano ~丸の内~ http://r.gnavi.co.jp/g763359/ ¥4500 : :
おお、なんかできてるっぽい
ソートも試してみる sort オプションを指定した場合に、 IndexSearcher.search() メソッドにて budget( 予算 ) フィールド値の降順で ソートされるようにしてみます 動かしてみます ☞ ShopSearchDemo.java: TopDocs docs = indexSearcher.search(q, null, 10,  new Sort(new SortField(&quot;budget&quot;, SortField.INT, true)));
$ ./run_shop.sh -search name: 丸の内  sort Search matched: 115 item(s) 09:59:17,396 DEBUG IndexReader:293 - Document read took: 9ms 1.  レストラン モナリザ 丸の内店 ~丸ビル~ http://r.gnavi.co.jp/g763345/ ¥10000 09:59:17,398 DEBUG IndexReader:293 - Document read took: 1ms 2.  センチュリーコート丸の内 http://r.gnavi.co.jp/g038917/ ¥10000 09:59:17,399 DEBUG IndexReader:293 - Document read took: 1ms 3.  Luxor 丸の内 http://r.gnavi.co.jp/g763393/ ¥9000 09:59:17,401 DEBUG IndexReader:293 - Document read took: 1ms 4.  丸の内 やんも http://r.gnavi.co.jp/g763373/ ¥8000 09:59:17,402 DEBUG IndexReader:293 - Document read took: 1ms 5.  たまさか 丸の内店 http://r.gnavi.co.jp/e533319/ ¥8000 09:59:17,403 DEBUG IndexReader:293 - Document read took: 1ms 6.  ワインショップエノテカ丸の内 ザ・ラウンジ http://r.gnavi.co.jp/g763382/ ¥6300 09:59:17,405 DEBUG IndexReader:293 - Document read took: 1ms 7.  寿し屋の勘八 旬 ~丸の内~ http://r.gnavi.co.jp/g763366/ ¥6000 :
ソートされてるっぽい
まとめ
わかったこと  1 Lucandra は謳い文句通り Lucene の バックエンドに Cassandra を採用した ものであり、アプリケーションは Lucene の資産 (API) をほぼそのまま 利用することができる # PhraseQuery は要調査
わかったこと  2 Lucene の機能を十分に使うには、 OrderPreservingPartitioner を選択する必要がある Partitioner は現状 Cluster で共通であり RandomPartitoner のシンプルで効果的なデータ分散の恩恵を受けられないので、共用環境への導入は要検討
わかったこと  3 Cassandra の内部特性を利用することで インデックスの最適化を不要とし、 リアルタイム性を高める構造である Twitter クライアントや RSS リーダーのような、ユーザーごとにインデックスが分かれていて総データ量が多く、 即時に検索が必要な場面に向いていると思われる
わかったこと  4 当然だが、 Java でしか使えない 他環境では、同梱の Solrandra を使って HTTP で利用するのだろう Java でも SolrJ を使って Solr のインデックス管理、キャッシュ機構を利用するのがベターなのかも
今後の課題 もう少し Lucene/Solr 勉強したら? Solrandra ベースでの実用性検証 データ量とパフォーマンス検証 RandomPartitioner での動作検証 PhraseQuery . . .
おしまい
参考 ■  A Cassandra-based Lucene backend http://blog.sematext.com/2010/02/09/lucandra-a-cassandra-based-lucene-backend/ ■  slideshare - Lucandra http://www.slideshare.net/otisg/lucandra ■  Cassandra: RandomPartitioner vs OrderPreservingPartitioner http://ria101.wordpress.com/2010/02/22/cassandra-randompartitioner-vs-orderpreservingpartitioner/ ■ 関口宏司の Lucene ブログ http://lucene.jugem.jp/
Lucandra を使ってみる  〜補足編〜 PhraseQuery を調べました ... 2010/7/15 佐藤 史彦
前回のあらすじ ,[object Object],[object Object],[object Object]
でもなんかひっかかる ... ,[object Object],[object Object],[object Object]
ということでソースを追いかけ ... TermInfo (転置インデックス)に Position (単語の出現位置)がないと PhraseQuery が機能しない ことがわかりました。 ※ Position を記録するには、インデクシング時に  指定する必要がある。 ※ 本家 Lucene はなくてもいけるのに ...
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 : 当該文書中の当該単語の出現位置 コレ
で、どうする? ,[object Object],[object Object],doc.add(new Field(&quot;name&quot;, name,  Store. YES ,  Index. ANALYZED ,  Field.TermVector. WITH_POSITIONS )); <field name= &quot;name&quot;  type= &quot;text_cjk&quot;   indexed= &quot;true&quot;  stored= &quot;true&quot; termPositions= &quot;true&quot;  /> インデックス生成時に Position s を指定する
実行結果 ( 一部省略 ) $ ./run_shop -index data.tsv $ ./run_shop.sh -search name: 丸の内 name:&quot; 丸の の内 &quot; Search matched: 115 item(s) 1.  Luxor 丸の内 http://r.gnavi.co.jp/g763393/ ¥9000 2.  the Pantry 丸の内店 http://r.gnavi.co.jp/g763381/ ¥1300 3.  MAISON・BARSAC 丸の内 http://r.gnavi.co.jp/g763375/ ¥5500 4.  丸の内 やんも http://r.gnavi.co.jp/g763373/ ¥8000 5.  Vinpicoeur ~丸の内~ http://r.gnavi.co.jp/g763372/ ¥3500 6.  DEAN&DELUCA ~丸の内~ http://r.gnavi.co.jp/g763365/ ¥1500 7.  S.Stefano ~丸の内~ http://r.gnavi.co.jp/g763359/ ¥4500
無事、検索できました ,[object Object],[object Object],以上です。

More Related Content

What's hot

Control distribution of virtual machines
Control distribution of virtual machinesControl distribution of virtual machines
Control distribution of virtual machinesirix_jp
 
Echo server implementation for Python
Echo server implementation for PythonEcho server implementation for Python
Echo server implementation for Python
Toshiki Tsuboi
 
Mongo dbのgridfsについて
Mongo dbのgridfsについてMongo dbのgridfsについて
Mongo dbのgridfsについて
Masahiro Saito
 
Apache Geode で始める Spring Data Gemfire
Apache Geode で始めるSpring Data GemfireApache Geode で始めるSpring Data Gemfire
Apache Geode で始める Spring Data Gemfire
Akihiro Kitada
 
OpenStack + Common Lisp
OpenStack + Common LispOpenStack + Common Lisp
OpenStack + Common Lispirix_jp
 
Measurement of Maximum new NAT-sessions per second / How to send packets
Measurement of Maximum new NAT-sessionsper second / How to send packetsMeasurement of Maximum new NAT-sessionsper second / How to send packets
Measurement of Maximum new NAT-sessions per second / How to send packets
@ otsuka752
 
AvailabilityZoneとHostAggregate
AvailabilityZoneとHostAggregateAvailabilityZoneとHostAggregate
AvailabilityZoneとHostAggregate
Hiroki Ishikawa
 
JAZUG #26 AKS backup with Velero
JAZUG #26 AKS backup with VeleroJAZUG #26 AKS backup with Velero
JAZUG #26 AKS backup with Velero
Tetsuya Sodo
 
〜Apache Geode 入門 gfsh によるクラスター構築・管理
〜Apache Geode 入門 gfsh によるクラスター構築・管理〜Apache Geode 入門 gfsh によるクラスター構築・管理
〜Apache Geode 入門 gfsh によるクラスター構築・管理
Akihiro Kitada
 
PGroonga 2 - PostgreSQLでの全文検索の決定版
PGroonga 2 - PostgreSQLでの全文検索の決定版PGroonga 2 - PostgreSQLでの全文検索の決定版
PGroonga 2 - PostgreSQLでの全文検索の決定版
Kouhei Sutou
 
メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月
メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月
メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月
Masahiro Nagano
 
20131230_CloudStack Advent Calendar VPCを作ってみよう
20131230_CloudStack Advent Calendar VPCを作ってみよう20131230_CloudStack Advent Calendar VPCを作ってみよう
20131230_CloudStack Advent Calendar VPCを作ってみよう
Midori Oge
 
20140828 #ssmjp 社内チューニンガソンで優勝したはなし
20140828 #ssmjp 社内チューニンガソンで優勝したはなし20140828 #ssmjp 社内チューニンガソンで優勝したはなし
20140828 #ssmjp 社内チューニンガソンで優勝したはなし
Masahiro NAKAYAMA
 
How to backup your mroonga database?
How to backup your mroonga database?How to backup your mroonga database?
How to backup your mroonga database?
yoku0825
 
Fig
FigFig
PHPでPostgreSQLとPGroongaを使って高速日本語全文検索!
 PHPでPostgreSQLとPGroongaを使って高速日本語全文検索! PHPでPostgreSQLとPGroongaを使って高速日本語全文検索!
PHPでPostgreSQLとPGroongaを使って高速日本語全文検索!
Kouhei Sutou
 
さくらのクラウドでVyOS使ってみた
さくらのクラウドでVyOS使ってみたさくらのクラウドでVyOS使ってみた
さくらのクラウドでVyOS使ってみた
SAKURA Internet Inc.
 
PostgreSQLとPGroongaで作るPHPマニュアル高速全文検索システム
PostgreSQLとPGroongaで作るPHPマニュアル高速全文検索システムPostgreSQLとPGroongaで作るPHPマニュアル高速全文検索システム
PostgreSQLとPGroongaで作るPHPマニュアル高速全文検索システム
Kouhei Sutou
 
Stream processing and Norikra
Stream processing and NorikraStream processing and Norikra
Stream processing and NorikraSATOSHI TAGOMORI
 

What's hot (20)

Control distribution of virtual machines
Control distribution of virtual machinesControl distribution of virtual machines
Control distribution of virtual machines
 
Echo server implementation for Python
Echo server implementation for PythonEcho server implementation for Python
Echo server implementation for Python
 
Mongo dbのgridfsについて
Mongo dbのgridfsについてMongo dbのgridfsについて
Mongo dbのgridfsについて
 
Apache Geode で始める Spring Data Gemfire
Apache Geode で始めるSpring Data GemfireApache Geode で始めるSpring Data Gemfire
Apache Geode で始める Spring Data Gemfire
 
OpenStack + Common Lisp
OpenStack + Common LispOpenStack + Common Lisp
OpenStack + Common Lisp
 
Measurement of Maximum new NAT-sessions per second / How to send packets
Measurement of Maximum new NAT-sessionsper second / How to send packetsMeasurement of Maximum new NAT-sessionsper second / How to send packets
Measurement of Maximum new NAT-sessions per second / How to send packets
 
AvailabilityZoneとHostAggregate
AvailabilityZoneとHostAggregateAvailabilityZoneとHostAggregate
AvailabilityZoneとHostAggregate
 
JAZUG #26 AKS backup with Velero
JAZUG #26 AKS backup with VeleroJAZUG #26 AKS backup with Velero
JAZUG #26 AKS backup with Velero
 
〜Apache Geode 入門 gfsh によるクラスター構築・管理
〜Apache Geode 入門 gfsh によるクラスター構築・管理〜Apache Geode 入門 gfsh によるクラスター構築・管理
〜Apache Geode 入門 gfsh によるクラスター構築・管理
 
PGroonga 2 - PostgreSQLでの全文検索の決定版
PGroonga 2 - PostgreSQLでの全文検索の決定版PGroonga 2 - PostgreSQLでの全文検索の決定版
PGroonga 2 - PostgreSQLでの全文検索の決定版
 
メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月
メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月
メルカリのデータベース戦略 / PHPとMySQLの怖い話 MyNA会2015年8月
 
20131230_CloudStack Advent Calendar VPCを作ってみよう
20131230_CloudStack Advent Calendar VPCを作ってみよう20131230_CloudStack Advent Calendar VPCを作ってみよう
20131230_CloudStack Advent Calendar VPCを作ってみよう
 
20140828 #ssmjp 社内チューニンガソンで優勝したはなし
20140828 #ssmjp 社内チューニンガソンで優勝したはなし20140828 #ssmjp 社内チューニンガソンで優勝したはなし
20140828 #ssmjp 社内チューニンガソンで優勝したはなし
 
How to backup your mroonga database?
How to backup your mroonga database?How to backup your mroonga database?
How to backup your mroonga database?
 
Fig
FigFig
Fig
 
PHPでPostgreSQLとPGroongaを使って高速日本語全文検索!
 PHPでPostgreSQLとPGroongaを使って高速日本語全文検索! PHPでPostgreSQLとPGroongaを使って高速日本語全文検索!
PHPでPostgreSQLとPGroongaを使って高速日本語全文検索!
 
Open stackceilometer
Open stackceilometerOpen stackceilometer
Open stackceilometer
 
さくらのクラウドでVyOS使ってみた
さくらのクラウドでVyOS使ってみたさくらのクラウドでVyOS使ってみた
さくらのクラウドでVyOS使ってみた
 
PostgreSQLとPGroongaで作るPHPマニュアル高速全文検索システム
PostgreSQLとPGroongaで作るPHPマニュアル高速全文検索システムPostgreSQLとPGroongaで作るPHPマニュアル高速全文検索システム
PostgreSQLとPGroongaで作るPHPマニュアル高速全文検索システム
 
Stream processing and Norikra
Stream processing and NorikraStream processing and Norikra
Stream processing and Norikra
 

Similar to Lucandraを使ってみる

HashiCorpのNomadを使ったコンテナのスケジューリング手法
HashiCorpのNomadを使ったコンテナのスケジューリング手法HashiCorpのNomadを使ったコンテナのスケジューリング手法
HashiCorpのNomadを使ったコンテナのスケジューリング手法
Masahito Zembutsu
 
Kubernetes + containerd で cgroup v2 に移行したら "failed to create fsnotify watcher...
Kubernetes + containerd で cgroup v2 に移行したら "failed to create fsnotify watcher...Kubernetes + containerd で cgroup v2 に移行したら "failed to create fsnotify watcher...
Kubernetes + containerd で cgroup v2 に移行したら "failed to create fsnotify watcher...
Preferred Networks
 
20140612_Docker上でCloudStackを動かしてみる!!
20140612_Docker上でCloudStackを動かしてみる!!20140612_Docker上でCloudStackを動かしてみる!!
20140612_Docker上でCloudStackを動かしてみる!!
Midori Oge
 
細かすぎて伝わらないかもしれない Azure Container Networking Deep Dive
細かすぎて伝わらないかもしれない Azure Container Networking Deep Dive細かすぎて伝わらないかもしれない Azure Container Networking Deep Dive
細かすぎて伝わらないかもしれない Azure Container Networking Deep Dive
Toru Makabe
 
Docker Swarm入門
Docker Swarm入門Docker Swarm入門
Docker Swarm入門
Masahito Zembutsu
 
Pulsar Handson 20180226
Pulsar Handson 20180226Pulsar Handson 20180226
Pulsar Handson 20180226
Nozomi Kurihara
 
Dockerのキホンその2 Docker Compose Swarm Machine 利用編
Dockerのキホンその2 Docker Compose Swarm Machine 利用編Dockerのキホンその2 Docker Compose Swarm Machine 利用編
Dockerのキホンその2 Docker Compose Swarm Machine 利用編
Naoki Nagazumi
 
Docker handson
Docker handsonDocker handson
Docker handson
koda3
 
20150101勉強会 dokku alt
20150101勉強会 dokku alt20150101勉強会 dokku alt
20150101勉強会 dokku altShugo Numano
 
SPARQLから入門するLinked Open Data(LOD)ハンズオン 第1回
SPARQLから入門するLinked Open Data(LOD)ハンズオン 第1回SPARQLから入門するLinked Open Data(LOD)ハンズオン 第1回
SPARQLから入門するLinked Open Data(LOD)ハンズオン 第1回yamahige
 
Real world android akka
Real world android akkaReal world android akka
Real world android akka
Taisuke Oe
 
半日でわかる コンテナー技術 (応用編)
半日でわかる コンテナー技術 (応用編)半日でわかる コンテナー技術 (応用編)
半日でわかる コンテナー技術 (応用編)
Toru Makabe
 
Docker最新動向2017秋+セキュリティの落とし穴
Docker最新動向2017秋+セキュリティの落とし穴Docker最新動向2017秋+セキュリティの落とし穴
Docker最新動向2017秋+セキュリティの落とし穴
Masahito Zembutsu
 
tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1Ryosuke IWANAGA
 
S3 を単純ストレージとして 利用する手段の比較
S3 を単純ストレージとして 利用する手段の比較S3 を単純ストレージとして 利用する手段の比較
S3 を単純ストレージとして 利用する手段の比較
真治 米田
 
JAWS-UG コンテナ支部 Docker入門 ハンズオン
JAWS-UG コンテナ支部 Docker入門 ハンズオンJAWS-UG コンテナ支部 Docker入門 ハンズオン
JAWS-UG コンテナ支部 Docker入門 ハンズオン
Ryo Nakamaru
 
cassandra調査レポート
cassandra調査レポートcassandra調査レポート
cassandra調査レポート
Akihiro Kuwano
 
Docker swarm mode 入門と ECS との比較
Docker swarm mode 入門と ECS との比較Docker swarm mode 入門と ECS との比較
Docker swarm mode 入門と ECS との比較
Yoshinori Teraoka
 
Getting Started Japanese Search and Calculate Similarity with Apache Lucene
Getting Started Japanese Search and Calculate Similarity with Apache LuceneGetting Started Japanese Search and Calculate Similarity with Apache Lucene
Getting Started Japanese Search and Calculate Similarity with Apache Lucene
Eiji Shinohara
 
CouchDB JP & BigCouch
CouchDB JP & BigCouchCouchDB JP & BigCouch
CouchDB JP & BigCouch
Yohei Sasaki
 

Similar to Lucandraを使ってみる (20)

HashiCorpのNomadを使ったコンテナのスケジューリング手法
HashiCorpのNomadを使ったコンテナのスケジューリング手法HashiCorpのNomadを使ったコンテナのスケジューリング手法
HashiCorpのNomadを使ったコンテナのスケジューリング手法
 
Kubernetes + containerd で cgroup v2 に移行したら "failed to create fsnotify watcher...
Kubernetes + containerd で cgroup v2 に移行したら "failed to create fsnotify watcher...Kubernetes + containerd で cgroup v2 に移行したら "failed to create fsnotify watcher...
Kubernetes + containerd で cgroup v2 に移行したら "failed to create fsnotify watcher...
 
20140612_Docker上でCloudStackを動かしてみる!!
20140612_Docker上でCloudStackを動かしてみる!!20140612_Docker上でCloudStackを動かしてみる!!
20140612_Docker上でCloudStackを動かしてみる!!
 
細かすぎて伝わらないかもしれない Azure Container Networking Deep Dive
細かすぎて伝わらないかもしれない Azure Container Networking Deep Dive細かすぎて伝わらないかもしれない Azure Container Networking Deep Dive
細かすぎて伝わらないかもしれない Azure Container Networking Deep Dive
 
Docker Swarm入門
Docker Swarm入門Docker Swarm入門
Docker Swarm入門
 
Pulsar Handson 20180226
Pulsar Handson 20180226Pulsar Handson 20180226
Pulsar Handson 20180226
 
Dockerのキホンその2 Docker Compose Swarm Machine 利用編
Dockerのキホンその2 Docker Compose Swarm Machine 利用編Dockerのキホンその2 Docker Compose Swarm Machine 利用編
Dockerのキホンその2 Docker Compose Swarm Machine 利用編
 
Docker handson
Docker handsonDocker handson
Docker handson
 
20150101勉強会 dokku alt
20150101勉強会 dokku alt20150101勉強会 dokku alt
20150101勉強会 dokku alt
 
SPARQLから入門するLinked Open Data(LOD)ハンズオン 第1回
SPARQLから入門するLinked Open Data(LOD)ハンズオン 第1回SPARQLから入門するLinked Open Data(LOD)ハンズオン 第1回
SPARQLから入門するLinked Open Data(LOD)ハンズオン 第1回
 
Real world android akka
Real world android akkaReal world android akka
Real world android akka
 
半日でわかる コンテナー技術 (応用編)
半日でわかる コンテナー技術 (応用編)半日でわかる コンテナー技術 (応用編)
半日でわかる コンテナー技術 (応用編)
 
Docker最新動向2017秋+セキュリティの落とし穴
Docker最新動向2017秋+セキュリティの落とし穴Docker最新動向2017秋+セキュリティの落とし穴
Docker最新動向2017秋+セキュリティの落とし穴
 
tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1
 
S3 を単純ストレージとして 利用する手段の比較
S3 を単純ストレージとして 利用する手段の比較S3 を単純ストレージとして 利用する手段の比較
S3 を単純ストレージとして 利用する手段の比較
 
JAWS-UG コンテナ支部 Docker入門 ハンズオン
JAWS-UG コンテナ支部 Docker入門 ハンズオンJAWS-UG コンテナ支部 Docker入門 ハンズオン
JAWS-UG コンテナ支部 Docker入門 ハンズオン
 
cassandra調査レポート
cassandra調査レポートcassandra調査レポート
cassandra調査レポート
 
Docker swarm mode 入門と ECS との比較
Docker swarm mode 入門と ECS との比較Docker swarm mode 入門と ECS との比較
Docker swarm mode 入門と ECS との比較
 
Getting Started Japanese Search and Calculate Similarity with Apache Lucene
Getting Started Japanese Search and Calculate Similarity with Apache LuceneGetting Started Japanese Search and Calculate Similarity with Apache Lucene
Getting Started Japanese Search and Calculate Similarity with Apache Lucene
 
CouchDB JP & BigCouch
CouchDB JP & BigCouchCouchDB JP & BigCouch
CouchDB JP & BigCouch
 

Recently uploaded

LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
CRI Japan, Inc.
 
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
t m
 
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
Toru Tamaki
 
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさJSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
0207sukipio
 
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
Matsushita Laboratory
 
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援しますキンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
Takayuki Nakayama
 
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
Toru Tamaki
 
This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.
chiefujita1
 
Generating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language ModelsGenerating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language Models
harmonylab
 

Recently uploaded (9)

LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアルLoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
LoRaWAN 4チャンネル電流センサー・コンバーター CS01-LB 日本語マニュアル
 
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
遺伝的アルゴリズムと知識蒸留による大規模言語モデル(LLM)の学習とハイパーパラメータ最適化
 
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
論文紹介:When Visual Prompt Tuning Meets Source-Free Domain Adaptive Semantic Seg...
 
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさJSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
JSAI_類似画像マッチングによる器への印象付与手法の妥当性検証_ver.3_高橋りさ
 
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
ReonHata_便利の副作用に気づかせるための発想支援手法の評価---行為の増減の提示による気づきへの影響---
 
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援しますキンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
キンドリル ネットワークアセスメントサービスご紹介 今のネットワーク環境は大丈夫? 調査〜対策までご支援します
 
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
論文紹介:Deep Learning-Based Human Pose Estimation: A Survey
 
This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.This is the company presentation material of RIZAP Technologies, Inc.
This is the company presentation material of RIZAP Technologies, Inc.
 
Generating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language ModelsGenerating Automatic Feedback on UI Mockups with Large Language Models
Generating Automatic Feedback on UI Mockups with Large Language Models
 

Lucandraを使ってみる

  • 2. Agenda Lucandra ってなに? Lucandra の構成 できること 使ってみる まとめ
  • 4. A Cassandra-based Lucene backend Author : Jake Luciani
  • 6. Cassandra にインデックス機能を 追加する、というより Lucene/Solr のインデックスを リアルタイムに作成、かつ 手軽にスケールさせる目的で インデックスのストア先に Cassandra を採用したもの
  • 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.
  • 16. 環境 Cassandra は 0.6.2 ( 単体 )
  • 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
  • 18. storage-conf.xml の差し替え storage-conf.xml を差し替えて Cassandra を立ち上げます ※ Cassandra のデータが空である前提 $ cp config/storage-conf.xml ¥ /usr/local/cassandra/conf/ $ /usr/local/cassandra/bin/cassandra
  • 19. storage-conf.xml のポイント <Keyspace Name=&quot;Lucandra&quot; > <ColumnFamily CompareWith=&quot;BytesType&quot; Name=&quot;Documents&quot; KeysCached=&quot;10%&quot; /> <ColumnFamily ColumnType=&quot;Super&quot; CompareWith=&quot;BytesType&quot; CompareSubcolumnsWith=&quot;BytesType&quot; Name=&quot;TermInfo&quot; KeysCached=&quot;10%&quot; /> : : </Keyspace> <Partitioner> org.apache.cassandra.dht.OrderPreservingPartitioner </Partitioner> クラスタノードでは InitialToken も適切に設定すべき
  • 20. Demo(BookmarksDemo) を試す Cassandra Bookmarks Demo Hits Document Document Document Field:url Field:title Field:tags -index QueryParser Document Document Document -search SimpleAnalyzer Query Lucene Index IndexReader IndexWriter SimpleAnalyzer IndexSearcher TSV File
  • 21. 動作確認 $ ./run_demo.sh -index bookmark.tsv $ ./run_demo.sh -search title:linu* Search matched: 5 item(s) 1. ZFS on FUSE/Linux http://zfs-on-fuse.blogspot.com/ 2. Set Up Postfix For Relaying Emails Through Another Mailserver | HowtoForge - Linux Howtos and Tutorials http://www.howtoforge.com/postfix_relaying_through_ another_mailserver 3. Debian GNU/Linux System Administration Resources http://www.debian-administration.org/ 4. Linux Scalability http://www.cs.wisc.edu/condor/condorg/linux_scalabi lity.html 5. LinuxDevCenter.com -- Cache-Friendly Web Pages http://www.linuxdevcenter.com/pub/a/linux/2002/02/ 28/cachefriendly.html
  • 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
  • 24. サンプルプログラム BookmarksDemo をコピーして、 下記の変更を加えます * Analyzer を変更 SimpleAnalyzer -> CJKAnalyzer * インデックス名を変更 bookmarks -> shopsearch * ドキュメントフィールドを  サンプルデータにあわせて変更
  • 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:&quot; 丸の の内 &quot; 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) あれ? ヒットしない。。。 (途中まではいい感じにみえるけど)
  • 27. 要因調査 CJKAnalyzer を使用した場合、 QueryParser.parse() は CJK 文字列を bi-gram に分割した Query を返却する name: 丸の内  ↓ name:&quot; 丸の の内 &quot;
  • 28. 要因調査 この際の Query は、 PhraseQuery の インスタンスになっている PhraseQuery が使用される場合、 LucandraTermDocs.nextPosition() が うまく機能しない (?) ためか、 Hit した ドキュメントが抽出できていない
  • 29. 要因調査 そこが問題のようだが、つっこんで 調査しないと影響範囲とか読めない ので、回避方法を検討。。。 解明しました。 詳細は付け足し資料 ( 補足編 ) にて。
  • 30. 回避方法 そもそもなぜ bi-gram が PhraseQuery として扱われるのかを調べていたら、 下記の情報がありました 関口宏司の Lucene ブログ http://lucene.jugem.jp/?cid=5
  • 31. 回避方法 これによると、 Lucene3.1 からは Analyzer により複数の単語が生成される場合、 PhraseQuery が生成される仕様を BooleanQuery に変えるべし と提案されており、 patch が提供されている
  • 32. 回避方法 このパッチを強引にも 2.9.1 にあてます $ tar xzf lucene-2.9.1.tar.gz $ cd lucene-2.9.1 $ curl -O https://issues.apache.org/jira/secure/attachment /12445136/LUCENE-2458.patch $ patch -b -p1 < LUCENE-2458.patch
  • 33. 回避方法 このままではビルドが通らないので 下記 2 ファイルを Lucene の レポジトリからとってきます org/apache/lucene/util/ Version.java VirtualMethod.java ※ メソッドのバージョニング関連クラスで  本処理にはあまり影響なさそう?
  • 34. 回避方法 パッチのあたったソースは Java5 以降の記述になっているため、 javac の オプションを変更してビルドします common-build.xml: 61: <property name=&quot;javac.source&quot; value=&quot; 6 &quot;/> 62: <property name=&quot;javac.target&quot; value=&quot; 6 &quot;/> 63: 64: <property name=&quot;javadoc.link&quot; value=&quot;http://java.sun .com/ javase / 6 /docs/api/&quot;/> $ ant
  • 35. 回避方法 build/lucene-core-2.9.1-dev.jar を Lucandra の lib/lucene-core-2.9.1.jar と 差し替えます QueryParser のデフォルトオペレータを AND にして、再チャレンジ!! ShopSearchDemo.java: QueryParser qp = new QueryParser(Version.LUCENE_CURRENT, &quot;name&quot;, analyzer); qp.setDefaultOperator( Operator.AND );
  • 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
  • 37. Search matched: 115 item(s) 09:52:16,739 DEBUG IndexReader:293 - Document read took: 10ms 1. Luxor 丸の内 http://r.gnavi.co.jp/g763393/ ¥9000 09:52:16,741 DEBUG IndexReader:293 - Document read took: 1ms 2. the Pantry 丸の内店 http://r.gnavi.co.jp/g763381/ ¥1300 09:52:16,743 DEBUG IndexReader:293 - Document read took: 1ms 3. MAISON・BARSAC 丸の内 http://r.gnavi.co.jp/g763375/ ¥5500 09:52:16,750 DEBUG IndexReader:293 - Document read took: 2ms 4. 丸の内 やんも http://r.gnavi.co.jp/g763373/ ¥8000 09:52:16,751 DEBUG IndexReader:293 - Document read took: 1ms 5. Vinpicoeur ~丸の内~ http://r.gnavi.co.jp/g763372/ ¥3500 09:52:16,753 DEBUG IndexReader:293 - Document read took: 1ms 6. DEAN&DELUCA ~丸の内~ http://r.gnavi.co.jp/g763365/ ¥1500 09:52:16,755 DEBUG IndexReader:293 - Document read took: 2ms 7. S.Stefano ~丸の内~ http://r.gnavi.co.jp/g763359/ ¥4500 : :
  • 39. ソートも試してみる sort オプションを指定した場合に、 IndexSearcher.search() メソッドにて budget( 予算 ) フィールド値の降順で ソートされるようにしてみます 動かしてみます ☞ ShopSearchDemo.java: TopDocs docs = indexSearcher.search(q, null, 10, new Sort(new SortField(&quot;budget&quot;, SortField.INT, true)));
  • 40. $ ./run_shop.sh -search name: 丸の内 sort Search matched: 115 item(s) 09:59:17,396 DEBUG IndexReader:293 - Document read took: 9ms 1. レストラン モナリザ 丸の内店 ~丸ビル~ http://r.gnavi.co.jp/g763345/ ¥10000 09:59:17,398 DEBUG IndexReader:293 - Document read took: 1ms 2. センチュリーコート丸の内 http://r.gnavi.co.jp/g038917/ ¥10000 09:59:17,399 DEBUG IndexReader:293 - Document read took: 1ms 3. Luxor 丸の内 http://r.gnavi.co.jp/g763393/ ¥9000 09:59:17,401 DEBUG IndexReader:293 - Document read took: 1ms 4. 丸の内 やんも http://r.gnavi.co.jp/g763373/ ¥8000 09:59:17,402 DEBUG IndexReader:293 - Document read took: 1ms 5. たまさか 丸の内店 http://r.gnavi.co.jp/e533319/ ¥8000 09:59:17,403 DEBUG IndexReader:293 - Document read took: 1ms 6. ワインショップエノテカ丸の内 ザ・ラウンジ http://r.gnavi.co.jp/g763382/ ¥6300 09:59:17,405 DEBUG IndexReader:293 - Document read took: 1ms 7. 寿し屋の勘八 旬 ~丸の内~ http://r.gnavi.co.jp/g763366/ ¥6000 :
  • 43. わかったこと 1 Lucandra は謳い文句通り Lucene の バックエンドに Cassandra を採用した ものであり、アプリケーションは Lucene の資産 (API) をほぼそのまま 利用することができる # PhraseQuery は要調査
  • 44. わかったこと 2 Lucene の機能を十分に使うには、 OrderPreservingPartitioner を選択する必要がある Partitioner は現状 Cluster で共通であり RandomPartitoner のシンプルで効果的なデータ分散の恩恵を受けられないので、共用環境への導入は要検討
  • 45. わかったこと 3 Cassandra の内部特性を利用することで インデックスの最適化を不要とし、 リアルタイム性を高める構造である Twitter クライアントや RSS リーダーのような、ユーザーごとにインデックスが分かれていて総データ量が多く、 即時に検索が必要な場面に向いていると思われる
  • 46. わかったこと 4 当然だが、 Java でしか使えない 他環境では、同梱の Solrandra を使って HTTP で利用するのだろう Java でも SolrJ を使って Solr のインデックス管理、キャッシュ機構を利用するのがベターなのかも
  • 47. 今後の課題 もう少し Lucene/Solr 勉強したら? Solrandra ベースでの実用性検証 データ量とパフォーマンス検証 RandomPartitioner での動作検証 PhraseQuery . . .
  • 49. 参考 ■ A Cassandra-based Lucene backend http://blog.sematext.com/2010/02/09/lucandra-a-cassandra-based-lucene-backend/ ■ slideshare - Lucandra http://www.slideshare.net/otisg/lucandra ■ Cassandra: RandomPartitioner vs OrderPreservingPartitioner http://ria101.wordpress.com/2010/02/22/cassandra-randompartitioner-vs-orderpreservingpartitioner/ ■ 関口宏司の Lucene ブログ http://lucene.jugem.jp/
  • 50. Lucandra を使ってみる  〜補足編〜 PhraseQuery を調べました ... 2010/7/15 佐藤 史彦
  • 51.
  • 52.
  • 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 : 当該文書中の当該単語の出現位置 コレ
  • 55.
  • 56. 実行結果 ( 一部省略 ) $ ./run_shop -index data.tsv $ ./run_shop.sh -search name: 丸の内 name:&quot; 丸の の内 &quot; Search matched: 115 item(s) 1. Luxor 丸の内 http://r.gnavi.co.jp/g763393/ ¥9000 2. the Pantry 丸の内店 http://r.gnavi.co.jp/g763381/ ¥1300 3. MAISON・BARSAC 丸の内 http://r.gnavi.co.jp/g763375/ ¥5500 4. 丸の内 やんも http://r.gnavi.co.jp/g763373/ ¥8000 5. Vinpicoeur ~丸の内~ http://r.gnavi.co.jp/g763372/ ¥3500 6. DEAN&DELUCA ~丸の内~ http://r.gnavi.co.jp/g763365/ ¥1500 7. S.Stefano ~丸の内~ http://r.gnavi.co.jp/g763359/ ¥4500
  • 57.