diff --git a/search/src/main/kotlin/LuceneDsl.kt b/search/src/main/kotlin/LuceneDsl.kt new file mode 100644 index 0000000..0ca02fd --- /dev/null +++ b/search/src/main/kotlin/LuceneDsl.kt @@ -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() + + 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?) diff --git a/search/src/main/kotlin/NoteSearcherImpl.kt b/search/src/main/kotlin/NoteSearcherImpl.kt index 98f9237..8956754 100644 --- a/search/src/main/kotlin/NoteSearcherImpl.kt +++ b/search/src/main/kotlin/NoteSearcherImpl.kt @@ -86,25 +86,12 @@ class NoteSearcherImpl(basePath: Path = Path.of("/tmp", "lucene")) : NoteSearche override fun search(userId: Int, terms: SearchTerms): List { 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)