Skip to content

Commit

Permalink
Much better Lucene support
Browse files Browse the repository at this point in the history
  • Loading branch information
darkfrog26 committed May 16, 2024
1 parent a29d33b commit e39be7f
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 12 deletions.
6 changes: 6 additions & 0 deletions all/src/test/scala/spec/SimpleHaloAndLuceneSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import lightdb._
import lightdb.halo.HaloDBSupport
import lightdb.lucene.{LuceneIndex, LuceneSupport}
import lightdb.model.Collection
import lightdb.query.Sort
import lightdb.upgrade.DatabaseUpgrade
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AsyncWordSpec
Expand Down Expand Up @@ -156,6 +157,11 @@ class SimpleHaloAndLuceneSpec extends AsyncWordSpec with AsyncIOSpec with Matche
}
}
}
"sort by age" in {
Person.query.sort(Sort.ByField(Person.age)).toList.map { people =>
people.map(_.name) should be(List("Jane Doe", "John Doe"))
}
}
"delete John" in {
Person.delete(id1).map { deleted =>
deleted should be(id1)
Expand Down
19 changes: 9 additions & 10 deletions lucene/src/main/scala/lightdb/lucene/LuceneIndex.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import fabric.define.DefType
import fabric.rw._
import lightdb.Document
import lightdb.index.{IndexSupport, IndexedField}
import org.apache.lucene.document.Field
import org.apache.lucene.index.Term
import org.apache.lucene.search._
import org.apache.lucene.{document => ld}
import org.apache.lucene.document._

case class LuceneIndex[F, D <: Document[D]](fieldName: String,
indexSupport: IndexSupport[D],
Expand All @@ -32,27 +31,27 @@ case class LuceneIndex[F, D <: Document[D]](fieldName: String,
}

def between(lower: F, upper: F): LuceneFilter[D] = LuceneFilter(() => (lower.json, upper.json) match {
case (NumInt(l, _), NumInt(u, _)) => ld.LongField.newRangeQuery(fieldName, l, u)
case (NumInt(l, _), NumInt(u, _)) => LongField.newRangeQuery(fieldName, l, u)
case _ => throw new RuntimeException(s"Unsupported between for $lower - $upper (${rw.definition})")
})

protected[lightdb] def createFields(doc: D): List[ld.Field] = if (tokenized) {
protected[lightdb] def createFields(doc: D): List[Field] = if (tokenized) {
getJson(doc).flatMap {
case Null => Nil
case Str(s, _) => List(s)
case f => throw new RuntimeException(s"Unsupported tokenized value: $f (${rw.definition})")
}.map { value =>
new ld.Field(fieldName, value, if (store) ld.TextField.TYPE_STORED else ld.TextField.TYPE_NOT_STORED)
new Field(fieldName, value, if (store) TextField.TYPE_STORED else TextField.TYPE_NOT_STORED)
}
} else {
def fs: Field.Store = if (store) ld.Field.Store.YES else ld.Field.Store.NO
def fs: Field.Store = if (store) Field.Store.YES else Field.Store.NO

getJson(doc).flatMap {
case Null => None
case Str(s, _) => Some(new ld.StringField(fieldName, s, fs))
case Bool(b, _) => Some(new ld.StringField(fieldName, b.toString, fs))
case NumInt(l, _) => Some(new ld.LongField(fieldName, l, fs))
case NumDec(bd, _) => Some(new ld.StringField(fieldName, bd.toString(), fs))
case Str(s, _) => Some(new StringField(fieldName, s, fs))
case Bool(b, _) => Some(new StringField(fieldName, b.toString, fs))
case NumInt(l, _) => Some(new LongField(fieldName, l, fs))
case NumDec(bd, _) => Some(new DoubleField(fieldName, bd.toDouble, fs))
case json => throw new RuntimeException(s"Unsupported JSON: $json (${rw.definition})")
}
}
Expand Down
11 changes: 9 additions & 2 deletions lucene/src/main/scala/lightdb/lucene/LuceneSupport.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package lightdb.lucene

import cats.effect.IO
import fabric.define.DefType
import lightdb._
import lightdb.index.{IndexSupport, IndexedField}
import lightdb.query.{Filter, PageContext, PagedResults, Query, SearchContext, Sort}
import org.apache.lucene.search.{IndexSearcher, MatchAllDocsQuery, ScoreDoc, SearcherFactory, SearcherManager, SortField, TopFieldDocs, Query => LuceneQuery, Sort => LuceneSort}
import org.apache.lucene.search.{IndexSearcher, MatchAllDocsQuery, ScoreDoc, SearcherFactory, SearcherManager, SortField, SortedNumericSortField, TopFieldDocs, Query => LuceneQuery, Sort => LuceneSort}
import org.apache.lucene.index.StoredFields

trait LuceneSupport[D <: Document[D]] extends IndexSupport[D] {
Expand All @@ -17,7 +18,13 @@ trait LuceneSupport[D <: Document[D]] extends IndexSupport[D] {
private def sort2SortField(sort: Sort): SortField = sort match {
case Sort.BestMatch => SortField.FIELD_SCORE
case Sort.IndexOrder => SortField.FIELD_DOC
case Sort.ByField(field, reverse) => new SortField(field.fieldName, field.asInstanceOf[LuceneIndex[_, D]].sortType, reverse)
case Sort.ByField(field, reverse) =>
val f = field.asInstanceOf[LuceneIndex[_, D]]
f.rw.definition match {
case DefType.Int => new SortedNumericSortField(field.fieldName, f.sortType, reverse)
case DefType.Str => new SortField(field.fieldName, f.sortType, reverse)
case d => throw new RuntimeException(s"Unsupported sort definition: $d")
}
}

override def doSearch(query: Query[D],
Expand Down

0 comments on commit e39be7f

Please sign in to comment.