Predicates¶
QueryMate provides a set of built-in predicates for filtering data. These predicates can be used in the filter
parameter of your queries.
Built-in Predicates¶
The following predicates are available out of the box:
Basic Predicates¶
Predicate |
Description |
Example |
---|---|---|
|
Equal to |
|
|
Not equal to |
|
|
Greater than |
|
|
Less than |
|
|
Greater than or equal to |
|
|
Less than or equal to |
|
|
Contains |
|
|
Starts with |
|
|
Ends with |
|
|
In list |
|
|
Not in list |
|
|
Is null |
|
|
Is not null |
|
Pattern Matching Predicates¶
Predicate |
Description |
Example |
---|---|---|
|
Matches pattern using LIKE |
|
|
Does not match pattern using NOT LIKE |
|
|
Matches any of the patterns |
|
|
Matches all of the patterns |
|
|
Does not match any of the patterns |
|
|
Does not match all of the patterns |
|
Presence Predicates¶
Predicate |
Description |
Example |
---|---|---|
|
Not null and not empty |
|
|
Null or empty |
|
Comparison Predicates¶
Predicate |
Description |
Example |
---|---|---|
|
Less than any of the values |
|
|
Less than or equal to any of the values |
|
|
Greater than any of the values |
|
|
Greater than or equal to any of the values |
|
|
Less than all of the values |
|
|
Less than or equal to all of the values |
|
|
Greater than all of the values |
|
|
Greater than or equal to all of the values |
|
|
Not equal to all of the values |
|
String Predicates¶
Predicate |
Description |
Example |
---|---|---|
|
Starts with |
|
|
Does not start with |
|
|
Starts with any of the values |
|
|
Starts with all of the values |
|
|
Does not start with any of the values |
|
|
Does not start with all of the values |
|
|
Ends with |
|
|
Does not end with |
|
|
Ends with any of the values |
|
|
Ends with all of the values |
|
|
Does not end with any of the values |
|
|
Does not end with all of the values |
|
Case-Insensitive Predicates¶
Predicate |
Description |
Example |
---|---|---|
|
Case-insensitive contains |
|
|
Case-insensitive contains any |
|
|
Case-insensitive contains all |
|
|
Case-insensitive does not contain |
|
|
Case-insensitive does not contain any |
|
|
Case-insensitive does not contain all |
|
Boolean Predicates¶
Predicate |
Description |
Example |
---|---|---|
|
Is true |
|
|
Is false |
|
Usage Examples¶
Basic Usage¶
# Filter users older than 18
query = QueryMate(filter={"age": {"gt": 18}})
# Filter users with name containing "john"
query = QueryMate(filter={"name": {"cont": "john"}})
# Filter users with age in [18, 19, 20]
query = QueryMate(filter={"age": {"in": [18, 19, 20]}})
Combining Predicates¶
You can combine multiple predicates using logical operators:
# Filter users older than 18 with name containing "john"
query = QueryMate(filter={
"age": {"gt": 18},
"name": {"cont": "john"}
})
# Filter users with age between 18 and 30
query = QueryMate(filter={
"age": {"gte": 18, "lte": 30}
})
# Filter users with name starting with "John" or "Jane"
query = QueryMate(filter={
"name": {"start_any": ["John", "Jane"]}
})
# Filter users with name containing "john" (case-insensitive)
query = QueryMate(filter={
"name": {"i_cont": "john"}
})
Extending Predicates¶
QueryMate is designed to be extensible. You can add your own predicates by creating a new predicate class and registering it with the FilterBuilder
.
Creating a Custom Predicate¶
Create a new predicate class:
from querymate.core.predicate import Predicate
class CustomPredicate(Predicate):
"""Custom predicate for checking if a value matches a pattern."""
def __init__(self, pattern: str):
self.pattern = pattern
def apply(self, field: Any, value: Any) -> bool:
"""Apply the predicate to the field and value."""
import re
return bool(re.match(self.pattern, str(value)))
Register the predicate:
from querymate.core.filter import FilterBuilder
# Register the predicate
FilterBuilder.register_predicate("matches", CustomPredicate)
Use the new predicate:
# Filter users with name matching a pattern
query = QueryMate(filter={"name": {"matches": "^J.*n$"}})
Contributing Predicates¶
We welcome contributions to add new predicates! Here’s how to contribute:
Fork the repository
Create a new branch for your predicate
Add your predicate class in
querymate/core/predicate.py
Add tests in
tests/test_predicate.py
Update the documentation
Submit a pull request
Guidelines for New Predicates¶
When contributing a new predicate, please ensure:
The predicate has a clear, descriptive name
The predicate is well-documented with docstrings
The predicate includes unit tests
The predicate follows the existing code style
The predicate is generic enough to be useful for multiple use cases
The predicate is efficient and doesn’t cause performance issues
Example Pull Request¶
Here’s an example of how to structure a pull request for a new predicate:
Title: Add regex_match predicate
Description:
Adds a new predicate for matching values against regular expressions.
This is useful for complex string matching scenarios.
Changes:
- Add RegexMatchPredicate class
- Add tests for regex_match predicate
- Update documentation
Example usage:
```python
query = QueryMate(filter={"name": {"regex_match": "^J.*n$"}})
```
Best Practices¶
Use the most specific predicate for your use case
Combine predicates logically for complex queries
Be mindful of performance when using string predicates
Consider using indexes for frequently used predicates
Document your custom predicates clearly