Skip to content

Commit bf03510

Browse files
authored
feat: add supports for aggregation filter expression for new query api (#95)
* adds integration test and fixed unit tests * reverted the accidental change * Fixed few comments * removes the usage of data accessor from filter clause * removes commented code * fixed the string cases after removal of data accessor pattern * addressed comments * added test for covering where and aggregation filter
1 parent 6cb9138 commit bf03510

File tree

11 files changed

+611
-86
lines changed

11 files changed

+611
-86
lines changed

document-store/src/integrationTest/java/org/hypertrace/core/documentstore/DocStoreTest.java

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1513,7 +1513,30 @@ public void testSearchIteratorInterface(String dataStoreName) throws IOException
15131513

15141514
@ParameterizedTest
15151515
@MethodSource("databaseContextProvider")
1516-
public void testNewAggregateApiWhereClause(String dataStoreName) throws IOException {
1516+
public void testQueryV1ForSimpleWhereClause(String dataStoreName) throws IOException {
1517+
Map<Key, Document> documents = createDocumentsFromResource("mongo/collection_data.json");
1518+
Datastore datastore = datastoreMap.get(dataStoreName);
1519+
Collection collection = datastore.getCollection(COLLECTION_NAME);
1520+
1521+
// add docs
1522+
boolean result = collection.bulkUpsert(documents);
1523+
Assertions.assertTrue(result);
1524+
1525+
// query docs
1526+
org.hypertrace.core.documentstore.query.Query query =
1527+
org.hypertrace.core.documentstore.query.Query.builder()
1528+
.setFilter(
1529+
RelationalExpression.of(
1530+
IdentifierExpression.of("quantity"), NEQ, ConstantExpression.of(10)))
1531+
.build();
1532+
1533+
Iterator<Document> iterator = collection.aggregate(query);
1534+
assertSizeAndDocsEqual(dataStoreName, iterator, 6, "mongo/simple_filter_quantity_neq_10.json");
1535+
}
1536+
1537+
@ParameterizedTest
1538+
@MethodSource("databaseContextProvider")
1539+
public void testQueryV1FilterWithNestedFiled(String dataStoreName) throws IOException {
15171540
Map<Key, Document> documents = createDocumentsFromResource("mongo/collection_data.json");
15181541
Datastore datastore = datastoreMap.get(dataStoreName);
15191542
Collection collection = datastore.getCollection(COLLECTION_NAME);
@@ -1687,6 +1710,102 @@ public void testQueryV1AggregationExpression(String dataStoreName) throws IOExce
16871710
dataStoreName, resultDocs, 3, "mongo/test_aggregation_expression_result.json");
16881711
}
16891712

1713+
@ParameterizedTest
1714+
@MethodSource("databaseContextProvider")
1715+
public void testQueryV1AggregationFilter(String dataStoreName) throws IOException {
1716+
Map<Key, Document> documents = createDocumentsFromResource("mongo/collection_data.json");
1717+
Datastore datastore = datastoreMap.get(dataStoreName);
1718+
Collection collection = datastore.getCollection(COLLECTION_NAME);
1719+
1720+
// add docs
1721+
boolean result = collection.bulkUpsert(documents);
1722+
Assertions.assertTrue(result);
1723+
1724+
org.hypertrace.core.documentstore.query.Query query =
1725+
org.hypertrace.core.documentstore.query.Query.builder()
1726+
.addSelection(
1727+
AggregateExpression.of(DISTINCT_COUNT, IdentifierExpression.of("quantity")),
1728+
"qty_count")
1729+
.addSelection(IdentifierExpression.of("item"))
1730+
.addAggregation(IdentifierExpression.of("item"))
1731+
.setAggregationFilter(
1732+
RelationalExpression.of(
1733+
IdentifierExpression.of("qty_count"), LTE, ConstantExpression.of(10)))
1734+
.build();
1735+
1736+
Iterator<Document> resultDocs = collection.aggregate(query);
1737+
assertSizeAndDocsEqual(dataStoreName, resultDocs, 4, "mongo/distinct_count_response.json");
1738+
}
1739+
1740+
@ParameterizedTest
1741+
@MethodSource("databaseContextProvider")
1742+
public void testQueryV1AggregationFilterWithWhereClause(String dataStoreName) throws IOException {
1743+
Map<Key, Document> documents = createDocumentsFromResource("mongo/collection_data.json");
1744+
Datastore datastore = datastoreMap.get(dataStoreName);
1745+
Collection collection = datastore.getCollection(COLLECTION_NAME);
1746+
1747+
// add docs
1748+
boolean result = collection.bulkUpsert(documents);
1749+
Assertions.assertTrue(result);
1750+
1751+
org.hypertrace.core.documentstore.query.Query query =
1752+
org.hypertrace.core.documentstore.query.Query.builder()
1753+
.addSelection(
1754+
AggregateExpression.of(DISTINCT_COUNT, IdentifierExpression.of("quantity")),
1755+
"qty_count")
1756+
.addSelection(IdentifierExpression.of("item"))
1757+
.addAggregation(IdentifierExpression.of("item"))
1758+
.setFilter(
1759+
RelationalExpression.of(
1760+
IdentifierExpression.of("price"), LTE, ConstantExpression.of(7.5)))
1761+
.setAggregationFilter(
1762+
RelationalExpression.of(
1763+
IdentifierExpression.of("qty_count"), LTE, ConstantExpression.of(10)))
1764+
.build();
1765+
1766+
Iterator<Document> resultDocs = collection.aggregate(query);
1767+
assertSizeAndDocsEqual(
1768+
dataStoreName, resultDocs, 2, "mongo/test_aggr_filter_and_where_filter_result.json");
1769+
}
1770+
1771+
@ParameterizedTest
1772+
@MethodSource("databaseContextProvider")
1773+
public void testQueryQ1AggregationFilterAlongWithNonAliasFields(String dataStoreName)
1774+
throws IOException {
1775+
Map<Key, Document> documents = createDocumentsFromResource("mongo/collection_data.json");
1776+
Datastore datastore = datastoreMap.get(dataStoreName);
1777+
Collection collection = datastore.getCollection(COLLECTION_NAME);
1778+
1779+
// add docs
1780+
boolean result = collection.bulkUpsert(documents);
1781+
Assertions.assertTrue(result);
1782+
1783+
org.hypertrace.core.documentstore.query.Query query =
1784+
org.hypertrace.core.documentstore.query.Query.builder()
1785+
.addSelection(
1786+
AggregateExpression.of(DISTINCT_COUNT, IdentifierExpression.of("quantity")),
1787+
"qty_count")
1788+
.addSelection(IdentifierExpression.of("item"))
1789+
.addSelection(IdentifierExpression.of("price"))
1790+
.addAggregation(IdentifierExpression.of("item"))
1791+
.addAggregation(IdentifierExpression.of("price"))
1792+
.setAggregationFilter(
1793+
LogicalExpression.builder()
1794+
.operator(AND)
1795+
.operand(
1796+
RelationalExpression.of(
1797+
IdentifierExpression.of("qty_count"), LTE, ConstantExpression.of(10)))
1798+
.operand(
1799+
RelationalExpression.of(
1800+
IdentifierExpression.of("price"), GT, ConstantExpression.of(5)))
1801+
.build())
1802+
.build();
1803+
1804+
Iterator<Document> resultDocs = collection.aggregate(query);
1805+
assertSizeAndDocsEqual(
1806+
dataStoreName, resultDocs, 4, "mongo/test_aggr_alias_distinct_count_response.json");
1807+
}
1808+
16901809
@ParameterizedTest
16911810
@MethodSource("databaseContextProvider")
16921811
public void whenBulkUpdatingNonExistentRecords_thenExpectNothingToBeUpdatedOrCreated(
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[
2+
{
3+
"item":"Soap",
4+
"qty_count":1,
5+
"price":20
6+
},
7+
{
8+
"item":"Mirror",
9+
"qty_count":1,
10+
"price":20
11+
},
12+
{
13+
"item":"Comb",
14+
"qty_count":2,
15+
"price":7.5
16+
},
17+
{
18+
"item":"Soap",
19+
"qty_count":2,
20+
"price":10
21+
}
22+
]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[
2+
{
3+
"item":"Shampoo",
4+
"qty_count":2
5+
},
6+
{
7+
"item":"Comb",
8+
"qty_count":2
9+
}
10+
]
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
[
2+
{
3+
"date":"2014-03-01T08:00:00Z",
4+
"item":"Soap",
5+
"price":10,
6+
"props":{
7+
"size":"M",
8+
"brand":"Dettol",
9+
"seller":{
10+
"name":"Metro Chemicals Pvt. Ltd.",
11+
"address":{
12+
"city":"Mumbai",
13+
"pincode":400004
14+
}
15+
}
16+
},
17+
"sales":[
18+
{
19+
"city":"delhi",
20+
"medium":[
21+
{
22+
"type":"distributionChannel",
23+
"volume":1000
24+
},
25+
{
26+
"type":"retail",
27+
"volume":500
28+
},
29+
{
30+
"type":"online",
31+
"volume":1000
32+
}
33+
]
34+
},
35+
{
36+
"city":"pune",
37+
"medium":[
38+
{
39+
"type":"distributionChannel",
40+
"volume":300
41+
},
42+
{
43+
"type":"online",
44+
"volume":2000
45+
}
46+
]
47+
}
48+
],
49+
"quantity":2
50+
},
51+
{
52+
"date":"2014-03-01T09:00:00Z",
53+
"item":"Mirror",
54+
"price":20,
55+
"sales":[
56+
{
57+
"city":"delhi",
58+
"medium":[
59+
60+
]
61+
}
62+
],
63+
"quantity":1
64+
},
65+
{
66+
"date":"2016-02-06T20:20:13Z",
67+
"item":"Soap",
68+
"price":10,
69+
"quantity":5
70+
},
71+
{
72+
"date":"2014-04-04T11:21:39.736Z",
73+
"item":"Shampoo",
74+
"price":5,
75+
"sales":[
76+
77+
],
78+
"quantity":20
79+
},
80+
{
81+
"date":"2014-04-04T21:23:13.331Z",
82+
"item":"Soap",
83+
"price":20,
84+
"props":{
85+
"size":"S",
86+
"brand":"Lifebuoy",
87+
"seller":{
88+
"name":"Hans and Co.",
89+
"address":{
90+
"city":"Kolkata",
91+
"pincode":700007
92+
}
93+
}
94+
},
95+
"quantity":5
96+
},
97+
{
98+
"date":"2015-06-04T05:08:13Z",
99+
"item":"Comb",
100+
"price":7.5,
101+
"quantity":5
102+
}
103+
]

document-store/src/main/java/org/hypertrace/core/documentstore/postgres/PostgresCollection.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,9 @@ public long count(org.hypertrace.core.documentstore.query.Query query) {
331331
private CloseableIterator<Document> executeQueryV1(
332332
final org.hypertrace.core.documentstore.query.Query query) {
333333
org.hypertrace.core.documentstore.postgres.query.v1.PostgresQueryParser queryParser =
334-
new org.hypertrace.core.documentstore.postgres.query.v1.PostgresQueryParser(collectionName);
335-
String sqlQuery = queryParser.parse(query);
334+
new org.hypertrace.core.documentstore.postgres.query.v1.PostgresQueryParser(
335+
collectionName, query);
336+
String sqlQuery = queryParser.parse();
336337
try {
337338
PreparedStatement preparedStatement =
338339
buildPreparedStatement(sqlQuery, queryParser.getParamsBuilder().build());

0 commit comments

Comments
 (0)