JEXL Expressions
JEXL expressions are the heart of the language, combining literals, variables, operators, functions, and transforms to create powerful data processing pipelines. This guide covers how to build and structure complex expressions effectively.
Expression Fundamentals
Simple Expressions
javascript
// Literal values
42
"hello world"
true
null
// Variable access
name
user.email
scores[0]Complex Expressions
javascript
// Arithmetic with variables
(score1 + score2 + score3) / 3
// String manipulation
firstName + " " + lastName | uppercase
// Conditional logic
age >= 18 ? "adult" : "minor"Function Calls
Functions perform operations and return values. Rakexl provides 80+ built-in functions.
Basic Function Calls
javascript
// Single argument
length("hello") // 5
abs(-10) // 10
uppercase("hello") // "HELLO"
// Multiple arguments
max([1, 5, 3, 9, 2]) // 9
substring("hello world", 0, 5) // "hello"
contains("hello world", "world") // trueNested Function Calls
javascript
// Functions within functions
length(split("a,b,c", ",")) // 3
max(map([1, 2, 3], "value * 2")) // 6
round(average([1.1, 2.7, 3.9]), 2) // 2.57Functions with Complex Arguments
javascript
// Using expressions as arguments
filter(users, "value.age > " + minAge)
map(items, "value.price * " + taxRate)
sort(products, "value.priority == 'high' ? 1 : 2")Transform Operations
Transforms use the pipe operator (|) to create data processing pipelines.
Single Transforms
javascript
" hello world " | trim // "hello world"
[1, 2, 3, 4, 5] | length // 5
{a: 1, b: 2, c: 3} | keys // ["a", "b", "c"]Transform Chains
javascript
// String processing pipeline
text | trim | lowercase | split(" ") | join("-")
// Array processing pipeline
numbers | filter("value > 0") | map("value * 2") | sort | reverse
// Mixed data processing
users | filter("value.active") | map("value.email") | distinct | sortTransforms with Arguments
javascript
// Transform functions with parameters
"hello world" | substring(0, 5) // "hello"
[1, 2, 3, 4] | filter("value > 2") // [3, 4]
"apple,banana,cherry" | split(",") // ["apple", "banana", "cherry"]Conditional Expressions
Ternary Operator
javascript
// Simple conditions
status = isActive ? "online" : "offline"
message = count == 1 ? "1 item" : count + " items"
// Nested conditions
grade = score >= 90 ? "A" :
score >= 80 ? "B" :
score >= 70 ? "C" :
score >= 60 ? "D" : "F"Logical Operations for Conditions
javascript
// Multiple conditions
canVote = age >= 18 && citizenship == "US" && registered == true
hasAccess = isAdmin || (isMember && subscription.active)
// Short-circuit evaluation
userName = user && user.profile && user.profile.name || "Anonymous"Array Operations
Array Creation and Manipulation
javascript
// Creating arrays
scores = [95, 87, 92, 78, 88]
names = ["Alice", "Bob", "Charlie"]
mixed = [user.name, user.age, user.active]
// Array transformations
highScores = scores | filter("value > 85") // [95, 87, 92, 88]
upperNames = names | map("value | uppercase") // ["ALICE", "BOB", "CHARLIE"]
sortedScores = scores | sort | reverse // [95, 92, 88, 87, 78]Array Aggregations
javascript
// Statistical operations
totalScore = scores | sum // 440
averageScore = scores | average // 88
highestScore = scores | max // 95
lowestScore = scores | min // 78
// Array analysis
uniqueValues = data | distinct
itemCount = items | length
hasHighScores = scores | any("value > 90") // true
allPassing = scores | all("value >= 60") // trueAdvanced Array Processing
javascript
// Group and process
usersByDepartment = users | groupBy("value.department")
departmentCounts = usersByDepartment | map("length(value)")
// Find operations
firstAdult = users | find("value.age >= 18")
adminIndex = users | findIndex("value.role == 'admin'")
// Array reduction
concatenated = strings | reduce("acc + value", "")
product = numbers | reduce("acc * value", 1)Object Operations
Object Creation and Access
javascript
// Creating objects
user = {
name: firstName + " " + lastName,
age: currentYear - birthYear,
isAdult: age >= 18,
email: name | lowercase | replace(" ", ".") + "@company.com"
}
// Dynamic property access
property = "email"
userEmail = user[property]Object Transformation
javascript
// Extract object information
userKeys = user | keys // ["name", "age", "isAdult", "email"]
userValues = user | values // ["John Doe", 30, true, "john.doe@company.com"]
userEntries = user | entries // [["name", "John Doe"], ...]
// Object merging
defaults = {theme: "light", timeout: 5000}
userPrefs = {theme: "dark"}
settings = merge(defaults, userPrefs) // {theme: "dark", timeout: 5000}String Processing
String Manipulation Chains
javascript
// Clean and format text
cleanTitle = rawTitle | trim | lowercase | replace(/[^a-z0-9\s]/g, "") | split(" ") | join("-")
// Text analysis
wordCount = text | split(" ") | length
hasKeyword = text | lowercase | contains(searchTerm | lowercase)
// String formatting
formatted = template | replace("{name}", user.name) | replace("{date}", now() | dateTimeFormat("YYYY-MM-DD"))String Validation
javascript
// Email validation pattern
isValidEmail = email | contains("@") && email | contains(".") && length(email) > 5
// Password strength
isStrongPassword = password | length >= 8 &&
password | contains(/[A-Z]/) &&
password | contains(/[a-z]/) &&
password | contains(/[0-9]/)Mathematical Expressions
Calculations
javascript
// Complex calculations
totalPrice = items | map("value.price * value.quantity") | sum
taxAmount = totalPrice * taxRate
finalPrice = totalPrice + taxAmount
// Statistics
variance = numbers | map("(value - " + (numbers | average) + ") ^ 2") | average
standardDeviation = sqrt(variance)
// Financial calculations
monthlyPayment = principal * (rate * (1 + rate)^months) / ((1 + rate)^months - 1)Mathematical Functions
javascript
// Trigonometry and advanced math
hypotenuse = sqrt(a^2 + b^2)
area = 3.14159 * radius^2
compound = principal * (1 + rate/periods)^(periods * years)
// Rounding and formatting
formatted = value | round(2) | formatNumber("$#,##0.00")
percentage = (value / total * 100) | round(1) + "%"Date and Time Operations
Date Calculations
javascript
// Current time operations
currentTime = now()
currentMillis = millis()
formatted = currentTime | dateTimeFormat("YYYY-MM-DD HH:mm:ss")
// Date arithmetic
futureDate = currentTime | dateTimeAdd("days", 30)
pastDate = currentTime | dateTimeAdd("months", -6)
// Time comparisons
isRecent = (now() | dateTimeToMillis) - (createdDate | dateTimeToMillis) < 86400000 // 24 hours
age = (now() | dateTimeToMillis) - (birthDate | dateTimeToMillis) | millisToDateTime | dateTimeFormat("YYYY")Error Handling and Safety
Safe Property Access
javascript
// Null-safe operations
userName = user && user.profile && user.profile.name || "Unknown"
email = user?.profile?.contact?.email || "No email"
// Checking existence
hasEmail = "email" in user && user.email != null && user.email != ""
validUser = user != null && "name" in user && "id" in userType Safety
javascript
// Type checking before operations
safeLength = typeof value == "string" || Array.isArray(value) ? length(value) : 0
safeUppercase = typeof text == "string" ? text | uppercase : text
// Default values for different types
safeName = typeof name == "string" && name | trim | length > 0 ? name | trim : "Unknown"
safeNumber = typeof num == "number" && !isNaN(num) ? num : 0Expression Composition
Building Complex Logic
javascript
// User eligibility check
isEligible = user.age >= minAge &&
user.status == "active" &&
user.credits >= requiredCredits &&
user.lastLogin | dateTimeToMillis >= cutoffDate | dateTimeToMillis
// Data processing pipeline
result = rawData
| filter("value != null && value.id != null")
| map("merge(value, {processedAt: now()})")
| sort("value.priority")
| filter("value.category in allowedCategories")
| map("transform(value)")Reusable Sub-expressions
javascript
// Define common calculations
taxRate = config.taxRate || 0.08
shippingCost = weight > 50 ? 25 : weight > 20 ? 15 : 5
discount = membership == "premium" ? 0.15 : membership == "standard" ? 0.10 : 0
// Use in main calculation
finalPrice = (basePrice * (1 - discount) * (1 + taxRate)) + shippingCostPerformance Considerations
Efficient Expression Structure
javascript
// Good - filter early, transform late
result = largeArray
| filter("value.active && value.score > threshold")
| map("complexTransformation(value)")
// Less efficient - transform everything first
result = largeArray
| map("complexTransformation(value)")
| filter("value.active && value.score > threshold")Minimize Function Calls
javascript
// Good - calculate once
currentTime = now()
recent = items | filter("value.timestamp > " + (currentTime - 86400000))
// Less efficient - calculate repeatedly
recent = items | filter("value.timestamp > " + (now() - 86400000))Common Expression Patterns
Data Validation
javascript
// Form validation
isValidForm = name | trim | length > 0 &&
email | contains("@") &&
age >= 18 &&
termsAccepted == true
// Data completeness
isComplete = requiredFields | all("value in data && data[value] != null")Data Transformation
javascript
// API response transformation
apiResponse = rawData | map("{
id: value.id,
name: value.full_name | trim,
email: value.email_address | lowercase,
isActive: value.status == 'active',
lastSeen: value.last_login | dateTimeFormat('YYYY-MM-DD')
}")Aggregation and Reporting
javascript
// Sales report
report = {
totalSales: orders | sum("value.amount"),
averageOrder: orders | average("value.amount"),
topCustomer: orders | groupBy("value.customerId") | map("sum(value, 'amount')") | max,
ordersByStatus: orders | groupBy("value.status") | map("length(value)")
}Search and Filtering
javascript
// Advanced search
searchResults = products
| filter("
(searchTerm == null || value.name | lowercase | contains(searchTerm | lowercase)) &&
(minPrice == null || value.price >= minPrice) &&
(maxPrice == null || value.price <= maxPrice) &&
(category == null || value.category == category)
")
| sort("value.relevanceScore")
| map("merge(value, {highlighted: highlightMatches(value.name, searchTerm)})")Best Practices
1. Use Meaningful Names
javascript
// Good
isEligibleCustomer = customer.age >= 18 && customer.creditScore > 600
customerFullName = customer.firstName + " " + customer.lastName
// Less clear
result = c.a >= 18 && c.cs > 600
name = c.fn + " " + c.ln2. Break Complex Expressions
javascript
// Good - readable steps
eligibilityAge = customer.age >= minimumAge
eligibilityCredit = customer.creditScore >= minimumCredit
eligibilityStatus = customer.status == "active"
isEligible = eligibilityAge && eligibilityCredit && eligibilityStatus
// Harder to read
isEligible = customer.age >= minimumAge && customer.creditScore >= minimumCredit && customer.status == "active"3. Use Comments for Complex Logic
javascript
// Calculate compound interest: P(1 + r/n)^(nt)
futureValue = principal * (1 + annualRate / compoundingsPerYear) ^ (compoundingsPerYear * years)
// Filter active users who logged in within the last 30 days
activeUsers = users | filter("value.status == 'active' && (now() - value.lastLogin) < 2592000000")4. Validate Inputs
javascript
// Good - safe processing
result = input != null && typeof input == "string" ?
input | trim | lowercase | split(",") | map("value | trim") :
[]
// Risky - assumes input is valid
result = input | trim | lowercase | split(",") | map("value | trim")Next: Learn about Context and Variables in JEXL expressions.