2017.12.15 Friday
スポンサーサイト
一定期間更新がないため広告を表示しています
| スポンサードリンク | - | | - | - |
関口宏司のLuceneブログOSS検索ライブラリのLuceneおよびそのサブプロジェクト(Solr/Tika/Mahoutなど)について
2009.06.27 Saturday
DVDレンタルのNetflixはSolr 1.4-devを利用の件
Solr 1.4のリリースが遅れだしてきており、私の周りでも「Solrのどのバージョンを使えばいいか」という質問が多く聞かれるようになった。現在はLucene 2.9のリリースを待つような気配となっている。
そんな中、日本では「集合知プログラミング」ですっかりおなじみとなったDVDレンタルのNetflixに勤務するサーチ・ソフトウェア・エンジニアのWalter Underwoodさんが「NetflixではSolr 1.4のnightly buildを使用している」とメーリングリストで言及したのでここで紹介しよう: http://www.nabble.com/Upgrade-to-solr-1.4-td24221475.html ちなみにNetflixは一日で200万クエリ以上をSolrでさばいているサイトである。 Netflixで使用しているSolr 1.4のバージョンは2009-05-11のnightly buildで、利用に当たっては通常の品質保証テストを行い、その後5台のうちの1台にSolr 1.4を適用し、2週間動作確認をして問題がないことを確認したあと5台全部にデプロイしたのが昨日。Solr 1.4にしてCPU使用率を10%減らしつつ、10%の処理トラフィック向上を達成したということである。 2009.06.20 Saturday
Luceneバージョンの後方互換性に関するポリシーの変更の提案(3.0)
Lucene 3.0から後方互換性のポリシーを変更(緩める)しようかという提案が行われている:
https://issues.apache.org/jira/browse/LUCENE-1698 現在のポリシーは前の記事を参照していただくとして、ここでは提案されている変更部分を示す:
なお、インデックスフォーマットに関するポリシーの変更はない。 これまでのLuceneユーザにとって、マイナーバージョン間でのAPIの非互換は結構インパクトが大きいと思われる。本提案はコミッター内での簡単な投票が行われ、上記JIRAでユーザ向けに公開/提案されているものであり、特に反対意見がなければこのようにポリシー変更がなされると思われる。 2009.06.19 Friday
インデックス全体のユニークターム数を取得する(2.9)
Lucene 2.9のIndexReaderに、インデックス全体のユニークターム数を取得するgetUniqueTermCount()というメソッドが追加された:
https://issues.apache.org/jira/browse/LUCENE-1586 「インデックス全体」とはいっても、複数セグメントからなるインデックスに対してこのメソッドを呼ぶとUnsupportedOperationExceptionが発行されてしまう。なぜなら複数セグメントからなるインデックスのIndexReaderの実体はMultiSegmentReaderとなり、個々のセグメントには同じTermが存在する可能性があり、マージ(optimize())しなければ同定が困難だからである。 なお、このメソッドは全フィールドに対するユニークターム数をカウントする。 2009.06.18 Thursday
よりソートが速くなったLucene 2.9
Lucene 2.9はソートがより速くなった。まず先日の記事で紹介したとおり、スコアが不要の時はScorerを呼ばないようにすることができるようになった。
また複数セグメントのインデックスにおいて、IndexReaderのreopen()時に変更のないセグメントは再読み込みしないようにしてwarm-up時間を短縮できるようになっている: https://issues.apache.org/jira/browse/LUCENE-1483 つまり、ソート時に使用するFieldCacheの内容が引き継がれるのでIndexReaderのreopen()後のソートがこれまでより速くなることが期待できる。 2009.06.17 Wednesday
"{x TO y]" や "[x TO y}"の範囲検索
現在のLuceneの範囲検索では"{"(中カッコ)と"]"(カギカッコ)を組み合わせて"{3 TO 6]"という検索をしようとすると、QueryParserによって次のように怒られる:
Exception in thread "main" org.apache.lucene.queryParser.ParseException: Cannot parse '{3 TO 6]': Encountered " https://issues.apache.org/jira/browse/LUCENE-996 Lucene 2.9以前で"{3 TO 6]"をするにはどうすればよいかという質問がMLに流れていて、それへの回答が"{3 TO 6} OR 6"でできますね、とあった。う〜ん、なるほど。 上記Q&AはQueryParserを使う前提である。しかしプログラムによりRangeQueryを次のように作成すれば、Lucene 2.9以前でも"{3 TO 6]"を表現することはできる: RangeQuery query = new RangeQuery( F, "3", "6", false, true ); 以下にQueryParserやRangeQueryを使った範囲検索のプログラム例を示す: public class MixIncExRange { static Directory dir = new RAMDirectory(); static Analyzer analyzer = new WhitespaceAnalyzer(); static final String F = "f"; static final String[] DOCS = { "1", "2", "3", "4", "5", "6", "7", "8" }; public static void main(String[] args) throws Exception { makeIndex(); testQuery(); testParser(); } static void makeIndex() throws IOException { System.out.println( "***** DATA *****" ); IndexWriter writer = new IndexWriter( dir, analyzer, true, MaxFieldLength.LIMITED ); for( String s : DOCS ){ System.out.print( s + " " ); Document doc = new Document(); doc.add( new Field( F, s, Store.YES, Index.ANALYZED ) ); writer.addDocument( doc ); } writer.close(); System.out.println(); // print '¥n' } static void testQuery() throws IOException { System.out.println( "¥n***** testQuery *****" ); // 3 < n < 6 RangeQuery rq1 = new RangeQuery( F, "3", "6", false, false ); exec( "3 < n < 6", rq1 ); // 3 <= n <= 6 RangeQuery rq2 = new RangeQuery( F, "3", "6", true, true ); exec( "3 <= n <= 6", rq2 ); // 3 < n <= 6 RangeQuery rq3 = new RangeQuery( F, "3", "6", false, true ); exec( "3 < n <= 6", rq3 ); } static void testParser() throws Exception { System.out.println( "¥n***** testParser *****" ); // 3 < n < 6 execParser( "3 < n < 6", "{3 TO 6}" ); // 3 <= n <= 6 execParser( "3 <= n <= 6", "[3 TO 6]" ); // 3 < n <= 6 execParser( "3 < n <= 6", "{3 TO 6} OR 6" ); } static void exec( String q, Query query ) throws IOException { System.out.print( q + " ---> "); System.out.print( query.toString() + " ---> " ); IndexSearcher searcher = new IndexSearcher( dir ); TopDocs docs = searcher.search( query, 10 ); for( ScoreDoc scoreDoc: docs.scoreDocs ){ int docId = scoreDoc.doc; Document doc = searcher.doc( docId ); System.out.print( doc.get( F ) + " " ); } searcher.close(); System.out.println(); // print '¥n' } static void execParser( String q, String parsedQuery ) throws Exception { QueryParser parser = new QueryParser( F, analyzer ); Query query = parser.parse( parsedQuery ); System.out.print( parsedQuery + " ---> " ); exec( q, query ); } } このプログラムを実行すると、次のように表示される: ***** DATA ***** 1 2 3 4 5 6 7 8 ***** testQuery ***** 3 < n < 6 ---> f:{3 TO 6} ---> 4 5 3 <= n <= 6 ---> f:[3 TO 6] ---> 3 4 5 6 3 < n <= 6 ---> f:{3 TO 6] ---> 4 5 6 ***** testParser ***** {3 TO 6} ---> 3 < n < 6 ---> f:{3 TO 6} ---> 4 5 [3 TO 6] ---> 3 <= n <= 6 ---> f:[3 TO 6] ---> 3 4 5 6 {3 TO 6} OR 6 ---> 3 < n <= 6 ---> f:{3 TO 6} f:6 ---> 6 4 5 2009.06.11 Thursday
フィールド値を持つ文書を検索する
あるフィールドに値がある(値が何であるかは気にしない)文書を検索したい場合は、ConstantScoreRangeQueryを使って次のようなQueryを作成し、それを使ってsearch()すればよい:
Query query = new ConstantScoreRangeQuery( "field", null, null, false, false ); public class GetAllDocsThatHasValues { static Directory dir = new RAMDirectory(); static Analyzer analyzer = new WhitespaceAnalyzer(); static final String F_ID = "id"; static final String F_NAME = "name"; static final String[] IDS = { "1", "2", "3", "4", "5" }; static final String[] NAMES = { "a", "b", "", null, "c" }; public static void main(String[] args) throws IOException { makeIndex(); searcIndex(); } static void makeIndex() throws IOException { IndexWriter writer = new IndexWriter( dir, analyzer, true, MaxFieldLength.LIMITED ); for( int i = 0; i < IDS.length; i++ ){ Document doc = new Document(); doc.add( new Field( F_ID, IDS[i], Store.YES, Index.ANALYZED ) ); if( NAMES[i] != null ) doc.add( new Field( F_NAME, NAMES[i], Store.YES, Index.ANALYZED ) ); writer.addDocument( doc ); } writer.close(); } static void searcIndex() throws IOException { Query query = new ConstantScoreRangeQuery( F_NAME, null, null, false, false ); IndexSearcher searcher = new IndexSearcher( dir ); TopDocs docs = searcher.search( query, 10 ); for( ScoreDoc scoreDoc : docs.scoreDocs ){ int docId = scoreDoc.doc; Document doc = searcher.doc( docId ); System.out.println( doc.get( F_ID ) + ":" + doc.get( F_NAME ) ); } searcher.close(); } } 1:a 2:b 5:c 2009.06.09 Tuesday
HitCollectorからCollectorへ(2.9)
Lucene 2.9ではHitCollectorがdeprecatedになり、代わりにCollectorを使うことが推奨されている。 CollectorはHitCollector同様collect()メソッドを持っているが、その引数はdoc(int)だけであり、scoreがない。その代わりにsetScorer(Scorer)メソッドを持っていてcollect()が呼ばれ始める前にLuceneからsetScorer()が呼ばれる。Collectorユーザは渡されたScorerのscore()メソッドをcollect()内で呼び出し、スコアを得ることができる。 Collectorではこのようにcollect()でスコアが渡されないのでscore()を呼ぶ面倒があるが、collect()からスコアが分離されたため、スコア計算が不要なアプリケーションではその分検索を高速化できるようになった。 https://issues.apache.org/jira/browse/LUCENE-1575 なお、従来のHitCollectorユーザのためのHitCollectorWrapperクラスが用意されており、HitCollectorWrapperのコンストラクタにHitCollectorオブジェクトを渡してnewすると、新しいCollectorクラスとしてHitCollectorWrapperを使うことができるようになっている(しかしこれもdeprecatedクラスであり、HitCollectorがなくなるときに一緒になくなる運命にある)。 スコア計算を行うCollectorはLucene提供のTopScoreDocCollectorを使うといいだろう: TopScoreDocCollector collector = TopScoreDocCollector.create(10,false); また、Searchable.search(Weight, Filter, int, Sort)を使うとスコア計算がされなくなり、指定されたソートのみを行うようになった: https://issues.apache.org/jira/browse/LUCENE-1656 もしソートもスコア計算もしたいのであれば、TopFieldCollectorを使ってSearchable.search(Weight, Filter, Collector)を次のように使う必要がある: TopFieldCollector tfc = TopFieldCollector.create(sort, numHits, fillFields, 2009.06.07 Sunday
ほぼリアルタイムサーチ(2.9)
「ほぼリアルタイムサーチ(Near Real Time Search; NRT)」はLucene 2.9に加わった機能である。「リアルタイムサーチ」機能とは、コンテンツ管理システムなどで管理されているドキュメントが追加/変更/削除などされた場合、検索結果がコンテンツとリアルタイムに連動している検索システムの検索機能のことである。
Lucene 2.9のリアルタイムサーチは「ほぼ」リアルタイムを実現するために、IndexWriterにgetReader()メソッドを加えた。これにより、インデックスにIndexWriterオブジェクトを使って追加したドキュメントが、同オブジェクトのgetReader()で取得したIndexReaderを使って即検索できるようになった: writer.addDocument(doc); // ドキュメントの追加 「ほぼリアルタイム」の「ほぼ」がついている意味は、getReader()によりどのくらい素早くIndexReaderを返せるか保証していないためである。今後もコミュニティのフィードバックを見ながら改良していくことが予定されている機能である。 http://wiki.apache.org/lucene-java/NearRealtimeSearch |
+ Solrによるブログ内検索
+ PROFILE
+ LINKS
+ Lucene&Solrデモ
+ ThinkIT記事
+ RECOMMEND
+ RECOMMEND
Lucene in Action (JUGEMレビュー »)
Erik Hatcher,Otis Gospodnetic,Mike McCandless FastVectorHighlighterについて解説記事を寄稿しました。
+ RECOMMEND
+ SELECTED ENTRIES
+ RECENT COMMENTS
+ RECENT TRACKBACK
+ CATEGORIES
+ ARCHIVES
+ MOBILE
+ SPONSORED LINKS
|
(C) 2024 ブログ JUGEM Some Rights Reserved.
|
PAGE TOP |