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> {
|
override fun search(userId: Int, terms: SearchTerms): List<PersistedNoteMetadata> {
|
||||||
val searcher = getIndexSearcher(userId)
|
val searcher = getIndexSearcher(userId)
|
||||||
|
|
||||||
val builder = BooleanQuery.Builder()
|
val query = query {
|
||||||
|
or { titleField eq terms.title }
|
||||||
terms.title?.let {
|
or { tagsField eq terms.tag }
|
||||||
val titleQuery = FuzzyQuery(Term(titleField, it))
|
or { contentField eq terms.content }
|
||||||
builder.add(BooleanClause(titleQuery, BooleanClause.Occur.SHOULD))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
val topDocs = searcher.search(query, 10)
|
||||||
logger.debug("Searching: `$query` results: ${topDocs.totalHits.value}")
|
logger.debug("Searching: `$query` results: ${topDocs.totalHits.value}")
|
||||||
return topDocs.toResults(searcher)
|
return topDocs.toResults(searcher)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user