Create lucene dsl
This commit is contained in:
parent
7305fb47c7
commit
f12947acbd
35
search/src/main/kotlin/LuceneDsl.kt
Normal file
35
search/src/main/kotlin/LuceneDsl.kt
Normal 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?)
|
||||
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user