Skip to content

Commit

Permalink
Simplified aggregation function references
Browse files Browse the repository at this point in the history
  • Loading branch information
darkfrog26 committed Jun 11, 2024
1 parent 00eef96 commit ac65581
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 52 deletions.
41 changes: 15 additions & 26 deletions all/src/test/scala/spec/AggregationSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,52 +54,41 @@ class AggregationSpec extends AsyncWordSpec with AsyncIOSpec with Matchers {
Person.commit()
}
"get a basic aggregation" in {
val max = Person.age.max()
val min = Person.age.min()
val avg = Person.age.avg()
val sum = Person.age.sum()
val count = Person.age.count()

Person.withSearchContext { implicit context =>
Person.query
.filter(Person.age <=> (5, 16))
.aggregate(max, min, avg, sum, count)
.aggregate(Person.age.max, Person.age.min, Person.age.avg, Person.age.sum, Person.age.count)
.stream
.compile
.toList
.map { list =>
list.map(m => m(max)) should be(List(15))
list.map(m => m(min)) should be(List(11))
list.map(m => m(avg)) should be(List(12.666666666666666))
list.map(m => m(sum)) should be(List(38))
list.map(m => m(count)) should be(List(3))
list.map(m => m(Person.age.max)) should be(List(15))
list.map(m => m(Person.age.min)) should be(List(11))
list.map(m => m(Person.age.avg)) should be(List(12.666666666666666))
list.map(m => m(Person.age.sum)) should be(List(38))
list.map(m => m(Person.age.count)) should be(List(3))
}
}
}
"aggregate with grouping and filtering" in {
val ids = Person._id.concat()
val names = Person.name.concat()
val age = Person.age.group()
val count = Person.age.count()
Person.query
.aggregate(ids, names, age, count)
.sort(count, SortDirection.Descending)
.filter(count > 1)
.aggregate(Person._id.concat, Person.name.concat, Person.age.group, Person.age.count)
.sort(Person.age.count, SortDirection.Descending)
.filter(Person.age.count > 1)
.toList
.map { list =>
list.map(_(names)).map(_.toSet) should be(List(Set("Oscar", "Adam")))
list.map(_(ids)).map(_.toSet) should be(List(Set(oscar._id, adam._id)))
list.map(_(age)) should be(List(21))
list.map(_(count)) should be(List(2))
list.map(_(Person.name.concat)).map(_.toSet) should be(List(Set("Oscar", "Adam")))
list.map(_(Person._id.concat)).map(_.toSet) should be(List(Set(oscar._id, adam._id)))
list.map(_(Person.age.group)) should be(List(21))
list.map(_(Person.age.count)) should be(List(2))
}
}
"aggregate with age concatenation" in {
val ages = Person.age.concat()
Person.query
.aggregate(ages)
.aggregate(Person.age.concat)
.toList
.map { list =>
list.map(_(ages).toSet) should be(List(
list.map(_(Person.age.concat).toSet) should be(List(
Set(2, 4, 11, 12, 15, 21, 21, 22, 23, 30, 33, 35, 42, 53, 62, 72, 81, 89, 99, 102)
))
}
Expand Down
26 changes: 10 additions & 16 deletions all/src/test/scala/spec/SimpleHaloAndSQLiteSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -186,22 +186,16 @@ class SimpleHaloAndSQLiteSpec extends AsyncWordSpec with AsyncIOSpec with Matche
}
}
"query with aggregate functions" in {
Person.withSearchContext { implicit context =>
val minAge = Person.age.min()
val maxAge = Person.age.max()
val avgAge = Person.age.avg()
val sumAge = Person.age.sum()
Person.query.aggregate(
minAge,
maxAge,
avgAge,
sumAge
).stream.compile.toList.map { list =>
list.map(m => m(minAge)).toSet should be(Set(19))
list.map(m => m(maxAge)).toSet should be(Set(21))
list.map(m => m(avgAge)).toSet should be(Set(20.0))
list.map(m => m(sumAge)).toSet should be(Set(40.0))
}
Person.query.aggregate(
Person.age.min,
Person.age.max,
Person.age.avg,
Person.age.sum
).toList.map { list =>
list.map(m => m(Person.age.min)).toSet should be(Set(19))
list.map(m => m(Person.age.max)).toSet should be(Set(21))
list.map(m => m(Person.age.avg)).toSet should be(Set(20.0))
list.map(m => m(Person.age.sum)).toSet should be(Set(40.0))
}
}
"delete John" in {
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/scala/lightdb/aggregate/AggregateFunction.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import lightdb.index.{FilterSupport, Index}

case class AggregateFunction[T, F, D <: Document[D]](name: String, index: Index[F, D], `type`: AggregateType)
(implicit val rw: RW[T]) extends FilterSupport[F, D, AggregateFilter[D]] {
def rename(name: String): AggregateFunction[T, F, D] = copy(name = name)

override implicit def fRW: RW[F] = index.fRW

override def is(value: F): AggregateFilter[D] = index.aggregateFilterSupport(name).is(value)
Expand Down
18 changes: 8 additions & 10 deletions core/src/main/scala/lightdb/index/Index.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,14 @@ trait Index[F, D <: Document[D]] extends FilterSupport[F, D, Filter[D]] {
def get: D => List[F]
def getJson: D => List[Json] = (doc: D) => get(doc).map(_.json)

private def un: String = Unique(length = 8, characters = Unique.LettersLower)

def max(name: String = un): AggregateFunction[F, F, D] = AggregateFunction(name, this, AggregateType.Max)
def min(name: String = un): AggregateFunction[F, F, D] = AggregateFunction(name, this, AggregateType.Min)
def avg(name: String = un): AggregateFunction[Double, F, D] = AggregateFunction(name, this, AggregateType.Avg)
def sum(name: String = un): AggregateFunction[F, F, D] = AggregateFunction(name, this, AggregateType.Sum)
def count(name: String = un): AggregateFunction[Int, F, D] = AggregateFunction(name, this, AggregateType.Count)
def countDistinct(name: String = un): AggregateFunction[Int, F, D] = AggregateFunction(name, this, AggregateType.CountDistinct)
def group(name: String = un): AggregateFunction[F, F, D] = AggregateFunction(name, this, AggregateType.Group)
def concat(name: String = un): AggregateFunction[List[F], F, D] = AggregateFunction(name, this, AggregateType.Concat)(Index.ConcatRW)
lazy val max: AggregateFunction[F, F, D] = AggregateFunction(s"${fieldName}Max", this, AggregateType.Max)
lazy val min: AggregateFunction[F, F, D] = AggregateFunction(s"${fieldName}Min", this, AggregateType.Min)
lazy val avg: AggregateFunction[Double, F, D] = AggregateFunction(s"${fieldName}Avg", this, AggregateType.Avg)
lazy val sum: AggregateFunction[F, F, D] = AggregateFunction(s"${fieldName}Sum", this, AggregateType.Sum)
lazy val count: AggregateFunction[Int, F, D] = AggregateFunction(s"${fieldName}Count", this, AggregateType.Count)
lazy val countDistinct: AggregateFunction[Int, F, D] = AggregateFunction(s"${fieldName}CountDistinct", this, AggregateType.CountDistinct)
lazy val group: AggregateFunction[F, F, D] = AggregateFunction(s"${fieldName}Group", this, AggregateType.Group)
lazy val concat: AggregateFunction[List[F], F, D] = AggregateFunction(s"${fieldName}Concat", this, AggregateType.Concat)(Index.ConcatRW)

def aggregateFilterSupport(name: String): FilterSupport[F, D, AggregateFilter[D]]
}
Expand Down

0 comments on commit ac65581

Please sign in to comment.