1616package  org .eclipse .jnosql .databases .elasticsearch .communication ;
1717
1818
19+ import  co .elastic .clients .elasticsearch .ElasticsearchClient ;
20+ import  co .elastic .clients .elasticsearch ._types .mapping .Property ;
1921import  co .elastic .clients .elasticsearch ._types .query_dsl .BoolQuery ;
22+ import  co .elastic .clients .elasticsearch ._types .query_dsl .MatchQuery ;
2023import  co .elastic .clients .elasticsearch ._types .query_dsl .Query ;
2124import  co .elastic .clients .elasticsearch ._types .query_dsl .QueryStringQuery ;
2225import  co .elastic .clients .elasticsearch ._types .query_dsl .RangeQuery ;
2326import  co .elastic .clients .elasticsearch ._types .query_dsl .TermQuery ;
27+ import  co .elastic .clients .elasticsearch .indices .get_mapping .IndexMappingRecord ;
2428import  co .elastic .clients .json .JsonData ;
2529import  org .eclipse .jnosql .communication .Condition ;
2630import  org .eclipse .jnosql .communication .TypeReference ;
2933import  org .eclipse .jnosql .communication .document .DocumentQuery ;
3034import  org .eclipse .jnosql .communication .driver .ValueUtil ;
3135
32- import  java .util . ArrayList ;
36+ import  java .io . IOException ;
3337import  java .util .EnumSet ;
3438import  java .util .List ;
39+ import  java .util .Map ;
3540import  java .util .Objects ;
3641import  java .util .Optional ;
3742import  java .util .Set ;
3843import  java .util .stream .Stream ;
3944
40- import  static  org .eclipse .jnosql .communication .Condition .EQUALS ;
4145import  static  org .eclipse .jnosql .communication .Condition .IN ;
4246
4347final  class  QueryConverter  {
@@ -47,17 +51,25 @@ final class QueryConverter {
4751    private  QueryConverter () {
4852    }
4953
50-     static  QueryConverterResult  select (DocumentQuery  query ) {
51-         List <String > ids  = new  ArrayList <>();
54+     static  QueryConverterResult  select (ElasticsearchClient  client , String  database , DocumentQuery  query ) {
55+ 
56+         var  indexMappingRecord  = getIndexMappingRecord (client , database , query );
5257
5358        Query .Builder  nameCondition  = Optional .of (query .name ())
54-                 .map (collection  -> new  Query .Builder ().term (q  -> q 
55-                         .field (EntityConverter .ENTITY ).value (collection )))
59+                 .map (collection  -> {
60+                     if  (supportTermQuery (indexMappingRecord , EntityConverter .ENTITY )) {
61+                         return  new  Query .Builder ().term (q  -> q 
62+                                 .field (EntityConverter .ENTITY ).value (collection ));
63+                     }
64+                     return  new  Query .Builder ().match (q  -> q 
65+                             .field (EntityConverter .ENTITY ).query (collection ));
66+ 
67+                 })
5668                .map (Query .Builder .class ::cast )
5769                .orElse (null );
5870
5971        Query .Builder  queryConditions  = query .condition ()
60-                 .map (c  -> getCondition (c ,  ids ))
72+                 .map (c  -> getCondition (indexMappingRecord ,  c ))
6173                .orElse (null );
6274
6375
@@ -67,31 +79,55 @@ static QueryConverterResult select(DocumentQuery query) {
6779                        .must (c1 .build (), c2 .build ()))))
6880                .orElse (null );
6981
70-         return  new  QueryConverterResult (builder ,  ids );
82+         return  new  QueryConverterResult (builder );
7183
7284    }
7385
86+     public  static  boolean  supportTermQuery (IndexMappingRecord  indexMappingRecord , String  attribute ) {
87+         return  supportTermQuery (indexMappingRecord .mappings ().properties (), attribute );
88+     }
7489
75-     private  static  Query .Builder  getCondition (DocumentCondition  condition , List <String > ids ) {
76-         Document  document  = condition .document ();
77- 
78-         if  (!NOT_APPENDABLE .contains (condition .condition ()) && isIdField (document )) {
79-             if  (IN .equals (condition .condition ())) {
80-                 ids .addAll (document .get (new  TypeReference <List <String >>() {
81-                 }));
82-             } else  if  (EQUALS .equals (condition .condition ())) {
83-                 ids .add (document .get (String .class ));
90+     public  static  boolean  supportTermQuery (Map <String , Property > properties , String  attribute ) {
91+         String  attributeName  = attribute ;
92+         if  (attributeName .contains ("." )) {
93+             attributeName  = attribute .substring (0 , attribute .indexOf ("." ));
94+             Property  property  = properties .get (attributeName );
95+             if  (Objects .nonNull (property ) && property .isObject ()) {
96+                 return  supportTermQuery (property .object ().properties (),
97+                         attribute .substring (attribute .indexOf ("." ) + 1 ));
8498            }
99+             return  false ;
100+         }
101+         Property  property  = properties .get (attributeName );
102+         return  Objects .nonNull (property ) && property .isKeyword ();
103+     }
85104
86-             return  null ;
105+     private  static  IndexMappingRecord  getIndexMappingRecord (ElasticsearchClient  client , String  database , DocumentQuery  query ) {
106+         try  {
107+             return  client .indices ().getMapping (q  -> q .index (database ))
108+                     .get (database );
109+         } catch  (IOException  e ) {
110+             throw  new  IllegalStateException ("cannot retrieve the index's mapping: %s" .formatted (e .getMessage ()), e );
87111        }
112+     }
113+ 
114+ 
115+     private  static  Query .Builder  getCondition (IndexMappingRecord  indexMappingRecord , DocumentCondition  condition ) {
116+         Document  document  = condition .document ();
88117
89118        switch  (condition .condition ()) {
90119            case  EQUALS :
120+                 if  (supportTermQuery (indexMappingRecord , document .name ())) {
121+                     return  (Query .Builder ) new  Query .Builder ()
122+                             .term (TermQuery .of (tq  -> tq 
123+                                     .field (document .name ())
124+                                     .value (v  -> v 
125+                                             .anyValue (JsonData .of (document .value ().get ())))));
126+                 }
91127                return  (Query .Builder ) new  Query .Builder ()
92-                         .term ( TermQuery .of (tq  -> tq 
128+                         .match ( MatchQuery .of (tq  -> tq 
93129                                .field (document .name ())
94-                                 .value (v  -> v 
130+                                 .query (v  -> v 
95131                                        .anyValue (JsonData .of (document .value ().get ())))));
96132            case  LESSER_THAN :
97133                return  (Query .Builder ) new  Query .Builder ()
@@ -122,10 +158,18 @@ private static Query.Builder getCondition(DocumentCondition condition, List<Stri
122158            case  IN :
123159                return  (Query .Builder ) ValueUtil .convertToList (document .value ())
124160                        .stream ()
125-                         .map (val  -> new  Query .Builder ()
126-                                 .term (TermQuery .of (tq  -> tq 
127-                                         .field (document .name ())
128-                                         .value (v  -> v .anyValue (JsonData .of (val ))))))
161+                         .map (val  -> {
162+                             if  (supportTermQuery (indexMappingRecord , document .name ())) {
163+                                 return  new  Query .Builder ()
164+                                         .term (TermQuery .of (tq  -> tq 
165+                                                 .field (document .name ())
166+                                                 .value (v  -> v .anyValue (JsonData .of (val )))));
167+                             }
168+                             return  new  Query .Builder ()
169+                                     .match (MatchQuery .of (tq  -> tq 
170+                                             .field (document .name ())
171+                                             .query (v  -> v .anyValue (JsonData .of (val )))));
172+                         })
129173                        .reduce ((d1 , d2 ) -> new  Query .Builder ()
130174                                .bool (BoolQuery .of (bq  -> bq 
131175                                        .should (List .of (d1 .build (), d2 .build ())))))
@@ -134,7 +178,7 @@ private static Query.Builder getCondition(DocumentCondition condition, List<Stri
134178                return  document .get (new  TypeReference <List <DocumentCondition >>() {
135179                        })
136180                        .stream ()
137-                         .map (d  -> getCondition (d ,  ids ))
181+                         .map (d  -> getCondition (indexMappingRecord ,  d ))
138182                        .filter (Objects ::nonNull )
139183                        .reduce ((d1 , d2 ) -> (Query .Builder ) new  Query .Builder ()
140184                                .bool (BoolQuery .of (bq  -> bq 
@@ -145,15 +189,15 @@ private static Query.Builder getCondition(DocumentCondition condition, List<Stri
145189                return  document .get (new  TypeReference <List <DocumentCondition >>() {
146190                        })
147191                        .stream ()
148-                         .map (d  -> getCondition (d ,  ids ))
192+                         .map (d  -> getCondition (indexMappingRecord ,  d ))
149193                        .filter (Objects ::nonNull )
150194                        .reduce ((d1 , d2 ) -> (Query .Builder ) new  Query .Builder ()
151195                                .bool (BoolQuery .of (bq  -> bq 
152196                                        .should (List .of (d1 .build (), d2 .build ())))))
153197                        .orElseThrow (() -> new  IllegalStateException ("An and condition cannot be empty" ));
154198            case  NOT :
155199                DocumentCondition  dc  = document .get (DocumentCondition .class );
156-                 Query .Builder  queryBuilder  = Optional .ofNullable (getCondition (dc ,  ids ))
200+                 Query .Builder  queryBuilder  = Optional .ofNullable (getCondition (indexMappingRecord ,  dc ))
157201                        .orElseThrow (() -> new  IllegalStateException ("An and condition cannot be empty" ));
158202                return  (Query .Builder ) new  Query .Builder ()
159203                        .bool (BoolQuery .of (bq  -> bq 
0 commit comments