Query DSL
The FLXBL Query DSL is a JSON-based query language that supports MongoDB-style operators and graph traversal. Query complex data without writing SQL or Cypher.
Basic Query Structure
// POST /api/v1/dynamic/Product/query
{
"where": {
"price": { "$lte": 100 },
"inStock": { "$eq": true }
},
"orderBy": "price",
"orderDirection": "ASC",
"limit": 20
}Query options:
| Option | Type | Description |
|---|---|---|
where | object | Filter conditions |
traverse | array | Graph relationship traversal |
orderBy | string | Field to sort by |
orderDirection | "ASC" | "DESC" | Sort direction |
limit | number | Maximum results to return |
offset | number | Number of results to skip |
Comparison Operators
// Comparison operators
{
"where": {
"price": { "$eq": 99.99 }, // Equal
"price": { "$neq": 99.99 }, // Not equal
"price": { "$gt": 50 }, // Greater than
"price": { "$gte": 50 }, // Greater than or equal
"price": { "$lt": 100 }, // Less than
"price": { "$lte": 100 }, // Less than or equal
"status": { "$in": ["active", "pending"] } // In array
}
}| Operator | Description | Example |
|---|---|---|
$eq | Equal to | { "status": { "$eq": "active" } } |
$neq | Not equal to | { "status": { "$neq": "deleted" } } |
$gt | Greater than | { "price": { "$gt": 50 } } |
$gte | Greater than or equal | { "price": { "$gte": 50 } } |
$lt | Less than | { "price": { "$lt": 100 } } |
$lte | Less than or equal | { "price": { "$lte": 100 } } |
$in | Value in array | { "status": { "$in": ["a", "b"] } } |
Array Operators
For array fields, use $contains to check if the array includes a specific value:
// Array operators (for array fields)
{
"where": {
"tags": { "$contains": "featured" } // Check if array contains value
}
}
Operator Description Example $contains Array contains value { "tags": { "$contains": "featured" } }
String Operators
For string fields, FLXBL provides case-insensitive matching operators:
// String operators (case-insensitive)
{
"where": {
"name": { "$contains": "widget" }, // Substring match
"email": { "$startsWith": "admin" }, // Prefix match
"email": { "$endsWith": "@example.com" } // Suffix match
}
}
Operator Description Example $contains Substring match (case-insensitive) { "name": { "$contains": "widget" } } $startsWith Prefix match (case-insensitive) { "email": { "$startsWith": "admin" } } $endsWith Suffix match (case-insensitive) { "email": { "$endsWith": "@example.com" } }
Note: The $contains operator works differently based on field type:
for array fields, it checks if the array includes the value;
for string fields, it performs a case-insensitive substring search.
Logical Operators
Combine multiple conditions with $and and $or:
// Logical operators
{
"where": {
"$and": [
{ "price": { "$gte": 10 } },
{ "price": { "$lte": 100 } }
]
}
}
// OR condition
{
"where": {
"$or": [
{ "status": { "$eq": "featured" } },
{ "price": { "$lt": 20 } }
]
}
}
// Combining AND and OR
{
"where": {
"$and": [
{ "inStock": { "$eq": true } },
{
"$or": [
{ "category": { "$eq": "electronics" } },
{ "category": { "$eq": "accessories" } }
]
}
]
}
}
Graph Traversal
The traverse option lets you follow relationships in the graph.
This is one of FLXBL's most powerful features.
// Graph traversal - follow relationships
{
"where": {
"name": { "$eq": "Wireless Headphones" }
},
"traverse": [{
"relationship": "BELONGS_TO",
"direction": "out",
"where": {
"name": { "$eq": "Electronics" }
}
}]
}
// Multi-hop traversal
{
"where": {
"email": { "$eq": "alice@example.com" }
},
"traverse": [
{
"relationship": "PURCHASED",
"direction": "out"
},
{
"relationship": "BELONGS_TO",
"direction": "out",
"where": {
"name": { "$eq": "Electronics" }
}
}
]
}
Traverse options:
Option Type Description relationship string Name of the relationship to follow direction "in" | "out" Direction to traverse where object Filter on the related entity
Pagination
// Pagination and sorting
{
"where": {
"status": { "$eq": "active" }
},
"orderBy": "createdAt",
"orderDirection": "DESC",
"limit": 10,
"offset": 20
}
Complete Example
Here's a complete example that combines multiple operators
with graph traversal:
// Complete query example
curl -X POST https://api.flxbl.dev/api/v1/dynamic/Product/query \
-H "Authorization: Bearer flxbl_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"where": {
"$and": [
{ "price": { "$gte": 10, "$lte": 500 } },
{ "inStock": { "$eq": true } },
{
"$or": [
{ "tags": { "$contains": "featured" } },
{ "tags": { "$contains": "sale" } }
]
}
]
},
"traverse": [{
"relationship": "BELONGS_TO",
"direction": "out",
"where": {
"slug": { "$in": ["electronics", "accessories"] }
}
}],
"orderBy": "price",
"orderDirection": "ASC",
"limit": 20
}'
TypeScript Client
Use the generated TypeScript client for type-safe queries:
// TypeScript client usage
import { createFlxblClient } from './schemas';
const client = createFlxblClient({
baseUrl: 'https://api.flxbl.dev',
apiKey: 'flxbl_your_api_key'
});
// Query with type safety
const products = await client.query('Product', {
where: {
price: { $gte: 10, $lte: 100 },
inStock: { $eq: true }
},
traverse: [{
relationship: 'BELONGS_TO',
direction: 'out',
where: { slug: { $eq: 'electronics' } }
}],
orderBy: 'price',
orderDirection: 'ASC',
limit: 20
});
console.log(products); // Typed as Product[]
Best Practices
- Limit results: Always set a reasonable limit to avoid returning too much data
- Optimize traversals: Start with the most selective condition first
- Cache when possible: Use Redis caching for frequently repeated queries
- Test with real data: Query performance varies with data size
Next Steps
- API Reference - Complete endpoint documentation
- Schema Design - Design schemas for better queries
- MCP Integration - Generate typed clients