Create lucene dsl

This commit is contained in:
Hubert Van De Walle 2020-08-21 16:02:10 +02:00
parent 7305fb47c7
commit f12947acbd
2 changed files with 39 additions and 17 deletions

View File

@ -0,0 +1,35 @@
package be.simplenotes.search
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
fun query(receiver: LuceneDsl.() -> Unit): Query {
val builder = BooleanQuery.Builder()
val dsl = LuceneDsl()
dsl.apply { this.receiver() }
dsl.clauses.forEach { (field, query) ->
query?.let {
builder.add(BooleanClause(FuzzyQuery(Term(field, query)), BooleanClause.Occur.SHOULD))
}
}
return builder.build()
}
class LuceneDsl {
val clauses = mutableListOf<BooleanExpression>()
fun addBooleanClause(booleanDsl: BooleanExpression) {
clauses.add(booleanDsl)
}
}
fun LuceneDsl.or(booleanExpression: () -> BooleanExpression) {
addBooleanClause(booleanExpression())
}
infix fun String.eq(query: String?) = BooleanExpression(this, query)
data class BooleanExpression(val term: String, val query: String?)

View File

@ -86,25 +86,12 @@ class NoteSearcherImpl(basePath: Path = Path.of("/tmp", "lucene")) : NoteSearche
override fun search(userId: Int, terms: SearchTerms): List<PersistedNoteMetadata> {
val searcher = getIndexSearcher(userId)
val builder = BooleanQuery.Builder()
terms.title?.let {
val titleQuery = FuzzyQuery(Term(titleField, it))
builder.add(BooleanClause(titleQuery, BooleanClause.Occur.SHOULD))
val query = query {
or { titleField eq terms.title }
or { tagsField eq terms.tag }
or { contentField eq terms.content }
}
terms.tag?.let {
val tagsQuery = FuzzyQuery(Term(tagsField, it))
builder.add(BooleanClause(tagsQuery, BooleanClause.Occur.SHOULD))
}
terms.content?.let {
val contentQuery = FuzzyQuery(Term(contentField, it))
builder.add(BooleanClause(contentQuery, BooleanClause.Occur.SHOULD))
}
val query = builder.build()
val topDocs = searcher.search(query, 10)
logger.debug("Searching: `$query` results: ${topDocs.totalHits.value}")
return topDocs.toResults(searcher)