Skip to content

Commit

Permalink
Support for increment update query operator (#153)
Browse files Browse the repository at this point in the history
* Support for increment update query operator

* Suggested comments

* resolve comments

* Update document-store/src/main/java/org/hypertrace/core/documentstore/mongo/update/MongoUpdateExecutor.java

* Integration test failure

---------

Co-authored-by: Suresh Prakash <[email protected]>
  • Loading branch information
shantanu-vsbhosale and suresh-prakash authored Jun 12, 2023
1 parent 59d24b5 commit 92affb6
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import static org.hypertrace.core.documentstore.model.options.ReturnDocumentType.AFTER_UPDATE;
import static org.hypertrace.core.documentstore.model.options.ReturnDocumentType.BEFORE_UPDATE;
import static org.hypertrace.core.documentstore.model.options.ReturnDocumentType.NONE;
import static org.hypertrace.core.documentstore.model.subdoc.UpdateOperator.ADD;
import static org.hypertrace.core.documentstore.model.subdoc.UpdateOperator.ADD_TO_LIST_IF_ABSENT;
import static org.hypertrace.core.documentstore.model.subdoc.UpdateOperator.APPEND_TO_LIST;
import static org.hypertrace.core.documentstore.model.subdoc.UpdateOperator.REMOVE_ALL_FROM_LIST;
Expand Down Expand Up @@ -2164,9 +2165,16 @@ void testUpdateWithAllOperators(final String datastoreName) throws IOException {
.operator(REMOVE_ALL_FROM_LIST)
.subDocumentValue(SubDocumentValue.of(new String[] {"Hello"}))
.build();
final SubDocumentUpdate increment =
SubDocumentUpdate.builder()
.subDocument("price")
.operator(ADD)
.subDocumentValue(SubDocumentValue.of(1))
.build();

final Query query = Query.builder().build();
final List<SubDocumentUpdate> updates = List.of(set, unset, add, another_add, append, remove);
final List<SubDocumentUpdate> updates =
List.of(set, unset, add, another_add, append, remove, increment);

final CloseableIterator<Document> iterator =
collection.bulkUpdate(
Expand Down Expand Up @@ -2203,8 +2211,14 @@ void testUpdateWithAllOperators(final String datastoreName) throws IOException {
.operator(REMOVE_ALL_FROM_LIST)
.subDocumentValue(SubDocumentValue.of(new String[] {"Pluto", "Mars"}))
.build();
final SubDocumentUpdate decrement =
SubDocumentUpdate.builder()
.subDocument("price")
.operator(ADD)
.subDocumentValue(SubDocumentValue.of(-1))
.build();
final List<SubDocumentUpdate> new_updates =
List.of(set_new, unset_new, add_new, append_new, remove_new);
List.of(set_new, unset_new, add_new, append_new, remove_new, decrement);

final CloseableIterator<Document> iterator_new =
collection.bulkUpdate(
Expand Down Expand Up @@ -2320,6 +2334,7 @@ void testUpdateWithAllOperatorsOnObject(final String datastoreName) throws IOExc
new JSONDocument(Map.of("name", "Mars"))
}))
.build();

final List<SubDocumentUpdate> new_updates =
List.of(set_new, unset_new, add_new, append_new, remove_new);

Expand Down Expand Up @@ -2433,6 +2448,62 @@ void testSameHierarchyUpdateThrowsException(final String datastoreName) throws I
collection.bulkUpdate(
query, updates, UpdateOptions.builder().returnDocumentType(NONE).build()));
}

@ParameterizedTest
@ArgumentsSource(AllProvider.class)
void testAddOperatorThrowExceptionForNonNumericValue(final String datastoreName)
throws IOException {
final Collection collection = getCollection(datastoreName, UPDATABLE_COLLECTION_NAME);
createCollectionData("query/updatable_collection_data.json", UPDATABLE_COLLECTION_NAME);

// assert exception for string
final SubDocumentUpdate addString =
SubDocumentUpdate.builder()
.subDocument("item")
.operator(ADD)
.subDocumentValue(SubDocumentValue.of("Comb"))
.build();

final Query query = Query.builder().build();
final List<SubDocumentUpdate> updates = List.of(addString);
assertExceptionForNonNumericValues(collection, query, updates);

// assert exception for list
final SubDocumentUpdate addList =
SubDocumentUpdate.builder()
.subDocument("props.added.list")
.operator(ADD)
.subDocumentValue(SubDocumentValue.of(new Integer[] {5, 1, 5}))
.build();
final Query query_addList = Query.builder().build();
final List<SubDocumentUpdate> updates_addList = List.of(addList);
assertExceptionForNonNumericValues(collection, query_addList, updates_addList);

// assert exception for Object
final SubDocumentUpdate addObject =
SubDocumentUpdate.builder()
.subDocument("props.newObject")
.operator(ADD)
.subDocumentValue(
SubDocumentValue.of(
new Document[] {
new JSONDocument(Map.of("name", "Pluto")),
new JSONDocument(Map.of("name", "Mars"))
}))
.build();
final Query query_addObject = Query.builder().build();
final List<SubDocumentUpdate> updates_addObject = List.of(addObject);
assertExceptionForNonNumericValues(collection, query_addObject, updates_addObject);
}

private void assertExceptionForNonNumericValues(
Collection collection, Query query, List<SubDocumentUpdate> updates) {
assertThrows(
IOException.class,
() ->
collection.bulkUpdate(
query, updates, UpdateOptions.builder().returnDocumentType(NONE).build()));
}
}

@Nested
Expand Down Expand Up @@ -2467,6 +2538,12 @@ void testBulkUpdateWithFilterAndGetNoDocuments(final String datastoreName) throw
final SubDocumentUpdate dateUpdate = SubDocumentUpdate.of("date", "2022-08-09T18:53:17Z");
final SubDocumentUpdate quantityUpdate = SubDocumentUpdate.of("quantity", 1000);
final SubDocumentUpdate propsUpdate = SubDocumentUpdate.of("props.brand", "Dettol");
final SubDocumentUpdate priceUpdate =
SubDocumentUpdate.builder()
.subDocument("price")
.operator(ADD)
.subDocumentValue(SubDocumentValue.of(1))
.build();
final SubDocumentUpdate addProperty =
SubDocumentUpdate.of(
"props.new_property.deep.nested.value",
Expand All @@ -2475,7 +2552,7 @@ void testBulkUpdateWithFilterAndGetNoDocuments(final String datastoreName) throw
final CloseableIterator<Document> docIterator =
collection.bulkUpdate(
query,
List.of(dateUpdate, quantityUpdate, propsUpdate, addProperty),
List.of(dateUpdate, quantityUpdate, propsUpdate, addProperty, priceUpdate),
UpdateOptions.builder().returnDocumentType(NONE).build());

assertFalse(docIterator.hasNext());
Expand Down Expand Up @@ -2525,6 +2602,12 @@ void testBulkUpdateWithFilterAndGetAfterDocumentsEmpty(final String datastoreNam
final SubDocumentUpdate dateUpdate = SubDocumentUpdate.of("date", "2022-08-09T18:53:17Z");
final SubDocumentUpdate quantityUpdate = SubDocumentUpdate.of("quantity", 1000);
final SubDocumentUpdate propsUpdate = SubDocumentUpdate.of("props.brand", "Dettol");
final SubDocumentUpdate priceUpdate =
SubDocumentUpdate.builder()
.subDocument("price")
.operator(ADD)
.subDocumentValue(SubDocumentValue.of(1))
.build();
final SubDocumentUpdate addProperty =
SubDocumentUpdate.of(
"props.new_property.deep.nested.value",
Expand All @@ -2533,7 +2616,7 @@ void testBulkUpdateWithFilterAndGetAfterDocumentsEmpty(final String datastoreNam
final CloseableIterator<Document> docIterator =
collection.bulkUpdate(
query,
List.of(dateUpdate, quantityUpdate, propsUpdate, addProperty),
List.of(dateUpdate, quantityUpdate, propsUpdate, addProperty, priceUpdate),
UpdateOptions.builder().returnDocumentType(AFTER_UPDATE).build());

// Since the date is updated to conflict with the filter, there will not be any documents
Expand Down Expand Up @@ -2575,6 +2658,12 @@ void testBulkUpdateWithFilterAndGetAfterDocumentsNonEmpty(final String datastore
final SubDocumentUpdate dateUpdate = SubDocumentUpdate.of("date", "2022-08-09T18:53:17Z");
final SubDocumentUpdate quantityUpdate = SubDocumentUpdate.of("quantity", 1000);
final SubDocumentUpdate propsUpdate = SubDocumentUpdate.of("props.brand", "Dettol");
final SubDocumentUpdate priceUpdate =
SubDocumentUpdate.builder()
.subDocument("price")
.operator(ADD)
.subDocumentValue(SubDocumentValue.of(1))
.build();
final SubDocumentUpdate addProperty =
SubDocumentUpdate.of(
"props.new_property.deep.nested.value",
Expand All @@ -2583,7 +2672,7 @@ void testBulkUpdateWithFilterAndGetAfterDocumentsNonEmpty(final String datastore
final CloseableIterator<Document> docIterator =
collection.bulkUpdate(
query,
List.of(dateUpdate, quantityUpdate, propsUpdate, addProperty),
List.of(dateUpdate, quantityUpdate, propsUpdate, addProperty, priceUpdate),
UpdateOptions.builder().returnDocumentType(AFTER_UPDATE).build());

assertDocsAndSizeEqual(
Expand Down Expand Up @@ -2632,11 +2721,17 @@ void testBulkUpdateWithFilterAndGetBeforeDocuments(final String datastoreName)
SubDocumentUpdate.of(
"props.new_property.deep.nested.value",
SubDocumentValue.of(new JSONDocument("{\"json\": \"new_value\"}")));
final SubDocumentUpdate priceUpdate =
SubDocumentUpdate.builder()
.subDocument("price")
.operator(ADD)
.subDocumentValue(SubDocumentValue.of(1))
.build();

final CloseableIterator<Document> docIterator =
collection.bulkUpdate(
query,
List.of(dateUpdate, quantityUpdate, propsUpdate, addProperty),
List.of(dateUpdate, quantityUpdate, propsUpdate, addProperty, priceUpdate),
UpdateOptions.builder().returnDocumentType(BEFORE_UPDATE).build());

assertDocsAndSizeEqual(
Expand Down Expand Up @@ -2687,11 +2782,17 @@ void testBulkUpdateWithNonMatchingFilterAndGetBeforeDocuments(final String datas
SubDocumentUpdate.of(
"props.new_property.deep.nested.value",
SubDocumentValue.of(new JSONDocument("{\"json\": \"new_value\"}")));
final SubDocumentUpdate priceUpdate =
SubDocumentUpdate.builder()
.subDocument("price")
.operator(ADD)
.subDocumentValue(SubDocumentValue.of(1))
.build();

final CloseableIterator<Document> docIterator =
collection.bulkUpdate(
query,
List.of(dateUpdate, quantityUpdate, propsUpdate, addProperty),
List.of(dateUpdate, quantityUpdate, propsUpdate, addProperty, priceUpdate),
UpdateOptions.builder().returnDocumentType(BEFORE_UPDATE).build());

assertFalse(docIterator.hasNext());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{
"date": "2022-08-09T18:53:17Z",
"item": "Soap",
"price": 10,
"price": 11,
"quantity": 1000,
"props": {
"brand": "Dettol",
Expand Down Expand Up @@ -57,7 +57,7 @@
{
"date": "2022-08-09T18:53:17Z",
"item": "Soap",
"price": 20,
"price": 21,
"quantity": 1000,
"props": {
"brand": "Dettol",
Expand Down Expand Up @@ -104,7 +104,7 @@
{
"date": "2022-08-09T18:53:17Z",
"item": "Soap",
"price": 10,
"price": 11,
"quantity": 1000,
"props": {
"brand": "Dettol",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{
"date": "2022-08-09T18:53:17Z",
"item": "Soap",
"price": 10,
"price": 11,
"quantity": 1000,
"props": {
"brand": "Dettol",
Expand Down Expand Up @@ -57,7 +57,7 @@
{
"date": "2022-08-09T18:53:17Z",
"item": "Soap",
"price": 20,
"price": 21,
"quantity": 1000,
"props": {
"brand": "Dettol",
Expand Down Expand Up @@ -104,7 +104,7 @@
{
"date": "2022-08-09T18:53:17Z",
"item": "Soap",
"price": 10,
"price": 11,
"quantity": 1000,
"props": {
"brand": "Dettol",
Expand All @@ -121,7 +121,7 @@
},
{
"item": "Soap",
"price": 88,
"price": 89,
"quantity": 1000,
"date": "2022-08-09T18:53:17Z",
"props": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[
{
"date": "2022-08-09T18:53:17Z",
"price": 10,
"price": 11,
"quantity": 1000,
"props": {
"brand": "Dettol",
Expand All @@ -26,7 +26,7 @@
},
{
"date": "2022-08-09T18:53:17Z",
"price": 10,
"price": 11,
"quantity": 1000,
"props": {
"brand": "Dettol",
Expand All @@ -43,7 +43,7 @@
},
{
"date": "2022-08-09T18:53:17Z",
"price": 20,
"price": 21,
"quantity": 1000,
"props": {
"brand": "Dettol",
Expand All @@ -67,7 +67,7 @@
}
},
{
"price": 88,
"price": 89,
"quantity": 1000,
"date": "2022-08-09T18:53:17Z",
"props": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[
{
"item": "Soap",
"price": 10,
"price": 11,
"quantity": 2,
"date": "2014-03-01T08:00:00Z",
"props": {
Expand Down Expand Up @@ -41,7 +41,7 @@
},
{
"item": "Mirror",
"price": 20,
"price": 21,
"quantity": 1,
"date": "2014-03-01T09:00:00Z",
"props": {
Expand Down Expand Up @@ -72,7 +72,7 @@
},
{
"item": "Shampoo",
"price": 5,
"price": 6,
"quantity": 10,
"date": "2014-03-15T09:00:00Z",
"props": {
Expand Down Expand Up @@ -112,7 +112,7 @@
},
{
"item": "Shampoo",
"price": 5,
"price": 6,
"quantity": 20,
"date": "2014-04-04T11:21:39.736Z",
"props": {
Expand Down Expand Up @@ -143,7 +143,7 @@
},
{
"item": "Soap",
"price": 20,
"price": 21,
"quantity": 5,
"date": "2014-04-04T21:23:13.331Z",
"props": {
Expand Down Expand Up @@ -183,7 +183,7 @@
},
{
"item": "Comb",
"price": 7.5,
"price": 8.5,
"quantity": 5,
"date": "2015-06-04T05:08:13Z",
"props": {
Expand Down Expand Up @@ -214,7 +214,7 @@
},
{
"item": "Comb",
"price": 7.5,
"price": 8.5,
"quantity": 10,
"date": "2015-09-10T08:43:00Z",
"props": {
Expand Down Expand Up @@ -252,7 +252,7 @@
},
{
"item": "Soap",
"price": 10,
"price": 11,
"quantity": 5,
"date": "2016-02-06T20:20:13Z",
"props": {
Expand Down Expand Up @@ -283,7 +283,7 @@
},
{
"item": "Soap",
"price": 88,
"price": 89,
"quantity": 50,
"date": "2023-08-09T18:53:17Z",
"props": {
Expand Down
Loading

0 comments on commit 92affb6

Please sign in to comment.