Skip to content

Commit e1074b9

Browse files
committed
Added 1 more integration test case to ensure result consistency b/w flat and nested collections
1 parent 13e591e commit e1074b9

1 file changed

Lines changed: 132 additions & 0 deletions

File tree

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

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3894,4 +3894,136 @@ void testFlatPostgresCollectionNestedFieldQuery(String dataStoreName) throws IOE
38943894
long cityCountQuery = flatCollection.count(cityQuery);
38953895
assertEquals(2, cityCountQuery);
38963896
}
3897+
3898+
@ParameterizedTest
3899+
@ArgumentsSource(PostgresProvider.class)
3900+
void testFlatVsNestedCollectionConsistency(String dataStoreName) throws IOException {
3901+
Datastore datastore = datastoreMap.get(dataStoreName);
3902+
3903+
// Get both collection types
3904+
Collection nestedCollection =
3905+
datastore.getCollection(COLLECTION_NAME); // Default nested collection
3906+
Collection flatCollection =
3907+
datastore.getCollectionForType(FLAT_COLLECTION_NAME, DocumentType.FLAT);
3908+
3909+
// Test 1: Count all documents - should be equal
3910+
Query countAllQuery = Query.builder().build();
3911+
long nestedCount = nestedCollection.count(countAllQuery);
3912+
long flatCount = flatCollection.count(countAllQuery);
3913+
assertEquals(
3914+
nestedCount, flatCount, "Total document count should be equal in both collections");
3915+
3916+
// Test 2: Filter by top-level field - item
3917+
Query itemFilterQuery =
3918+
Query.builder()
3919+
.setFilter(
3920+
RelationalExpression.of(
3921+
IdentifierExpression.of("item"), EQ, ConstantExpression.of("Soap")))
3922+
.build();
3923+
3924+
long nestedSoapCount = nestedCollection.count(itemFilterQuery);
3925+
long flatSoapCount = flatCollection.count(itemFilterQuery);
3926+
assertEquals(nestedSoapCount, flatSoapCount, "Soap count should be equal in both collections");
3927+
3928+
// Test 3: Filter by numeric field - price
3929+
Query priceFilterQuery =
3930+
Query.builder()
3931+
.setFilter(
3932+
RelationalExpression.of(
3933+
IdentifierExpression.of("price"), GT, ConstantExpression.of(10)))
3934+
.build();
3935+
3936+
long nestedPriceCount = nestedCollection.count(priceFilterQuery);
3937+
long flatPriceCount = flatCollection.count(priceFilterQuery);
3938+
assertEquals(
3939+
nestedPriceCount, flatPriceCount, "Price > 10 count should be equal in both collections");
3940+
3941+
// Test 4: Compare actual document content for same filter
3942+
CloseableIterator<Document> nestedIterator = nestedCollection.find(itemFilterQuery);
3943+
CloseableIterator<Document> flatIterator = flatCollection.find(itemFilterQuery);
3944+
3945+
// Collect documents from both collections
3946+
java.util.List<String> nestedDocs = new java.util.ArrayList<>();
3947+
java.util.List<String> flatDocs = new java.util.ArrayList<>();
3948+
3949+
while (nestedIterator.hasNext()) {
3950+
nestedDocs.add(nestedIterator.next().toJson());
3951+
}
3952+
nestedIterator.close();
3953+
3954+
while (flatIterator.hasNext()) {
3955+
flatDocs.add(flatIterator.next().toJson());
3956+
}
3957+
flatIterator.close();
3958+
3959+
// Both should return the same number of documents
3960+
assertEquals(
3961+
nestedDocs.size(),
3962+
flatDocs.size(),
3963+
"Both collections should return same number of documents");
3964+
3965+
// Test 5: Verify document structure consistency
3966+
if (!nestedDocs.isEmpty() && !flatDocs.isEmpty()) {
3967+
// Parse and compare first document from each collection
3968+
ObjectMapper mapper = new ObjectMapper();
3969+
JsonNode nestedDoc = mapper.readTree(nestedDocs.get(0));
3970+
JsonNode flatDoc = mapper.readTree(flatDocs.get(0));
3971+
3972+
// Verify both have the same top-level fields
3973+
assertTrue(nestedDoc.has("item") && flatDoc.has("item"), "Both should have 'item' field");
3974+
assertTrue(nestedDoc.has("price") && flatDoc.has("price"), "Both should have 'price' field");
3975+
assertTrue(
3976+
nestedDoc.has("quantity") && flatDoc.has("quantity"),
3977+
"Both should have 'quantity' field");
3978+
assertTrue(nestedDoc.has("date") && flatDoc.has("date"), "Both should have 'date' field");
3979+
3980+
// Verify the values are the same for basic fields
3981+
assertEquals(
3982+
nestedDoc.get("item").asText(), flatDoc.get("item").asText(), "Item values should match");
3983+
assertEquals(
3984+
nestedDoc.get("price").asInt(),
3985+
flatDoc.get("price").asInt(),
3986+
"Price values should match");
3987+
assertEquals(
3988+
nestedDoc.get("quantity").asInt(),
3989+
flatDoc.get("quantity").asInt(),
3990+
"Quantity values should match");
3991+
}
3992+
3993+
// Test 6: Test with different filter - quantity
3994+
Query quantityFilterQuery =
3995+
Query.builder()
3996+
.setFilter(
3997+
RelationalExpression.of(
3998+
IdentifierExpression.of("quantity"), EQ, ConstantExpression.of(10)))
3999+
.build();
4000+
4001+
long nestedQuantityCount = nestedCollection.count(quantityFilterQuery);
4002+
long flatQuantityCount = flatCollection.count(quantityFilterQuery);
4003+
assertEquals(
4004+
nestedQuantityCount,
4005+
flatQuantityCount,
4006+
"Quantity = 10 count should be equal in both collections");
4007+
4008+
// Test 7: Verify DocumentType is different
4009+
CloseableIterator<Document> nestedDocIterator = nestedCollection.find(Query.builder().build());
4010+
CloseableIterator<Document> flatDocIterator = flatCollection.find(Query.builder().build());
4011+
4012+
if (nestedDocIterator.hasNext() && flatDocIterator.hasNext()) {
4013+
Document nestedDocument = nestedDocIterator.next();
4014+
Document flatDocument = flatDocIterator.next();
4015+
4016+
assertEquals(
4017+
DocumentType.NESTED,
4018+
nestedDocument.getDocumentType(),
4019+
"Nested collection should return NESTED documents");
4020+
assertEquals(
4021+
DocumentType.FLAT,
4022+
flatDocument.getDocumentType(),
4023+
"Flat collection should return FLAT documents");
4024+
}
4025+
4026+
nestedDocIterator.close();
4027+
flatDocIterator.close();
4028+
}
38974029
}

0 commit comments

Comments
 (0)