From 372652d332ddd6567c9adf1dda5b926585012cbd Mon Sep 17 00:00:00 2001 From: Hubert Van De Walle Date: Fri, 21 Aug 2020 16:28:03 +0200 Subject: [PATCH] Improve dsl --- search/src/main/kotlin/Extractors.kt | 16 ++++----- search/src/main/kotlin/LuceneDsl.kt | 18 ++++++---- search/src/main/kotlin/NoteSearcherImpl.kt | 42 +++++++++------------- 3 files changed, 34 insertions(+), 42 deletions(-) diff --git a/search/src/main/kotlin/Extractors.kt b/search/src/main/kotlin/Extractors.kt index ae1db61..295a6dd 100644 --- a/search/src/main/kotlin/Extractors.kt +++ b/search/src/main/kotlin/Extractors.kt @@ -23,13 +23,9 @@ internal fun PersistedNote.toDocument(): Document { } } -internal fun TopDocs.toResults(searcher: IndexSearcher) = scoreDocs.map { - searcher.doc(it.doc).let { doc -> - PersistedNoteMetadata( - title = doc.get(titleField), - uuid = UuidFieldConverter.fromDoc(doc.get(uuidField)), - updatedAt = LocalDateTimeFieldConverter.fromDoc(doc.get(updatedAtField)), - tags = TagsFieldConverter.fromDoc(doc.get(tagsField)) - ) - } -} +internal fun Document.toNoteMeta() = PersistedNoteMetadata( + title = get(titleField), + uuid = UuidFieldConverter.fromDoc(get(uuidField)), + updatedAt = LocalDateTimeFieldConverter.fromDoc(get(updatedAtField)), + tags = TagsFieldConverter.fromDoc(get(tagsField)) +) diff --git a/search/src/main/kotlin/LuceneDsl.kt b/search/src/main/kotlin/LuceneDsl.kt index 0ca02fd..a1e374d 100644 --- a/search/src/main/kotlin/LuceneDsl.kt +++ b/search/src/main/kotlin/LuceneDsl.kt @@ -1,12 +1,14 @@ package be.simplenotes.search +import org.apache.lucene.document.Document import org.apache.lucene.index.Term -import org.apache.lucene.search.BooleanClause -import org.apache.lucene.search.BooleanQuery -import org.apache.lucene.search.FuzzyQuery -import org.apache.lucene.search.Query +import org.apache.lucene.search.* +import org.slf4j.LoggerFactory -fun query(receiver: LuceneDsl.() -> Unit): Query { +private val logger = LoggerFactory.getLogger("be.simplenotes.search.dsl") + +fun IndexSearcher.query(receiver: LuceneDsl.() -> Unit): List { + val indexSearcher = this val builder = BooleanQuery.Builder() val dsl = LuceneDsl() dsl.apply { this.receiver() } @@ -15,11 +17,15 @@ fun query(receiver: LuceneDsl.() -> Unit): Query { builder.add(BooleanClause(FuzzyQuery(Term(field, query)), BooleanClause.Occur.SHOULD)) } } - return builder.build() + val query = builder.build() + val topDocs = indexSearcher.search(query, dsl.count) + logger.debug("Searching: `$query` results: ${topDocs.totalHits.value}") + return topDocs.scoreDocs.map { indexSearcher.doc(it.doc) } } class LuceneDsl { val clauses = mutableListOf() + var count: Int = 10 fun addBooleanClause(booleanDsl: BooleanExpression) { clauses.add(booleanDsl) diff --git a/search/src/main/kotlin/NoteSearcherImpl.kt b/search/src/main/kotlin/NoteSearcherImpl.kt index 8956754..254860e 100644 --- a/search/src/main/kotlin/NoteSearcherImpl.kt +++ b/search/src/main/kotlin/NoteSearcherImpl.kt @@ -1,13 +1,14 @@ package be.simplenotes.search import be.simplenotes.domain.model.PersistedNote -import be.simplenotes.domain.model.PersistedNoteMetadata import be.simplenotes.domain.usecases.search.NoteSearcher import be.simplenotes.domain.usecases.search.SearchTerms import be.simplenotes.search.utils.rmdir import org.apache.lucene.analysis.standard.StandardAnalyzer +import org.apache.lucene.document.Document import org.apache.lucene.index.* -import org.apache.lucene.search.* +import org.apache.lucene.search.IndexSearcher +import org.apache.lucene.search.TermQuery import org.apache.lucene.store.Directory import org.apache.lucene.store.FSDirectory import org.slf4j.LoggerFactory @@ -26,22 +27,25 @@ class NoteSearcherImpl(basePath: Path = Path.of("/tmp", "lucene")) : NoteSearche return FSDirectory.open(index) } - private fun getIndexSearcher(userId: Int): IndexSearcher { + private fun indexSearcher(userId: Int): IndexSearcher { val directory = getDirectory(userId) val reader: IndexReader = DirectoryReader.open(directory) return IndexSearcher(reader) } + + private fun writer(userId: Int): IndexWriter { + val dir = getDirectory(userId) + val config = IndexWriterConfig(StandardAnalyzer()) + return IndexWriter(dir, config) + } // endregion override fun indexNote(userId: Int, note: PersistedNote) { logger.debug("Indexing note ${note.uuid} for user $userId") - val dir = getDirectory(userId) - val config = IndexWriterConfig(StandardAnalyzer()) - val writer = IndexWriter(dir, config) val doc = note.toDocument() - with(writer) { + with(writer(userId)) { addDocument(doc) commit() close() @@ -51,12 +55,9 @@ class NoteSearcherImpl(basePath: Path = Path.of("/tmp", "lucene")) : NoteSearche override fun indexNotes(userId: Int, notes: List) { logger.debug("Indexing notes for user $userId") - val dir = getDirectory(userId) - val config = IndexWriterConfig(StandardAnalyzer()) - val writer = IndexWriter(dir, config) val docs = notes.map { it.toDocument() } - with(writer) { + with(writer(userId)) { addDocuments(docs) commit() close() @@ -66,11 +67,7 @@ class NoteSearcherImpl(basePath: Path = Path.of("/tmp", "lucene")) : NoteSearche override fun deleteIndex(userId: Int, uuid: UUID) { logger.debug("Deleting index $uuid for user $userId") - val dir = getDirectory(userId) - val config = IndexWriterConfig(StandardAnalyzer()) - val writer = IndexWriter(dir, config) - - with(writer) { + with(writer(userId)) { deleteDocuments(TermQuery(Term(uuidField, UuidFieldConverter.toDoc(uuid)))) commit() close() @@ -83,19 +80,12 @@ class NoteSearcherImpl(basePath: Path = Path.of("/tmp", "lucene")) : NoteSearche indexNote(userId, note) } - override fun search(userId: Int, terms: SearchTerms): List { - val searcher = getIndexSearcher(userId) - - val query = query { + override fun search(userId: Int, terms: SearchTerms) = + indexSearcher(userId).query { or { titleField eq terms.title } or { tagsField eq terms.tag } or { contentField eq terms.content } - } - - val topDocs = searcher.search(query, 10) - logger.debug("Searching: `$query` results: ${topDocs.totalHits.value}") - return topDocs.toResults(searcher) - } + }.map(Document::toNoteMeta) override fun dropIndex(userId: Int) = rmdir(File(baseFile, userId.toString()).toPath())