Skip to content

Commit 4df34ac

Browse files
authored
feat: add supports for pagination expression for new api (#98)
* wip * feat: adds support for pagination * Moved test case to DocStoreTest
1 parent 46ebfdc commit 4df34ac

File tree

11 files changed

+275
-234
lines changed

11 files changed

+275
-234
lines changed

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

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
import static org.hypertrace.core.documentstore.expression.operators.RelationalOperator.EQ;
1313
import static org.hypertrace.core.documentstore.expression.operators.RelationalOperator.GT;
1414
import static org.hypertrace.core.documentstore.expression.operators.RelationalOperator.GTE;
15+
import static org.hypertrace.core.documentstore.expression.operators.RelationalOperator.IN;
1516
import static org.hypertrace.core.documentstore.expression.operators.RelationalOperator.LTE;
1617
import static org.hypertrace.core.documentstore.expression.operators.RelationalOperator.NEQ;
18+
import static org.hypertrace.core.documentstore.expression.operators.SortOrder.ASC;
1719
import static org.hypertrace.core.documentstore.expression.operators.SortOrder.DESC;
1820
import static org.hypertrace.core.documentstore.utils.CreateUpdateTestThread.FAILURE;
1921
import static org.hypertrace.core.documentstore.utils.CreateUpdateTestThread.SUCCESS;
@@ -54,6 +56,11 @@
5456
import org.hypertrace.core.documentstore.expression.impl.RelationalExpression;
5557
import org.hypertrace.core.documentstore.mongo.MongoDatastore;
5658
import org.hypertrace.core.documentstore.postgres.PostgresDatastore;
59+
import org.hypertrace.core.documentstore.query.Pagination;
60+
import org.hypertrace.core.documentstore.query.Selection;
61+
import org.hypertrace.core.documentstore.query.SelectionSpec;
62+
import org.hypertrace.core.documentstore.query.Sort;
63+
import org.hypertrace.core.documentstore.query.SortingSpec;
5764
import org.hypertrace.core.documentstore.utils.CreateUpdateTestThread;
5865
import org.hypertrace.core.documentstore.utils.CreateUpdateTestThread.Operation;
5966
import org.hypertrace.core.documentstore.utils.Utils;
@@ -1551,12 +1558,22 @@ public void testQueryV1FilterWithNestedFiled(String dataStoreName) throws IOExce
15511558
org.hypertrace.core.documentstore.query.Query query =
15521559
org.hypertrace.core.documentstore.query.Query.builder()
15531560
.setFilter(
1554-
RelationalExpression.of(
1555-
IdentifierExpression.of("quantity"), NEQ, ConstantExpression.of(10)))
1561+
LogicalExpression.builder()
1562+
.operator(AND)
1563+
.operand(
1564+
RelationalExpression.of(
1565+
IdentifierExpression.of("quantity"), GT, ConstantExpression.of(5)))
1566+
.operand(
1567+
RelationalExpression.of(
1568+
IdentifierExpression.of("props.seller.address.city"),
1569+
EQ,
1570+
ConstantExpression.of("Kolkata")))
1571+
.build())
15561572
.build();
15571573

15581574
Iterator<Document> iterator = collection.aggregate(query);
1559-
assertSizeAndDocsEqual(dataStoreName, iterator, 6, "mongo/simple_filter_quantity_neq_10.json");
1575+
assertSizeAndDocsEqual(
1576+
dataStoreName, iterator, 1, "mongo/test_nest_field_filter_response.json");
15601577
}
15611578

15621579
@ParameterizedTest
@@ -1772,8 +1789,7 @@ public void testQueryV1AggregationFilterWithWhereClause(String dataStoreName) th
17721789

17731790
@ParameterizedTest
17741791
@MethodSource("databaseContextProvider")
1775-
public void testQueryQ1AggregationFilterAlongWithNonAliasFields(String dataStoreName)
1776-
throws IOException {
1792+
public void testQueryV1DistinctCountWithSortingSpecs(String dataStoreName) throws IOException {
17771793
Map<Key, Document> documents = createDocumentsFromResource("mongo/collection_data.json");
17781794
Datastore datastore = datastoreMap.get(dataStoreName);
17791795
Collection collection = datastore.getCollection(COLLECTION_NAME);
@@ -1788,53 +1804,64 @@ public void testQueryQ1AggregationFilterAlongWithNonAliasFields(String dataStore
17881804
AggregateExpression.of(DISTINCT_COUNT, IdentifierExpression.of("quantity")),
17891805
"qty_count")
17901806
.addSelection(IdentifierExpression.of("item"))
1791-
.addSelection(IdentifierExpression.of("price"))
17921807
.addAggregation(IdentifierExpression.of("item"))
1793-
.addAggregation(IdentifierExpression.of("price"))
17941808
.setAggregationFilter(
1795-
LogicalExpression.builder()
1796-
.operator(AND)
1797-
.operand(
1798-
RelationalExpression.of(
1799-
IdentifierExpression.of("qty_count"), LTE, ConstantExpression.of(10)))
1800-
.operand(
1801-
RelationalExpression.of(
1802-
IdentifierExpression.of("price"), GT, ConstantExpression.of(5)))
1803-
.build())
1809+
RelationalExpression.of(
1810+
IdentifierExpression.of("qty_count"), LTE, ConstantExpression.of(1000)))
1811+
.addSort(IdentifierExpression.of("qty_count"), DESC)
1812+
.addSort(IdentifierExpression.of("item"), DESC)
18041813
.build();
18051814

18061815
Iterator<Document> resultDocs = collection.aggregate(query);
1807-
assertSizeAndDocsEqual(
1808-
dataStoreName, resultDocs, 4, "mongo/test_aggr_alias_distinct_count_response.json");
1816+
assertDocsAndSizeEqual(resultDocs, "mongo/distinct_count_response.json", 4);
18091817
}
18101818

18111819
@ParameterizedTest
18121820
@MethodSource("databaseContextProvider")
1813-
public void testQueryV1DistinctCountWithSortingSpecs(String dataStoreName) throws IOException {
1821+
public void testFindWithSortingAndPagination(String datastoreName) throws IOException {
18141822
Map<Key, Document> documents = createDocumentsFromResource("mongo/collection_data.json");
1815-
Datastore datastore = datastoreMap.get(dataStoreName);
1823+
Datastore datastore = datastoreMap.get(datastoreName);
18161824
Collection collection = datastore.getCollection(COLLECTION_NAME);
18171825

18181826
// add docs
18191827
boolean result = collection.bulkUpsert(documents);
18201828
Assertions.assertTrue(result);
1829+
List<SelectionSpec> selectionSpecs =
1830+
List.of(
1831+
SelectionSpec.of(IdentifierExpression.of("item")),
1832+
SelectionSpec.of(IdentifierExpression.of("price")),
1833+
SelectionSpec.of(IdentifierExpression.of("quantity")),
1834+
SelectionSpec.of(IdentifierExpression.of("date")));
1835+
Selection selection = Selection.builder().selectionSpecs(selectionSpecs).build();
1836+
1837+
org.hypertrace.core.documentstore.query.Filter filter =
1838+
org.hypertrace.core.documentstore.query.Filter.builder()
1839+
.expression(
1840+
RelationalExpression.of(
1841+
IdentifierExpression.of("item"),
1842+
IN,
1843+
ConstantExpression.ofStrings(List.of("Mirror", "Comb", "Shampoo", "Bottle"))))
1844+
.build();
1845+
1846+
Sort sort =
1847+
Sort.builder()
1848+
.sortingSpec(SortingSpec.of(IdentifierExpression.of("quantity"), DESC))
1849+
.sortingSpec(SortingSpec.of(IdentifierExpression.of("item"), ASC))
1850+
.build();
1851+
1852+
Pagination pagination = Pagination.builder().offset(1).limit(3).build();
18211853

18221854
org.hypertrace.core.documentstore.query.Query query =
18231855
org.hypertrace.core.documentstore.query.Query.builder()
1824-
.addSelection(
1825-
AggregateExpression.of(DISTINCT_COUNT, IdentifierExpression.of("quantity")),
1826-
"qty_count")
1827-
.addSelection(IdentifierExpression.of("item"))
1828-
.addAggregation(IdentifierExpression.of("item"))
1829-
.setAggregationFilter(
1830-
RelationalExpression.of(
1831-
IdentifierExpression.of("qty_count"), LTE, ConstantExpression.of(1000)))
1832-
.addSort(IdentifierExpression.of("qty_count"), DESC)
1833-
.addSort(IdentifierExpression.of("item"), DESC)
1856+
.setSelection(selection)
1857+
.setFilter(filter)
1858+
.setSort(sort)
1859+
.setPagination(pagination)
18341860
.build();
18351861

1836-
Iterator<Document> resultDocs = collection.aggregate(query);
1837-
assertDocsAndSizeEqual(resultDocs, "mongo/distinct_count_response.json", 4);
1862+
Iterator<Document> resultDocs = collection.find(query);
1863+
Utils.assertDocsAndSizeEqual(
1864+
resultDocs, "mongo/filter_with_sorting_and_pagination_response.json", 3);
18381865
}
18391866

18401867
@ParameterizedTest

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

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static org.hypertrace.core.documentstore.expression.operators.AggregationOperator.COUNT;
44
import static org.hypertrace.core.documentstore.expression.operators.AggregationOperator.DISTINCT;
5+
import static org.hypertrace.core.documentstore.expression.operators.AggregationOperator.DISTINCT_COUNT;
56
import static org.hypertrace.core.documentstore.expression.operators.AggregationOperator.SUM;
67
import static org.hypertrace.core.documentstore.expression.operators.FunctionOperator.LENGTH;
78
import static org.hypertrace.core.documentstore.expression.operators.FunctionOperator.MULTIPLY;
@@ -51,6 +52,7 @@
5152
import org.hypertrace.core.documentstore.query.SelectionSpec;
5253
import org.hypertrace.core.documentstore.query.Sort;
5354
import org.hypertrace.core.documentstore.query.SortingSpec;
55+
import org.hypertrace.core.documentstore.utils.Utils;
5456
import org.junit.jupiter.api.AfterAll;
5557
import org.junit.jupiter.api.BeforeAll;
5658
import org.junit.jupiter.api.Test;
@@ -167,46 +169,6 @@ public void testFindWithDuplicateSelections() throws IOException {
167169
assertSizeEqual(query, "mongo/simple_filter_response.json");
168170
}
169171

170-
@Test
171-
public void testFindWithSortingAndPagination() throws IOException {
172-
List<SelectionSpec> selectionSpecs =
173-
List.of(
174-
SelectionSpec.of(IdentifierExpression.of("item")),
175-
SelectionSpec.of(IdentifierExpression.of("price")),
176-
SelectionSpec.of(IdentifierExpression.of("quantity")),
177-
SelectionSpec.of(IdentifierExpression.of("date")));
178-
Selection selection = Selection.builder().selectionSpecs(selectionSpecs).build();
179-
180-
Filter filter =
181-
Filter.builder()
182-
.expression(
183-
RelationalExpression.of(
184-
IdentifierExpression.of("item"),
185-
IN,
186-
ConstantExpression.ofStrings(List.of("Mirror", "Comb", "Shampoo", "Bottle"))))
187-
.build();
188-
189-
Sort sort =
190-
Sort.builder()
191-
.sortingSpec(SortingSpec.of(IdentifierExpression.of("quantity"), DESC))
192-
.sortingSpec(SortingSpec.of(IdentifierExpression.of("item"), ASC))
193-
.build();
194-
195-
Pagination pagination = Pagination.builder().offset(1).limit(3).build();
196-
197-
Query query =
198-
Query.builder()
199-
.setSelection(selection)
200-
.setFilter(filter)
201-
.setSort(sort)
202-
.setPagination(pagination)
203-
.build();
204-
205-
Iterator<Document> resultDocs = collection.find(query);
206-
assertDocsEqual(resultDocs, "mongo/filter_with_sorting_and_pagination_response.json");
207-
assertSizeEqual(query, "mongo/filter_with_sorting_and_pagination_response.json");
208-
}
209-
210172
@Test
211173
public void testFindWithDuplicateSortingAndPagination() throws IOException {
212174
List<SelectionSpec> selectionSpecs =
@@ -596,6 +558,34 @@ public void testFilterAndUnnest() throws IOException {
596558
assertSizeEqual(query, "mongo/unwind_filter_response.json");
597559
}
598560

561+
@Test
562+
public void testQueryQ1AggregationFilterAlongWithNonAliasFields() throws IOException {
563+
org.hypertrace.core.documentstore.query.Query query =
564+
org.hypertrace.core.documentstore.query.Query.builder()
565+
.addSelection(
566+
AggregateExpression.of(DISTINCT_COUNT, IdentifierExpression.of("quantity")),
567+
"qty_count")
568+
.addSelection(IdentifierExpression.of("item"))
569+
.addSelection(IdentifierExpression.of("price"))
570+
.addAggregation(IdentifierExpression.of("item"))
571+
.addAggregation(IdentifierExpression.of("price"))
572+
.setAggregationFilter(
573+
LogicalExpression.builder()
574+
.operator(AND)
575+
.operand(
576+
RelationalExpression.of(
577+
IdentifierExpression.of("qty_count"), LTE, ConstantExpression.of(10)))
578+
.operand(
579+
RelationalExpression.of(
580+
IdentifierExpression.of("price"), GT, ConstantExpression.of(5)))
581+
.build())
582+
.build();
583+
584+
Iterator<Document> resultDocs = collection.aggregate(query);
585+
Utils.assertDocsAndSizeEqualWithoutOrder(
586+
resultDocs, "mongo/test_aggr_alias_distinct_count_response.json", 4);
587+
}
588+
599589
private static void assertDocsEqual(Iterator<Document> documents, String filePath)
600590
throws IOException {
601591
String fileContent = readFileFromResource(filePath).orElseThrow();

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,23 @@ public static void assertDocsAndSizeEqual(
112112
assertEquals(expected, actual);
113113
assertEquals(expectedSize, actualSize);
114114
}
115+
116+
public static void assertDocsAndSizeEqualWithoutOrder(
117+
Iterator<Document> documents, String filePath, int expectedSize) throws IOException {
118+
String fileContent = readFileFromResource(filePath).orElseThrow();
119+
List<Map<String, Object>> expectedDocs = convertJsonToMap(fileContent);
120+
121+
List<Map<String, Object>> actualDocs = new ArrayList<>();
122+
int actualSize = 0;
123+
while (documents.hasNext()) {
124+
Map<String, Object> doc = convertDocumentToMap(documents.next());
125+
actualDocs.add(doc);
126+
actualSize++;
127+
}
128+
129+
long count =
130+
expectedDocs.stream().filter(expectedDoc -> actualDocs.contains(expectedDoc)).count();
131+
assertEquals(expectedSize, actualSize);
132+
assertEquals(expectedSize, count);
133+
}
115134
}

document-store/src/integrationTest/resources/mongo/test_aggr_alias_distinct_count_response.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
"qty_count":1,
55
"price":20
66
},
7+
{
8+
"item":"Soap",
9+
"qty_count":2,
10+
"price":10
11+
},
712
{
813
"item":"Mirror",
914
"qty_count":1,
@@ -13,10 +18,5 @@
1318
"item":"Comb",
1419
"qty_count":2,
1520
"price":7.5
16-
},
17-
{
18-
"item":"Soap",
19-
"qty_count":2,
20-
"price":10
2121
}
2222
]

0 commit comments

Comments
 (0)