13
13
* permissions and limitations under the License.
14
14
*/
15
15
16
- package com .amazon .opendistroforelasticsearch .sql .intgtest ;
16
+ package com .amazon .opendistroforelasticsearch .sql .esintgtest ;
17
17
18
- import com .amazon .opendistroforelasticsearch .sql .exception .SqlParseException ;
19
- import com .amazon .opendistroforelasticsearch .sql .plugin .SearchDao ;
20
- import com .amazon .opendistroforelasticsearch .sql .query .SqlElasticRequestBuilder ;
18
+ import com .amazon .opendistroforelasticsearch .sql .intgtest .TestsConstants ;
21
19
import org .elasticsearch .action .search .SearchResponse ;
20
+ import org .elasticsearch .common .xcontent .LoggingDeprecationHandler ;
21
+ import org .elasticsearch .common .xcontent .NamedXContentRegistry ;
22
+ import org .elasticsearch .common .xcontent .XContentFactory ;
23
+ import org .elasticsearch .common .xcontent .XContentParser ;
24
+ import org .elasticsearch .common .xcontent .XContentType ;
22
25
import org .elasticsearch .search .SearchHit ;
23
- import org .elasticsearch .search .aggregations .Aggregation ;
24
- import org .elasticsearch .search .aggregations .Aggregations ;
25
- import org .elasticsearch .search .aggregations .bucket .nested .InternalNested ;
26
- import org .elasticsearch .search .aggregations .bucket .terms .Terms ;
27
- import org .elasticsearch .search .aggregations .metrics .Avg ;
28
- import org .elasticsearch .search .aggregations .metrics .Sum ;
29
- import org .elasticsearch .search .aggregations .metrics .ValueCount ;
30
26
import org .hamcrest .BaseMatcher ;
31
27
import org .hamcrest .Description ;
32
28
import org .hamcrest .FeatureMatcher ;
33
29
import org .hamcrest .Matcher ;
30
+ import org .json .JSONArray ;
31
+ import org .json .JSONObject ;
32
+ import org .junit .Assert ;
34
33
import org .junit .Test ;
35
34
36
- import java .sql . SQLFeatureNotSupportedException ;
35
+ import java .io . IOException ;
37
36
import java .util .ArrayList ;
38
37
import java .util .function .Function ;
39
38
40
- import static org .hamcrest .MatcherAssert .assertThat ;
41
39
import static org .hamcrest .Matchers .allOf ;
42
40
import static org .hamcrest .Matchers .arrayContainingInAnyOrder ;
43
41
import static org .hamcrest .Matchers .closeTo ;
44
- import static org .hamcrest .Matchers .containsInAnyOrder ;
42
+ import static org .hamcrest .Matchers .equalTo ;
45
43
import static org .hamcrest .Matchers .is ;
46
44
47
45
/**
62
60
* 5) HAVING
63
61
* 6) Verification for conditions mixed with regular and nested fields
64
62
*/
65
- public class NestedFieldQueryTest {
63
+ public class NestedFieldQueryIT extends SQLIntegTestCase {
66
64
67
65
private static final String FROM = "FROM " + TestsConstants .TEST_INDEX_NESTED_TYPE + "/nestedType n, n.message m" ;
68
66
67
+ @ Override
68
+ protected void init () throws Exception {
69
+ loadIndex (Index .NESTED );
70
+ }
71
+
69
72
@ Test
70
- public void selectAll () {
73
+ public void selectAll () throws IOException {
71
74
queryAll ("SELECT *" );
72
75
}
73
76
74
77
@ Test
75
- public void noCondition () {
78
+ public void noCondition () throws IOException {
76
79
queryAll ("SELECT myNum, someField, m.author, m.info" );
77
80
}
78
81
79
- private void queryAll (String sql ) {
82
+ private void queryAll (String sql ) throws IOException {
80
83
assertThat (
81
84
query (sql ),
82
85
hits (
@@ -139,7 +142,7 @@ private void queryAll(String sql) {
139
142
}
140
143
141
144
@ Test
142
- public void singleCondition () {
145
+ public void singleCondition () throws IOException {
143
146
assertThat (
144
147
query (
145
148
"SELECT myNum, m.author, m.info" ,
@@ -169,7 +172,7 @@ public void singleCondition() {
169
172
}
170
173
171
174
@ Test
172
- public void multipleConditionsOfNestedField () {
175
+ public void multipleConditionsOfNestedField () throws IOException {
173
176
assertThat (
174
177
query (
175
178
"SELECT someField, m.author, m.info" ,
@@ -190,7 +193,7 @@ public void multipleConditionsOfNestedField() {
190
193
}
191
194
192
195
@ Test
193
- public void multipleConditionsOfNestedFieldNoMatch () {
196
+ public void multipleConditionsOfNestedFieldNoMatch () throws IOException {
194
197
assertThat (
195
198
query (
196
199
"SELECT someField, m.author, m.info" ,
@@ -201,7 +204,7 @@ public void multipleConditionsOfNestedFieldNoMatch() {
201
204
}
202
205
203
206
@ Test
204
- public void multipleConditionsOfRegularAndNestedField () {
207
+ public void multipleConditionsOfRegularAndNestedField () throws IOException {
205
208
assertThat (
206
209
query (
207
210
"SELECT myNum, m.author, m.info" ,
@@ -222,7 +225,7 @@ public void multipleConditionsOfRegularAndNestedField() {
222
225
}
223
226
224
227
@ Test
225
- public void multipleConditionsOfRegularOrNestedField () {
228
+ public void multipleConditionsOfRegularOrNestedField () throws IOException {
226
229
assertThat (
227
230
query (
228
231
"SELECT myNum, m.author, m.info" ,
@@ -255,46 +258,54 @@ public void multipleConditionsOfRegularOrNestedField() {
255
258
}
256
259
257
260
@ Test
258
- public void aggregationWithoutGroupBy () {
259
- SearchResponse resp = query ("SELECT AVG(m.dayOfWeek) AS avgDay" );
260
- Avg avgDay = getNestedAgg (resp , "message.dayOfWeek" , "avgDay" );
261
- assertThat (avgDay .getValue (), isCloseTo (3.166666666 ));
261
+ public void aggregationWithoutGroupBy () throws IOException {
262
+ String sql = "SELECT AVG(m.dayOfWeek) AS avgDay " + FROM ;
263
+
264
+ JSONObject result = executeQuery (sql );
265
+ JSONObject aggregation = getAggregation (result , "message.dayOfWeek@NESTED" );
266
+
267
+ Assert .assertThat ((Double ) aggregation .query ("/avgDay/value" ), closeTo (3.166666666 , 0.01 ));
262
268
}
263
269
264
270
@ Test
265
- public void groupByNestedFieldAndCount () {
266
- SearchResponse resp = query (
267
- "SELECT m.info, COUNT(*)" , "GROUP BY m.info"
268
- );
269
- assertThat (
270
- getNestedAgg (resp , "message.info" , "message.info" ),
271
- buckets (
272
- bucket ("a" , count (equalTo (2 ))),
273
- bucket ("c" , count (equalTo (2 ))),
274
- bucket ("b" , count (equalTo (1 ))),
275
- bucket ("zz" , count (equalTo (1 )))
276
- )
277
- );
271
+ public void groupByNestedFieldAndCount () throws IOException {
272
+ final String sql = "SELECT m.info, COUNT(*) " + FROM + " GROUP BY m.info" ;
273
+
274
+ JSONObject result = executeQuery (sql );
275
+ JSONObject aggregation = getAggregation (result , "message.info@NESTED" );
276
+ JSONArray msgInfoBuckets = (JSONArray )aggregation .optQuery ("/message.info/buckets" );
277
+
278
+ Assert .assertNotNull (msgInfoBuckets );
279
+ Assert .assertThat (msgInfoBuckets .length (), equalTo (4 ));
280
+ Assert .assertThat (msgInfoBuckets .query ("/0/key" ), equalTo ("a" ));
281
+ Assert .assertThat (msgInfoBuckets .query ("/0/COUNT(*)/value" ), equalTo (2 ));
282
+ Assert .assertThat (msgInfoBuckets .query ("/1/key" ), equalTo ("c" ));
283
+ Assert .assertThat (msgInfoBuckets .query ("/1/COUNT(*)/value" ), equalTo (2 ));
284
+ Assert .assertThat (msgInfoBuckets .query ("/2/key" ), equalTo ("b" ));
285
+ Assert .assertThat (msgInfoBuckets .query ("/2/COUNT(*)/value" ), equalTo (1 ));
286
+ Assert .assertThat (msgInfoBuckets .query ("/3/key" ), equalTo ("zz" ));
287
+ Assert .assertThat (msgInfoBuckets .query ("/3/COUNT(*)/value" ), equalTo (1 ));
278
288
}
279
289
280
290
@ Test
281
- public void groupByRegularFieldAndSum () {
282
- SearchResponse resp = query (
283
- "SELECT *, SUM(m.dayOfWeek) AS sumDay" ,
284
- "GROUP BY someField"
285
- );
286
- assertThat (
287
- getAgg (resp , "someField" ),
288
- buckets (
289
- bucket ("a" , sum ("message.dayOfWeek" , "sumDay" , isCloseTo (9.0 ))),
290
- bucket ("b" , sum ("message.dayOfWeek" , "sumDay" , isCloseTo (10.0 )))
291
- )
292
- );
291
+ public void groupByRegularFieldAndSum () throws IOException {
292
+ final String sql = "SELECT *, SUM(m.dayOfWeek) AS sumDay " + FROM + " GROUP BY someField" ;
293
+
294
+ JSONObject result = executeQuery (sql );
295
+ JSONObject aggregation = getAggregation (result , "someField" );
296
+ JSONArray msgInfoBuckets = (JSONArray )aggregation .optQuery ("/buckets" );
297
+
298
+ Assert .assertNotNull (msgInfoBuckets );
299
+ Assert .assertThat (msgInfoBuckets .length (), equalTo (2 ));
300
+ Assert .assertThat (msgInfoBuckets .query ("/0/key" ), equalTo ("a" ));
301
+ Assert .assertThat ((Double ) msgInfoBuckets .query ("/0/message.dayOfWeek@NESTED/sumDay/value" ), closeTo (9.0 , 0.01 ));
302
+ Assert .assertThat (msgInfoBuckets .query ("/1/key" ), equalTo ("b" ));
303
+ Assert .assertThat ((Double ) msgInfoBuckets .query ("/1/message.dayOfWeek@NESTED/sumDay/value" ), closeTo (10.0 , 0.01 ));
293
304
}
294
305
295
306
// Doesn't support: aggregate function other than COUNT()
296
307
@ SuppressWarnings ("unused" )
297
- public void groupByNestedFieldAndAvg () {
308
+ public void groupByNestedFieldAndAvg () throws IOException {
298
309
query (
299
310
"SELECT m.info, AVG(m.dayOfWeek)" ,
300
311
"GROUP BY m.info"
@@ -306,33 +317,31 @@ public void groupByNestedFieldAndAvg() {
306
317
}
307
318
308
319
@ Test
309
- public void groupByNestedAndRegularField () {
310
- SearchResponse resp = query (
311
- "SELECT someField, m.info, COUNT(*)" ,
312
- "GROUP BY someField, m.info"
313
- );
314
- Terms agg = getAgg (resp , "someField" );
315
- assertThat (
316
- getNestedAgg (agg .getBucketByKey ("a" ).getAggregations (), "message.info" , "message.info" ),
317
- buckets (
318
- bucket ("b" , count (equalTo (1 ))),
319
- bucket ("c" , count (equalTo (1 ))),
320
- bucket ("zz" , count (equalTo (1 )))
321
- )
322
- );
323
- assertThat (
324
- getNestedAgg (agg .getBucketByKey ("b" ).getAggregations (), "message.info" , "message.info" ),
325
- buckets (
326
- bucket ("a" , count (equalTo (2 ))),
327
- bucket ("c" , count (equalTo (1 )))
328
- )
329
- );
320
+ public void groupByNestedAndRegularField () throws IOException {
321
+ final String sql = "SELECT someField, m.info, COUNT(*) " + FROM + " GROUP BY someField, m.info" ;
322
+
323
+ JSONObject result = executeQuery (sql );
324
+ JSONObject aggregation = getAggregation (result , "someField" );
325
+ JSONArray msgInfoBuckets = (JSONArray )aggregation .optQuery ("/buckets" );
326
+
327
+ Assert .assertNotNull (msgInfoBuckets );
328
+ Assert .assertThat (msgInfoBuckets .length (), equalTo (2 ));
329
+ Assert .assertThat (msgInfoBuckets .query ("/0/key" ), equalTo ("a" ));
330
+ Assert .assertThat (msgInfoBuckets .query ("/1/key" ), equalTo ("b" ));
330
331
331
- //doesn't support: group by nested field first
332
- /*query(
333
- "SELECT *, SUM(m.dayOfWeek)",
334
- "GROUP BY m.author, someField"
335
- );*/
332
+ JSONArray innerBuckets = (JSONArray )msgInfoBuckets .optQuery ("/0/message.info@NESTED/message.info/buckets" );
333
+ Assert .assertThat (innerBuckets .query ("/0/key" ), equalTo ("b" ));
334
+ Assert .assertThat (innerBuckets .query ("/0/COUNT(*)/value" ), equalTo (1 ));
335
+ Assert .assertThat (innerBuckets .query ("/1/key" ), equalTo ("c" ));
336
+ Assert .assertThat (innerBuckets .query ("/1/COUNT(*)/value" ), equalTo (1 ));
337
+ Assert .assertThat (innerBuckets .query ("/2/key" ), equalTo ("zz" ));
338
+ Assert .assertThat (innerBuckets .query ("/2/COUNT(*)/value" ), equalTo (1 ));
339
+
340
+ innerBuckets = (JSONArray )msgInfoBuckets .optQuery ("/1/message.info@NESTED/message.info/buckets" );
341
+ Assert .assertThat (innerBuckets .query ("/0/key" ), equalTo ("a" ));
342
+ Assert .assertThat (innerBuckets .query ("/0/COUNT(*)/value" ), equalTo (2 ));
343
+ Assert .assertThat (innerBuckets .query ("/1/key" ), equalTo ("c" ));
344
+ Assert .assertThat (innerBuckets .query ("/1/COUNT(*)/value" ), equalTo (1 ));
336
345
}
337
346
338
347
@@ -414,50 +423,6 @@ private final Matcher<SearchHit> innerHits(String path, Matcher<SearchHit>... in
414
423
Matchers for Aggregation Testing
415
424
***********************************************************/
416
425
417
- private <T extends Aggregation > T getAgg (SearchResponse resp ,
418
- String fieldName ) {
419
- return resp .getAggregations ().get (fieldName );
420
- }
421
-
422
- private <T extends Aggregation > T getNestedAgg (SearchResponse resp ,
423
- String nestedFieldName ,
424
- String aggAlias ) {
425
- return getNestedAgg (resp .getAggregations (), nestedFieldName , aggAlias );
426
- }
427
-
428
- private <T extends Aggregation > T getNestedAgg (Aggregations aggs ,
429
- String nestedFieldName ,
430
- String aggAlias ) {
431
- return aggs .<InternalNested >get (nestedFieldName + "@NESTED" ).
432
- getAggregations ().
433
- get (aggAlias );
434
- }
435
-
436
- @ SafeVarargs
437
- private final Matcher <Terms > buckets (Matcher <Terms .Bucket >... subMatchers ) {
438
- return featureValueOf ("buckets" , containsInAnyOrder (subMatchers ), Terms ::getBuckets );
439
- }
440
-
441
- private Matcher <Terms .Bucket > bucket (String key , Matcher <Aggregations > valMatcher ) {
442
- return featureValueOf (key , valMatcher , Terms .Bucket ::getAggregations );
443
- }
444
-
445
- private Matcher <Aggregations > count (Matcher <Long > subMatcher ) {
446
- return featureValueOf ("COUNT(*)" , subMatcher , aggs -> ((ValueCount ) aggs .get ("COUNT(*)" )).getValue ());
447
- }
448
-
449
- private Matcher <Aggregations > sum (String nestedFieldName , String name , Matcher <Double > subMatcher ) {
450
- return featureValueOf (name , subMatcher , aggs -> ((Sum ) getNestedAgg (aggs , nestedFieldName , name )).getValue ());
451
- }
452
-
453
- private Matcher <Double > isCloseTo (double expected ) {
454
- return closeTo (expected , 0.01 );
455
- }
456
-
457
- private Matcher <Long > equalTo (int expected ) {
458
- return is ((long ) expected );
459
- }
460
-
461
426
private <T , U > FeatureMatcher <T , U > featureValueOf (String name , Matcher <U > subMatcher , Function <T , U > getter ) {
462
427
return new FeatureMatcher <T , U >(subMatcher , name , name ) {
463
428
@ Override
@@ -471,19 +436,28 @@ protected U featureValueOf(T actual) {
471
436
Query Utility to Fetch Response for SQL
472
437
***********************************************************/
473
438
474
- private SearchResponse query (String select , String ... statements ) {
439
+ private SearchResponse query (String select , String ... statements ) throws IOException {
475
440
return execute (select + " " + FROM + " " + String .join (" " , statements ));
476
441
}
477
442
478
- private SearchResponse execute (String sql ) {
479
- SearchDao searchDao = MainTestSuite .getSearchDao ();
480
- try {
481
- SqlElasticRequestBuilder result = searchDao .explain (sql ).explain ();
482
- return (SearchResponse ) result .get ();
483
- }
484
- catch (SqlParseException | SQLFeatureNotSupportedException e ) {
485
- throw new IllegalStateException ("Query failed: " + sql , e );
486
- }
443
+ private SearchResponse execute (String sql ) throws IOException {
444
+ final JSONObject jsonObject = executeQuery (sql );
445
+
446
+ final XContentParser parser = XContentFactory .xContent (XContentType .JSON ).createParser (
447
+ NamedXContentRegistry .EMPTY ,
448
+ LoggingDeprecationHandler .INSTANCE ,
449
+ jsonObject .toString ());
450
+ return SearchResponse .fromXContent (parser );
451
+ }
452
+
453
+ private JSONObject getAggregation (final JSONObject queryResult , final String aggregationName )
454
+ {
455
+ final String aggregationsObjName = "aggregations" ;
456
+ Assert .assertTrue (queryResult .has (aggregationsObjName ));
457
+
458
+ final JSONObject aggregations = queryResult .getJSONObject (aggregationsObjName );
459
+ Assert .assertTrue (aggregations .has (aggregationName ));
460
+ return aggregations .getJSONObject (aggregationName );
487
461
}
488
462
489
463
}
0 commit comments