Skip to main content

Query Expressions

Query expressions allow you to filter, sort, and paginate your data in ekoDB. This guide covers all operators, syntax patterns, and examples for both direct API usage and all client libraries.

Expression Structure

ekoDB uses a tagged union format for query expressions:

{
"type": "Condition" | "Logical",
"content": { ... }
}

Two Expression Types

  1. Condition - Single field comparison
  2. Logical - Combine multiple expressions (AND, OR, NOT)

Comparison Operators

All comparison operators follow this structure:

{
"type": "Condition",
"content": {
"field": "field_name",
"operator": "OperatorName",
"value": "comparison_value"
}
}

Available Operators

OperatorDescriptionAliasesExample Value
EqEqualsEqual, Equals"active", 25
NeNot equalsNotEqual, NotEquals"deleted", 0
GtGreater thanGreaterThan18, 100.5
GteGreater than or equalGreaterThanOrEqual18, 0
LtLess thanLessThan65, 1000
LteLess than or equalLessThanOrEqual100, 999.99
InValue in array-["active", "pending"]
NotInValue not in array-["deleted", "archived"]

String Operators

Special operators for string/text matching:

OperatorDescriptionCase SensitiveExample
ContainsSubstring matchYes"@gmail.com"
StartsWithPrefix matchYes"Dr. "
EndsWithSuffix matchYes".com"
String Matching

All string operators are case-sensitive. To perform case-insensitive searches, normalize your data (e.g., lowercase) on insert.


Logical Operators

Combine multiple expressions with logical operators:

AND - All conditions must match

{
"type": "Logical",
"content": {
"operator": "And",
"expressions": [
{
"type": "Condition",
"content": {
"field": "age",
"operator": "Gte",
"value": 18
}
},
{
"type": "Condition",
"content": {
"field": "status",
"operator": "Eq",
"value": "active"
}
}
]
}
}

OR - At least one condition must match

{
"type": "Logical",
"content": {
"operator": "Or",
"expressions": [
{
"type": "Condition",
"content": {
"field": "role",
"operator": "Eq",
"value": "admin"
}
},
{
"type": "Condition",
"content": {
"field": "role",
"operator": "Eq",
"value": "moderator"
}
}
]
}
}

NOT - Negate a condition

{
"type": "Logical",
"content": {
"operator": "Not",
"expressions": [
{
"type": "Condition",
"content": {
"field": "status",
"operator": "Eq",
"value": "deleted"
}
}
]
}
}

Complex Nested Logic

You can nest logical operators for complex queries:

{
"type": "Logical",
"content": {
"operator": "And",
"expressions": [
{
"type": "Condition",
"content": {
"field": "age",
"operator": "Gte",
"value": 18
}
},
{
"type": "Logical",
"content": {
"operator": "Or",
"expressions": [
{
"type": "Condition",
"content": {
"field": "country",
"operator": "Eq",
"value": "US"
}
},
{
"type": "Condition",
"content": {
"field": "country",
"operator": "Eq",
"value": "CA"
}
}
]
}
}
]
}
}

This finds records where: age >= 18 AND (country = "US" OR country = "CA")


Query Options

Beyond filters, you can add sorting, pagination, and performance options:

{
"filter": { ... },
"sort": [
{
"field": "created_at",
"ascending": false
},
{
"field": "name",
"ascending": true
}
],
"limit": 10,
"skip": 20,
"bypass_cache": false,
"bypass_ripple": true
}

Options Reference

OptionTypeDescription
filterQueryExpressionFilter condition (see above)
sortArraySort by one or more fields
limitIntegerMax results to return
skipIntegerResults to skip (pagination)
bypass_cacheBooleanSkip cache lookup
bypass_rippleBooleanDon't propagate to ripple peers

Usage Examples

For practical examples of using query expressions:


Common Query Patterns

Find All Active Records

{
"filter": {
"type": "Condition",
"content": {
"field": "status",
"operator": "Eq",
"value": "active"
}
}
}

Range Query (Between Values)

{
"filter": {
"type": "Logical",
"content": {
"operator": "And",
"expressions": [
{
"type": "Condition",
"content": {
"field": "price",
"operator": "Gte",
"value": 10.00
}
},
{
"type": "Condition",
"content": {
"field": "price",
"operator": "Lte",
"value": 100.00
}
}
]
}
}
}

Exclude Values (NOT IN)

{
"filter": {
"type": "Condition",
"content": {
"field": "status",
"operator": "NotIn",
"value": ["deleted", "archived", "spam"]
}
}
}

Search Multiple Fields (OR)

{
"filter": {
"type": "Logical",
"content": {
"operator": "Or",
"expressions": [
{
"type": "Condition",
"content": {
"field": "title",
"operator": "Contains",
"value": "urgent"
}
},
{
"type": "Condition",
"content": {
"field": "description",
"operator": "Contains",
"value": "urgent"
}
}
]
}
}
}

Complex Business Logic

Find premium users who are either:

  • Over 30 years old, OR
  • Have made more than 10 purchases
{
"filter": {
"type": "Logical",
"content": {
"operator": "And",
"expressions": [
{
"type": "Condition",
"content": {
"field": "tier",
"operator": "Eq",
"value": "premium"
}
},
{
"type": "Logical",
"content": {
"operator": "Or",
"expressions": [
{
"type": "Condition",
"content": {
"field": "age",
"operator": "Gt",
"value": 30
}
},
{
"type": "Condition",
"content": {
"field": "purchase_count",
"operator": "Gt",
"value": 10
}
}
]
}
}
]
}
}
}

Performance Tips

Use Indexes

First, generate an access token using your API key:

curl -X POST https://{EKODB_API_URL}/api/auth/token \
-H "Content-Type: application/json" \
-d '{"api_key": "YOUR_API_KEY"}'

Response:

{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Create indexes on fields you query frequently:

curl -X POST https://{EKODB_API_URL}/api/indexes/users \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"field": "status",
"index_type": "hash"
}'

See Indexes Documentation for more details.

Limit Results

Always use limit to prevent loading excessive data:

{
"filter": { ... },
"limit": 100
}

Bypass Cache for Fresh Data

When you need the absolute latest data:

{
"filter": { ... },
"bypass_cache": true
}

Use Specific Fields

Only select fields you need (reduces bandwidth):

{
"filter": { ... },
"select_fields": ["id", "name", "email"]
}

Troubleshooting

400 Bad Request - Invalid Filter Format

Wrong:

{
"filter": {
"field": "status",
"operator": "Eq",
"value": "active"
}
}

Correct:

{
"filter": {
"type": "Condition",
"content": {
"field": "status",
"operator": "Eq",
"value": "active"
}
}
}

Missing type and content wrapper!

400 Bad Request - Unknown Operator

Wrong:

{
"operator": "equals" // lowercase
}

Correct:

{
"operator": "Eq" // PascalCase
}

Operators are case-sensitive and use PascalCase.

Empty Results When Data Exists

  • Check if field names are correct (case-sensitive)
  • Verify value types match (string vs number)
  • For string matching, remember it's case-sensitive

Next Steps

Need Help?