Skip to content

Commit c88174d

Browse files
committed
support nested of nested aggregations
1 parent 1df5fae commit c88174d

File tree

7 files changed

+533
-283
lines changed

7 files changed

+533
-283
lines changed

es6/sql-bridge/src/main/scala/app/softnetwork/elastic/sql/bridge/ElasticAggregation.scala

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import app.softnetwork.elastic.sql.query.{
77
Criteria,
88
Desc,
99
Field,
10+
NestedElement,
11+
NestedElements,
1012
SortOrder
1113
}
1214
import app.softnetwork.elastic.sql.function._
@@ -46,9 +48,10 @@ case class ElasticAggregation(
4648
filteredAgg: Option[FilterAggregation] = None,
4749
aggType: AggregateFunction,
4850
agg: Aggregation,
49-
direction: Option[SortOrder] = None
51+
direction: Option[SortOrder] = None,
52+
nestedElement: Option[NestedElement] = None
5053
) {
51-
val nested: Boolean = nestedAgg.nonEmpty
54+
val nested: Boolean = nestedElement.nonEmpty
5255
val filtered: Boolean = filteredAgg.nonEmpty
5356
}
5457

@@ -59,7 +62,7 @@ object ElasticAggregation {
5962
bucketsDirection: Map[String, SortOrder]
6063
): ElasticAggregation = {
6164
import sqlAgg._
62-
val sourceField = identifier.name
65+
val sourceField = identifier.path
6366

6467
val direction = bucketsDirection.get(identifier.identifierName)
6568

@@ -175,18 +178,45 @@ object ElasticAggregation {
175178
aggPath ++= Seq(aggName)
176179
}
177180

181+
val nestedElement = identifier.nestedElement
182+
183+
val nestedElements: Seq[NestedElement] =
184+
nestedElement.map(n => NestedElements.buildNestedTrees(Seq(n))).getOrElse(Nil)
185+
178186
val nestedAgg =
179-
if (identifier.nested) {
180-
val path = sourceField.split("\\.").head
181-
val nestedAgg = s"nested_${identifier.nestedType.getOrElse(aggName)}"
182-
aggPath ++= Seq(nestedAgg)
183-
filtered()
184-
Some(nestedAggregation(nestedAgg, path))
185-
} else {
186-
filtered()
187-
None
187+
nestedElements match {
188+
case Nil =>
189+
None
190+
case nestedElements =>
191+
def buildNested(n: NestedElement): NestedAggregation = {
192+
aggPath ++= Seq(n.innerHitsName)
193+
val children = n.children
194+
if (children.nonEmpty) {
195+
val innerAggs = children.map(buildNested)
196+
val combinedAgg = if (innerAggs.size == 1) {
197+
innerAggs.head
198+
} else {
199+
innerAggs.reduceLeft { (agg1, agg2) =>
200+
agg1.copy(subaggs = agg1.subaggs ++ Seq(agg2))
201+
}
202+
}
203+
nestedAggregation(
204+
n.innerHitsName,
205+
n.path
206+
) subaggs Seq(combinedAgg)
207+
} else {
208+
nestedAggregation(
209+
n.innerHitsName,
210+
n.path
211+
)
212+
}
213+
}
214+
215+
Some(buildNested(nestedElements.head))
188216
}
189217

218+
filtered()
219+
190220
ElasticAggregation(
191221
aggPath.mkString("."),
192222
field,
@@ -195,7 +225,8 @@ object ElasticAggregation {
195225
nestedAgg = nestedAgg,
196226
aggType = aggType,
197227
agg = _agg,
198-
direction = direction
228+
direction = direction,
229+
nestedElement = nestedElement
199230
)
200231
}
201232

@@ -210,13 +241,13 @@ object ElasticAggregation {
210241
val agg = {
211242
bucketsDirection.get(bucket.identifier.identifierName) match {
212243
case Some(direction) =>
213-
termsAgg(bucket.name, s"${bucket.identifier.name}.keyword")
244+
termsAgg(bucket.name, s"${bucket.identifier.path}.keyword")
214245
.order(Seq(direction match {
215246
case Asc => TermsOrder(bucket.name, asc = true)
216247
case _ => TermsOrder(bucket.name, asc = false)
217248
}))
218249
case None =>
219-
termsAgg(bucket.name, s"${bucket.identifier.name}.keyword")
250+
termsAgg(bucket.name, s"${bucket.identifier.path}.keyword")
220251
}
221252
}
222253
current match {

0 commit comments

Comments
 (0)