From 28688f0155226022033ec5237bb6d0842204b7b0 Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Fri, 20 Feb 2026 15:38:57 -0700 Subject: [PATCH 1/6] Updated examples to match Quickstart docs Renamed binName to "catalog" Aligned examples with Quickstart versions. --- .../aerospike/pathexpressions/PathExpressionsDemo.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java b/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java index 7ad71c8..da54fdd 100644 --- a/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java +++ b/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java @@ -54,7 +54,7 @@ public static void main(String[] args) throws IOException { AerospikeClient client = new AerospikeClient(clientPolicy, new Host("localhost", 3000)); // Truncate the inventory set client.truncate(null, "test", "products", null); - String binName = "inventory"; + String binName = "catalog"; // insert the inventory Key key = new Key("test", "products", "catalog"); client.put(null, key, new Bin(binName, inventory)); @@ -124,7 +124,9 @@ public static void main(String[] args) throws IOException { Record regexList = client.operate(null, key, CdtOperation.selectByPath(binName, Exp.SELECT_MAP_KEY, CTX.allChildren(), - CTX.allChildrenWithFilter(filterOnKey))); + CTX.allChildrenWithFilter(filterOnFeatured), + CTX.mapKey(Value.get("variants")), + CTX.allChildrenWithFilter(filterOnVariantInventory))); System.out.println("Result (MAP_KEYS only): " + Debug.print(regexList.getList(binName))); @@ -147,7 +149,7 @@ public static void main(String[] args) throws IOException { Record cheapInStock = client.operate(null, key, CdtOperation.selectByPath(binName, Exp.SELECT_MATCHING_TREE, CTX.allChildren(), - CTX.allChildren(), + CTX.allChildrenWithFilter(filterOnFeatured), CTX.mapKey(Value.get("variants")), CTX.allChildrenWithFilter(filterOnCheapInStock))); From b98399a730c86142b781c7292f17dab576252149 Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Fri, 20 Feb 2026 15:39:44 -0700 Subject: [PATCH 2/6] Updated examples to match Quickstart versions. Corrected descriptions of examples. --- README.md | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 2ef9cf2..a4f2343 100644 --- a/README.md +++ b/README.md @@ -127,15 +127,16 @@ We’ll filter at two levels of the data: When traversing with Path Expressions, the server evaluates filters at different depths. Here’s the stack we’re walking for this example: ``` -inventory (bin) - └── product (map entry, keyed by productId) - ├── category - ├── featured <-- product-level filter - ├── name - ├── description - └── variants - ├── { "2001": {...}, "2002": {...} } <-- map-backed variants - └── [ {sku:3007,...}, {sku:3008,...} ] <-- list-backed variants +catalog (bin) + └── inventory (map entry) + └── product (map entry, keyed by productId) + ├── category + ├── featured <-- product-level filter + ├── name + ├── description + └── variants + ├── { "2001": {...}, "2002": {...} } <-- map-backed variants + └── [ {sku:3007,...}, {sku:3008,...} ] <-- list-backed variants ^ variant-level filter ``` At product level, we filter by the `featured` field inside each product map. @@ -337,9 +338,11 @@ Exp filterOnKey = // Operation Record record = client.operate(null, key, - CdtOperation.selectByPath(binName, Exp.SELECT_MAP_KEY, + CdtOperation.selectByPath(binName, Exp.SELECT_MAP_KEY | Exp.SELECT_NO_FAIL, CTX.allChildren(), - CTX.allChildrenWithFilter(filterOnKey) + CTX.allChildrenWithFilter(filterOnKey), + CTX.mapKey(Value.get("variants")), + CTX.allChildrenWithFilter(filterOnVariantInventory) ) ); @@ -359,11 +362,11 @@ Expected Output: Filters can be chained with `AND` / `OR`. -**Example**: Select variants that are in stock and have price < 50 (across all products). +**Example**: Select variants that are in stock, have price < 50 (across all products), and are featured. **Note**: Unlike the previous examples focused on featured products for homepage promotion, this example demonstrates filtering at the variant level only, without a product-level filter. This pattern is useful for different scenarios like finding clearance items, budget options, or inventory that meets specific criteria across your entire catalog. -When you run the demo, look for the output labeled **"ADVANCED EXAMPLE 3: Combining multiple filters (price < 50 AND quantity > 0)"** in your terminal. +When you run the demo, look for the output labeled **"ADVANCED EXAMPLE 3: Combining multiple filters (price < 50 AND quantity > 0 AND featured = true)"** in your terminal. ```java Exp filterOnCheapInStock = Exp.and( @@ -381,7 +384,7 @@ Exp filterOnCheapInStock = Exp.and( Record record = client.operate(null, key, CdtOperation.selectByPath(binName, Exp.SELECT_MATCHING_TREE, CTX.allChildren(), // Navigate into all products - CTX.allChildren(), // Navigate deeper into product structure + CTX.allChildrenWithFilter(filterOnFeatured), // Navigate deeper into the featured product structure CTX.mapKey(Value.get("variants")), // Navigate to variants map/list CTX.allChildrenWithFilter(filterOnCheapInStock) // Filter variants by price and quantity ) @@ -485,7 +488,7 @@ Record noFailResponse = client.operate(null, key, With `NO_FAIL`, `malformed_product` excluded silently because variants was "no variant". -When you run the demo, look for the output labeled **"ADVANCED EXAMPLE 5: NO_FAIL flag to tolerate malformed data"** in your terminal. You'll first see **"❌ Operation failed as expected (malformed data without NO_FAIL flag)"** showing the operation fails without NO_FAIL, then **"✅ Operation succeeded with NO_FAIL flag:"** showing the successful operation with the flag. +When you run the demo, look for the output labeled **"ADVANCED EXAMPLE 6: NO_FAIL flag to tolerate malformed data"** in your terminal. You'll first see **"❌ Operation failed as expected (malformed data without NO_FAIL flag)"** showing the operation fails without NO_FAIL, then **"✅ Operation succeeded with NO_FAIL flag:"** showing the successful operation with the flag. Expected output: @@ -569,4 +572,4 @@ Exposes metadata of the current element (key, value, or index) during traversal. **Returns**: -An `Exp` object usable inside filter or modifying expressions. \ No newline at end of file +An `Exp` object usable inside filter or modifying expressions. From aa18901d0c42cf8ca7a3a2d6cc10e4fb223c23a2 Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Tue, 24 Feb 2026 11:29:49 -0700 Subject: [PATCH 3/6] Replaced modified example record with initial record value --- .../com/aerospike/pathexpressions/PathExpressionsDemo.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java b/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java index da54fdd..55f9add 100644 --- a/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java +++ b/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java @@ -278,6 +278,11 @@ public static void main(String[] args) throws IOException { System.out.println("✅ Operation succeeded with NO_FAIL flag:"); System.out.println(Debug.print(noFailResponse.getValue(binName))); + // Remove malformed data and return record to initial state + WritePolicy policy = new WritePolicy(); + policy.recordExistsAction = RecordExistsAction.UPDATE_ONLY; + client.put(updatePolicy, key, new Bin(binName, inventory)); + client.close(); } } From 6bd7861df83924ed0573c7559e7bf6a6691fb1d8 Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Tue, 24 Feb 2026 11:39:12 -0700 Subject: [PATCH 4/6] Replaced UPDATE_ONLY with REPLACE Replaced UPDATE_ONLY with REPLACE --- .../java/com/aerospike/pathexpressions/PathExpressionsDemo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java b/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java index 55f9add..820adec 100644 --- a/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java +++ b/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java @@ -280,7 +280,7 @@ public static void main(String[] args) throws IOException { // Remove malformed data and return record to initial state WritePolicy policy = new WritePolicy(); - policy.recordExistsAction = RecordExistsAction.UPDATE_ONLY; + policy.recordExistsAction = RecordExistsAction.REPLACE; client.put(updatePolicy, key, new Bin(binName, inventory)); client.close(); From ea9bdee9b5408ab5f8eb758efcc7c87a3174358c Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Tue, 24 Feb 2026 12:23:38 -0700 Subject: [PATCH 5/6] Fixed incorrect variable name for put replace command --- .../java/com/aerospike/pathexpressions/PathExpressionsDemo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java b/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java index 820adec..d5b61b6 100644 --- a/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java +++ b/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java @@ -281,7 +281,7 @@ public static void main(String[] args) throws IOException { // Remove malformed data and return record to initial state WritePolicy policy = new WritePolicy(); policy.recordExistsAction = RecordExistsAction.REPLACE; - client.put(updatePolicy, key, new Bin(binName, inventory)); + client.put(policy, key, new Bin(binName, inventory)); client.close(); } From 02eedf6dccb8273127195e1293baa421e816b4e7 Mon Sep 17 00:00:00 2001 From: Dominic Pelini <111786059+DomPeliniAerospike@users.noreply.github.com> Date: Tue, 24 Feb 2026 12:30:49 -0700 Subject: [PATCH 6/6] Added NO_FAIL to example 2 Since MAP_KEY expects map backed variants, but since product 50000009 is has list backed variants, this NO_FAIL flag is required. --- .../java/com/aerospike/pathexpressions/PathExpressionsDemo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java b/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java index d5b61b6..d717864 100644 --- a/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java +++ b/src/main/java/com/aerospike/pathexpressions/PathExpressionsDemo.java @@ -122,7 +122,7 @@ public static void main(String[] args) throws IOException { System.out.println("ADVANCED EXAMPLE 2: Alternate return modes with Exp.SELECT_"); System.out.println("=".repeat(80)); Record regexList = client.operate(null, key, - CdtOperation.selectByPath(binName, Exp.SELECT_MAP_KEY, + CdtOperation.selectByPath(binName, Exp.SELECT_MAP_KEY | Exp.SELECT_NO_FAIL, CTX.allChildren(), CTX.allChildrenWithFilter(filterOnFeatured), CTX.mapKey(Value.get("variants")),