2016-09-11 11 views
0

Lucene 6.2を使用して(ScalaのSlickを使用して)MySQLからデータのインデックスを作成しようとしています。以下はコードですLucene 6.2でScalaを使用して検索できません

package oc.api.services 

/** 
    * Created by sujit on 9/7/16. 
    */ 
import org.apache.lucene.document._ 
import org.apache.lucene.analysis.standard.StandardAnalyzer 
import org.apache.lucene.index._ 
import org.apache.lucene.search.IndexSearcher 
import java.io.{File, IOException} 
import java.nio.file.Paths 

import akka.actor.ActorSystem 
import akka.event.{Logging, LoggingAdapter} 
import akka.stream.ActorMaterializer 
import oc.api.utils.{Config, DatabaseService} 
import org.apache.lucene.analysis.core.KeywordAnalyzer 
import org.apache.lucene.index.IndexWriterConfig.OpenMode 
import org.apache.lucene.queryparser.classic.{QueryParser} 
import org.apache.lucene.store.FSDirectory 

import scala.concurrent.ExecutionContext 

class Indexer extends Config { 
    implicit val actorSystem = ActorSystem() 
    implicit val executor: ExecutionContext = actorSystem.dispatcher 
    implicit val log: LoggingAdapter = Logging(actorSystem, getClass) 
    implicit val materializer: ActorMaterializer = ActorMaterializer() 

    val databaseService = new DatabaseService(jdbcUrl, dbUser, dbPassword) 

    val notesService = new NotesService(databaseService)  

    def setIndex = { 
    val IndexStoreDir = Paths.get("/var/www/html/LuceneIndex") 
    val analyzer = new KeywordAnalyzer() 
    val writerConfig = new IndexWriterConfig(analyzer) 
    writerConfig.setOpenMode(OpenMode.CREATE) 
    writerConfig.setRAMBufferSizeMB(500) 
    val directory = FSDirectory.open(IndexStoreDir) 
    var writer = new IndexWriter(directory, writerConfig) 
    val notes = notesService.getNotes() //Gets all notes from slick. Data is coming in getNotes() 
    var doc = new Document() 
    var count = 0 

    val stringType = new FieldType() 
    notes.map(_.foreach{ 
     case(note) => 
     doc = new Document() 

     var field = new TextField("title", note.title, Field.Store.YES) 
     doc.add(field) 

     field = new TextField("teaser", note.teaser, Field.Store.YES) 
     doc.add(field) 

     field = new TextField("description", note.description, Field.Store.YES) 
     doc.add(field) 

     writer.addDocument(doc) 
    }) 
    writer.commit() 
    } 

    def search(keyword: String) = { 
    val IndexStoreDir = Paths.get("/var/www/html/LuceneIndex") 
    var directoryReader = DirectoryReader.open(FSDirectory.open(IndexStoreDir)) 
    val analyzer = new StandardAnalyzer() 

    val searcher = new IndexSearcher(directoryReader) 

    val mqp = new QueryParser("title", analyzer) //MultiFieldQueryParser(filesToSearch,analyzer) 
    val query = mqp.parse(keyword) 

    val hits = searcher.search(query,10) 
    val scoreDoc = hits.scoreDocs 
    println(scoreDoc.length) 
    } 

} 

object Indexer extends App { 
    val index = new Indexer 
    index.setIndex 
    index.search("Donec") 
} 

setIndex関数は、指定されたPathで期待通りに機能しています。しかし、私はキーワードに基づいてインデックスを検索している間、0の結果をスローします。 seach機能に間違いはありますか?どのように解決できますか?

答えて

2

主な理由はおそらくアナライザの不一致です。索引付けにはKeywordAnalyzerを使用しますが、これはまったく分析しません。検索にはStandardAnalyzerを使用します。あなたの例では、クエリ"Donec"が解析され、title:donecのように解析されます; dはnew TermQuery(new Term("title", "donec"))です。インデックス時にキーワードアナライザーを使用したため、これは正確なタイトルがdonecの文書にのみ一致します。インデックス作成にも同じアナライザを使用するようにしてください。

もう1つのことがあるかもしれません - これだけしか推測できません - notesService.getNotes()は滑らかであることを考えるとFuture[_](または同様の非同期タイプ)かもしれません。そうである場合は、.map()へのコールのすべてのドキュメントを追加します。これは、将来解決される予定です。ただし、writer.commit()呼び出しは、すべてのドキュメントを追加する前に呼び出しスレッドで発生するため、コミットをmapコールバックに移動する必要があります。

+0

ここではまず、KeywordAnalyzerを誤って使いました。次に、未来の地図の中にwriter.commitを使用しました。これは私に結果をもたらしました。ご協力いただきありがとうございます。正しいコードで質問を編集しました。 – Sujit

+0

インデックス作成プロセスを最適化するためのスレッドを使用して、上記のコードをどのように実装できますか? – Sujit

+0

@Sujitこれについて新しい質問をすることをお勧めします。 – knutwalker

関連する問題