Improve dsl
This commit is contained in:
parent
f12947acbd
commit
372652d332
@ -23,13 +23,9 @@ internal fun PersistedNote.toDocument(): Document {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun TopDocs.toResults(searcher: IndexSearcher) = scoreDocs.map {
|
internal fun Document.toNoteMeta() = PersistedNoteMetadata(
|
||||||
searcher.doc(it.doc).let { doc ->
|
title = get(titleField),
|
||||||
PersistedNoteMetadata(
|
uuid = UuidFieldConverter.fromDoc(get(uuidField)),
|
||||||
title = doc.get(titleField),
|
updatedAt = LocalDateTimeFieldConverter.fromDoc(get(updatedAtField)),
|
||||||
uuid = UuidFieldConverter.fromDoc(doc.get(uuidField)),
|
tags = TagsFieldConverter.fromDoc(get(tagsField))
|
||||||
updatedAt = LocalDateTimeFieldConverter.fromDoc(doc.get(updatedAtField)),
|
)
|
||||||
tags = TagsFieldConverter.fromDoc(doc.get(tagsField))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
package be.simplenotes.search
|
package be.simplenotes.search
|
||||||
|
|
||||||
|
import org.apache.lucene.document.Document
|
||||||
import org.apache.lucene.index.Term
|
import org.apache.lucene.index.Term
|
||||||
import org.apache.lucene.search.BooleanClause
|
import org.apache.lucene.search.*
|
||||||
import org.apache.lucene.search.BooleanQuery
|
import org.slf4j.LoggerFactory
|
||||||
import org.apache.lucene.search.FuzzyQuery
|
|
||||||
import org.apache.lucene.search.Query
|
|
||||||
|
|
||||||
fun query(receiver: LuceneDsl.() -> Unit): Query {
|
private val logger = LoggerFactory.getLogger("be.simplenotes.search.dsl")
|
||||||
|
|
||||||
|
fun IndexSearcher.query(receiver: LuceneDsl.() -> Unit): List<Document> {
|
||||||
|
val indexSearcher = this
|
||||||
val builder = BooleanQuery.Builder()
|
val builder = BooleanQuery.Builder()
|
||||||
val dsl = LuceneDsl()
|
val dsl = LuceneDsl()
|
||||||
dsl.apply { this.receiver() }
|
dsl.apply { this.receiver() }
|
||||||
@ -15,11 +17,15 @@ fun query(receiver: LuceneDsl.() -> Unit): Query {
|
|||||||
builder.add(BooleanClause(FuzzyQuery(Term(field, query)), BooleanClause.Occur.SHOULD))
|
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 {
|
class LuceneDsl {
|
||||||
val clauses = mutableListOf<BooleanExpression>()
|
val clauses = mutableListOf<BooleanExpression>()
|
||||||
|
var count: Int = 10
|
||||||
|
|
||||||
fun addBooleanClause(booleanDsl: BooleanExpression) {
|
fun addBooleanClause(booleanDsl: BooleanExpression) {
|
||||||
clauses.add(booleanDsl)
|
clauses.add(booleanDsl)
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
package be.simplenotes.search
|
package be.simplenotes.search
|
||||||
|
|
||||||
import be.simplenotes.domain.model.PersistedNote
|
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.NoteSearcher
|
||||||
import be.simplenotes.domain.usecases.search.SearchTerms
|
import be.simplenotes.domain.usecases.search.SearchTerms
|
||||||
import be.simplenotes.search.utils.rmdir
|
import be.simplenotes.search.utils.rmdir
|
||||||
import org.apache.lucene.analysis.standard.StandardAnalyzer
|
import org.apache.lucene.analysis.standard.StandardAnalyzer
|
||||||
|
import org.apache.lucene.document.Document
|
||||||
import org.apache.lucene.index.*
|
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.Directory
|
||||||
import org.apache.lucene.store.FSDirectory
|
import org.apache.lucene.store.FSDirectory
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
@ -26,22 +27,25 @@ class NoteSearcherImpl(basePath: Path = Path.of("/tmp", "lucene")) : NoteSearche
|
|||||||
return FSDirectory.open(index)
|
return FSDirectory.open(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getIndexSearcher(userId: Int): IndexSearcher {
|
private fun indexSearcher(userId: Int): IndexSearcher {
|
||||||
val directory = getDirectory(userId)
|
val directory = getDirectory(userId)
|
||||||
val reader: IndexReader = DirectoryReader.open(directory)
|
val reader: IndexReader = DirectoryReader.open(directory)
|
||||||
return IndexSearcher(reader)
|
return IndexSearcher(reader)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun writer(userId: Int): IndexWriter {
|
||||||
|
val dir = getDirectory(userId)
|
||||||
|
val config = IndexWriterConfig(StandardAnalyzer())
|
||||||
|
return IndexWriter(dir, config)
|
||||||
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
override fun indexNote(userId: Int, note: PersistedNote) {
|
override fun indexNote(userId: Int, note: PersistedNote) {
|
||||||
logger.debug("Indexing note ${note.uuid} for user $userId")
|
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()
|
val doc = note.toDocument()
|
||||||
|
|
||||||
with(writer) {
|
with(writer(userId)) {
|
||||||
addDocument(doc)
|
addDocument(doc)
|
||||||
commit()
|
commit()
|
||||||
close()
|
close()
|
||||||
@ -51,12 +55,9 @@ class NoteSearcherImpl(basePath: Path = Path.of("/tmp", "lucene")) : NoteSearche
|
|||||||
override fun indexNotes(userId: Int, notes: List<PersistedNote>) {
|
override fun indexNotes(userId: Int, notes: List<PersistedNote>) {
|
||||||
logger.debug("Indexing notes for user $userId")
|
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() }
|
val docs = notes.map { it.toDocument() }
|
||||||
|
|
||||||
with(writer) {
|
with(writer(userId)) {
|
||||||
addDocuments(docs)
|
addDocuments(docs)
|
||||||
commit()
|
commit()
|
||||||
close()
|
close()
|
||||||
@ -66,11 +67,7 @@ class NoteSearcherImpl(basePath: Path = Path.of("/tmp", "lucene")) : NoteSearche
|
|||||||
override fun deleteIndex(userId: Int, uuid: UUID) {
|
override fun deleteIndex(userId: Int, uuid: UUID) {
|
||||||
logger.debug("Deleting index $uuid for user $userId")
|
logger.debug("Deleting index $uuid for user $userId")
|
||||||
|
|
||||||
val dir = getDirectory(userId)
|
with(writer(userId)) {
|
||||||
val config = IndexWriterConfig(StandardAnalyzer())
|
|
||||||
val writer = IndexWriter(dir, config)
|
|
||||||
|
|
||||||
with(writer) {
|
|
||||||
deleteDocuments(TermQuery(Term(uuidField, UuidFieldConverter.toDoc(uuid))))
|
deleteDocuments(TermQuery(Term(uuidField, UuidFieldConverter.toDoc(uuid))))
|
||||||
commit()
|
commit()
|
||||||
close()
|
close()
|
||||||
@ -83,19 +80,12 @@ class NoteSearcherImpl(basePath: Path = Path.of("/tmp", "lucene")) : NoteSearche
|
|||||||
indexNote(userId, note)
|
indexNote(userId, note)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun search(userId: Int, terms: SearchTerms): List<PersistedNoteMetadata> {
|
override fun search(userId: Int, terms: SearchTerms) =
|
||||||
val searcher = getIndexSearcher(userId)
|
indexSearcher(userId).query {
|
||||||
|
|
||||||
val query = query {
|
|
||||||
or { titleField eq terms.title }
|
or { titleField eq terms.title }
|
||||||
or { tagsField eq terms.tag }
|
or { tagsField eq terms.tag }
|
||||||
or { contentField eq terms.content }
|
or { contentField eq terms.content }
|
||||||
}
|
}.map(Document::toNoteMeta)
|
||||||
|
|
||||||
val topDocs = searcher.search(query, 10)
|
|
||||||
logger.debug("Searching: `$query` results: ${topDocs.totalHits.value}")
|
|
||||||
return topDocs.toResults(searcher)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dropIndex(userId: Int) = rmdir(File(baseFile, userId.toString()).toPath())
|
override fun dropIndex(userId: Int) = rmdir(File(baseFile, userId.toString()).toPath())
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user