Dealing with Predicate Expression Filters in Aerospike REST Client (Part 2)
Tags: aerospike, rest
Published: 2020-04-26 16:02:56

![](https://images.unsplash.com/photo-1535406208535-1429839cfd13?ixlib=rb-1.2.1&auto=format&fit=crop&w=900&q=60)

In the previous [part](https://dev.to/aerospike/dealing-with-predicate-expression-filters-in-aerospike-rest-client-part-1-3njl) we spoke about using simple Predicate Expression Filters with the Aerospike REST Client. In this post I want to dive deeper and show how special filter operators could come in handy.

**LAST_UPDATE**
Asserts the last update time before processing the transaction.

Parameters:
* comparison operator 
* time in seconds since the epoch time (1970-01-01)

Example:
`LAST_UPDATE(>=, 1577880000)`

Java equivalent:
```java
PredExp.recLastUpdate()
PredExp.integerValue(1577880000000000000) //in nano
PredExp.integerGreaterEq()
```

**VOID_TIME**
Asserts the record’s expiration time before processing the transaction.

Parameters:
* comparison operator
* time in seconds since the epoch time (1970-01-01)

Example:
`VOID_TIME(>=, 1577880000)`

Java equivalent:
```java
PredExp.recVoidTime()
PredExp.integerValue(1577880000000000000) //in nano
PredExp.integerGreaterEq()
```

**DIGEST_MODULO**
Asserts a modulo against the record’s digest. The 160 bits (20 Bytes) digest field is generated by hashing the set name and the user key using the RipeMD-160 hashing function.

Parameters:
* modulo divisor
* comparison operator
* expected remainder value

Example for digest(key) % 3 == 1:
`DIGEST_MODULO(3, ==, 1)`

Java equivalent:
```java
PredExp.recDigestModulo(3)
PredExp.integerValue(1)
PredExp.integerEqual()
```

**STRING_REGEX**
Asserts that the regular expression matches the string valued bin.

Parameters:
* string bin name
* regular expression

Example:
`STRING_REGEX(str, [0-9]*)`

Java equivalent:
```java
PredExp.stringBin("str")
PredExp.stringValue("[0-9]*")
PredExp.stringRegex(RegexFlag.NONE)
```

**LIST_ITERATE_OR**
Creates a predicate expression to match **any** item in a list value bin.

Parameters:
* list bin name
* comparison operator
* value

Example:
Find records where any list item v = "hello" in list bin x.
`LIST_ITERATE_OR(x, ==, hello)`

Java equivalent:
```java
PredExp.stringVar("v")
PredExp.stringValue("hello")
PredExp.stringEqual()
PredExp.listBin("x")
PredExp.listIterateOr("v")
```

**LIST_ITERATE_AND**
Creates a predicate expression to match **all** items in a list value bin.

Parameters:
* list bin name
* comparison operator
* value

Example:
Find records where all list elements v != "world" in list bin x.
`LIST_ITERATE_AND(x, !=, world)`

Java equivalent:
```java
PredExp.stringVar("v")
PredExp.stringValue("world")
PredExp.stringUnequal()
PredExp.listBin("x")
PredExp.listIterateAnd("v")
```

**MAPKEY_ITERATE_OR**
Creates a predicate expression to match **any** map key.

Parameters:
* map bin name
* comparison operator
* value

Example:
Find records where any map key k = 7 in map bin m.
`MAPKEY_ITERATE_OR(m, ==, 7)`

Java equivalent:
```java
PredExp.integerVar("k")
PredExp.integerValue(7)
PredExp.integerEqual()
PredExp.mapBin("m")
PredExp.mapKeyIterateOr("k")
```

**MAPVAL_ITERATE_OR**
Creates a predicate expression to match **any** map value.

Parameters:
* map bin name
* comparison operator
* value

Example:
Find records where any map value v > 100 in map bin m.
`MAPVAL_ITERATE_OR(m, >, 100)`

Java equivalent:
```java
PredExp.integerVar("v")
PredExp.integerValue(100)
PredExp.integerGreater()
PredExp.mapBin("m")
PredExp.mapValIterateOr("v")
```

**MAPKEY_ITERATE_AND**
Creates a predicate expression to match **all** map keys.

Parameters:
* map bin name
* comparison operator
* value

Example:
Find records where all map keys k < 5 in map bin m.
`MAPKEY_ITERATE_AND(m, <, 5)`

Java equivalent:
```java
PredExp.integerVar("k")
PredExp.integerValue(5)
PredExp.integerLess()
PredExp.mapBin("m")
PredExp.mapKeyIterateAnd("k")
```

**MAPVAL_ITERATE_AND**
Creates a predicate expression to match **all** map values.

Parameters:
* map bin name
* comparison operator
* value

Example:
Find records where all map values v > 500 in map bin m.
`MAPVAL_ITERATE_AND(m, >, 500)`

Java equivalent:
```java
PredExp.integerVar("v")
PredExp.integerValue(500)
PredExp.integerGreater()
PredExp.mapBin("m")
PredExp.mapValIterateAnd("v")
```

At the end you can glue those with logical operators (and | or) mixing with simple filters, Base64-encode the whole expression and send it as a GET parameter.
```python
KVS_URL = 'http://localhost:8080/v1/kvs'

# In this example I put all metadata checks first, because Aerospike doesn't have an
# optimizer that knows how to shuffle predicates around more efficiently. This way, if the
# data is on an SSD, we can save on reading the record.
exp = b'(c >= 11 and not c < 20) or LAST_UPDATE(>=, 1577880000) or DIGEST_MODULO(3, ==, 1)'
encoded_exp = base64.b64encode(exp)

predexp_uri = '{base}/{ns}/{setname}/{userkey}'.format(
    base=KVS_URL, ns=namespace, setname=setname, userkey=userkey)

response = requests.get(predexp_uri, {"predexp": encoded_exp})
print(response.json())
```

To summarize, we’ve seen that Predicate Expression Filters are a very powerful tool and learned how to use them with the Aerospike REST Client.

If you still haven’t tried Aerospike REST Client and want to do so, you can find it [here](https://github.com/aerospike/aerospike-client-rest).