11package app .softnetwork .elastic .sql .bridge
22
33import app .softnetwork .elastic .sql .query .{
4+ BetweenExpr ,
45 ElasticBoolQuery ,
56 ElasticChild ,
67 ElasticFilter ,
7- DistanceCriteria ,
88 ElasticMatch ,
99 ElasticNested ,
1010 ElasticParent ,
11- BetweenExpr ,
1211 GenericExpression ,
1312 InExpr ,
14- IsNotNullExpr ,
1513 IsNotNullCriteria ,
14+ IsNotNullExpr ,
15+ IsNullCriteria ,
1616 IsNullExpr ,
17- IsNullCriteria
17+ NestedElement
1818}
1919import com .sksamuel .elastic4s .ElasticApi ._
20+ import com .sksamuel .elastic4s .requests .common .FetchSourceContext
2021import com .sksamuel .elastic4s .requests .searches .queries .Query
2122
23+ import scala .annotation .tailrec
24+
2225case class ElasticQuery (filter : ElasticFilter ) {
2326 def query (
2427 innerHitsNames : Set [String ] = Set .empty,
@@ -39,15 +42,77 @@ case class ElasticQuery(filter: ElasticFilter) {
3942 criteria.asFilter(currentQuery).query(innerHitsNames, currentQuery)
4043 } else {
4144 val boolQuery = Option (ElasticBoolQuery (group = true ))
42- nestedQuery(
43- relationType.getOrElse(" " ),
44- criteria
45- .asFilter(boolQuery)
46- .query(innerHitsNames + innerHitsName.getOrElse(" " ), boolQuery)
47- ) /* .scoreMode(ScoreMode.None)*/
48- .inner(
49- innerHits(innerHitsName.getOrElse(" " )).from(0 ).size(limit.map(_.limit).getOrElse(3 ))
50- )
45+ val q = criteria
46+ .asFilter(boolQuery)
47+ .query(innerHitsNames + innerHitsName.getOrElse(" " ), boolQuery)
48+
49+ val nestedElements : Seq [NestedElement ] = criteria.nestedElements.sortBy(_.level)
50+ nestedElements.foreach(n => println(s " nestedElement: ${n.path}, level: ${n.level}" ))
51+
52+ val nestedParentsPath
53+ : collection.mutable.Map [String , (NestedElement , Seq [NestedElement ])] =
54+ collection.mutable.Map .empty
55+
56+ @ tailrec
57+ def getNestedParents (
58+ n : NestedElement ,
59+ parents : Seq [NestedElement ]
60+ ): Seq [NestedElement ] = {
61+ n.parent match {
62+ case Some (p) =>
63+ if (! nestedParentsPath.contains(p.path)) {
64+ nestedParentsPath += p.path -> (p, Seq (n))
65+ getNestedParents(p, p +: parents)
66+ } else {
67+ nestedParentsPath += p.path -> (p, nestedParentsPath(p.path)._2 :+ n)
68+ parents
69+ }
70+ case _ => parents
71+ }
72+ }
73+
74+ val nestedParents = getNestedParents(nestedElements.last, Seq .empty)
75+
76+ def buildNestedQuery (n : NestedElement ): Query = {
77+ val children = nestedParentsPath.get(n.path).map(_._2).getOrElse(Seq .empty)
78+ if (children.nonEmpty) {
79+ val innerQueries = children.map(buildNestedQuery)
80+ val combinedQuery = if (innerQueries.size == 1 ) {
81+ innerQueries.head
82+ } else {
83+ must(innerQueries)
84+ }
85+ nestedQuery(
86+ n.path,
87+ combinedQuery
88+ ) /* .scoreMode(ScoreMode.None)*/
89+ .inner(
90+ innerHits(n.innerHitsName)
91+ .from(0 )
92+ .size(n.size.getOrElse(3 ))
93+ .fetchSource(
94+ FetchSourceContext (fetchSource = true , includes = n.sources.toArray)
95+ )
96+ )
97+ } else {
98+ nestedQuery(
99+ n.path,
100+ q
101+ ) /* .scoreMode(ScoreMode.None)*/
102+ .inner(
103+ innerHits(n.innerHitsName)
104+ .from(0 )
105+ .size(n.size.getOrElse(3 ))
106+ .fetchSource(
107+ FetchSourceContext (fetchSource = true , includes = n.sources.toArray)
108+ )
109+ )
110+ }
111+ }
112+ if (nestedParents.nonEmpty)
113+ buildNestedQuery(nestedParents.head)
114+ else
115+ buildNestedQuery(nestedElements.last)
51116 }
52117 case child : ElasticChild =>
53118 import child ._
0 commit comments