Filtering Data
Learn how to effectively filter data using OData query syntax.
Basic Filtering
The $filter query option allows you to retrieve only records that match specific criteria.
Syntax
Simple Equality
Filter for an exact match:
# Patients with last name 'Smith'
GET /Patients?$filter=last_name eq 'Smith'
# Appointments with status 'confirmed'
GET /Appointments?$filter=status eq 'confirmed'
Numeric Comparisons
Use comparison operators for numbers and dates:
# Patients older than 18
GET /Patients?$filter=age gt 18
# Appointments after a specific date
GET /Appointments?$filter=appointment_date ge '2024-01-01'
# Patients between 18 and 65
GET /Patients?$filter=age ge 18 and age le 65
Logical Operators
AND
Combine multiple conditions that must all be true:
# Confirmed appointments for a specific patient
GET /Appointments?$filter=patient_id eq 12345 and status eq 'confirmed'
# Adult patients named John Smith
GET /Patients?$filter=first_name eq 'John' and last_name eq 'Smith' and age gt 18
OR
Match records that satisfy any condition:
# Appointments that are confirmed or pending
GET /Appointments?$filter=status eq 'confirmed' or status eq 'pending'
# Patients named John or Jane
GET /Patients?$filter=first_name eq 'John' or first_name eq 'Jane'
NOT
Negate a condition:
# Appointments that are not cancelled
GET /Appointments?$filter=not (status eq 'cancelled')
# Equivalent to:
GET /Appointments?$filter=status ne 'cancelled'
String Functions
contains()
Check if a string contains a substring:
# Patients with 'smith' anywhere in last name
GET /Patients?$filter=contains(last_name,'smith')
# Case-sensitive in some implementations
GET /Patients?$filter=contains(last_name,'Smith')
startswith()
Match strings that start with a specific value:
# Patients with last name starting with 'Sm'
GET /Patients?$filter=startswith(last_name,'Sm')
# Appointments in morning time slots (9:00 AM)
GET /Appointments?$filter=startswith(appointment_time,'09:')
endswith()
Match strings that end with a specific value:
# Patients with last name ending in 'son'
GET /Patients?$filter=endswith(last_name,'son')
# Emails ending with specific domain
GET /Patients?$filter=endswith(email,'@example.com')
Date and Time Filtering
Date Ranges
Filter by date ranges using comparison operators:
# Appointments in January 2024
GET /Appointments?$filter=appointment_date ge '2024-01-01' and appointment_date le '2024-01-31'
# Future appointments
GET /Appointments?$filter=appointment_date gt '2024-02-17'
# Past appointments
GET /Appointments?$filter=appointment_date lt '2024-02-17'
Date Functions
# Appointments on a specific date
GET /Appointments?$filter=appointment_date eq '2024-02-20'
# Patients born before a certain date
GET /Patients?$filter=date_of_birth lt '2000-01-01'
Filtering on Related Data
Use navigation properties in filter expressions:
# Patients with at least one appointment
GET /Patients?$filter=Appointments/any()
# Patients with confirmed appointments
GET /Patients?$filter=Appointments/any(a: a/status eq 'confirmed')
# Patients where all appointments are confirmed
GET /Patients?$filter=Appointments/all(a: a/status eq 'confirmed')
# Appointments with a specific physician
GET /Appointments?$filter=Physician/physician_id eq 67890
Complex Filters
Combine multiple techniques for sophisticated queries:
# Adult patients named Smith with confirmed appointments in February
GET /Patients
?$filter=last_name eq 'Smith'
and age gt 18
and Appointments/any(a:
a/status eq 'confirmed'
and a/appointment_date ge '2024-02-01'
and a/appointment_date le '2024-02-29'
)
Null Values
Check for null or non-null values:
# Patients with no email address
GET /Patients?$filter=email eq null
# Patients with an email address
GET /Patients?$filter=email ne null
Common Patterns
Search by Name
# Case-insensitive search (if supported)
GET /Patients?$filter=contains(tolower(last_name),'smith')
# Search by first or last name
GET /Patients
?$filter=contains(first_name,'John') or contains(last_name,'John')
Status Filtering
# Active appointments
GET /Appointments
?$filter=status ne 'cancelled' and appointment_date ge '2024-02-17'
# Completed appointments
GET /Appointments
?$filter=status eq 'completed' and appointment_date lt '2024-02-17'
Date-Based Queries
# This month's appointments
GET /Appointments
?$filter=appointment_date ge '2024-02-01' and appointment_date lt '2024-03-01'
# Today's appointments
GET /Appointments?$filter=appointment_date eq '2024-02-17'
# Upcoming appointments
GET /Appointments
?$filter=appointment_date ge '2024-02-17'
and status ne 'cancelled'
&$orderby=appointment_date
Performance Tips
Optimize Your Filters
- Index-friendly filters: Filter on indexed columns (IDs, status, dates)
- Specific before general: Put more restrictive filters first
- Avoid complex string operations: Use exact matches when possible
- Limit results: Combine with
$topto reduce response size
Avoid These Patterns
- Not using filters: Retrieving all data and filtering client-side
- Too complex: Filters that are difficult to optimize
- Case-insensitive text search: Can be slow on large datasets
- Too many OR conditions: Consider breaking into multiple requests
Examples by Use Case
Patient Lookup
# By full name
GET /Patients
?$filter=first_name eq 'John' and last_name eq 'Smith'
# By partial name
GET /Patients?$filter=contains(last_name,'Smi')
# By date of birth
GET /Patients?$filter=date_of_birth eq '1980-05-15'
Appointment Management
# Today's confirmed appointments
GET /Appointments
?$filter=appointment_date eq '2024-02-17' and status eq 'confirmed'
&$expand=Patient,Physician
&$orderby=appointment_time
# Pending appointments needing confirmation
GET /Appointments
?$filter=status eq 'pending' and appointment_date ge '2024-02-17'
&$orderby=appointment_date
Reporting Queries
# Monthly appointment count by status
GET /Appointments
?$filter=appointment_date ge '2024-02-01' and appointment_date lt '2024-03-01'
&$count=true
# New patients this year
GET /Patients
?$filter=created_date ge '2024-01-01'
&$count=true
Troubleshooting
Common Errors
Error: "Property 'xyz' does not exist"
Solution: Check property names match the schema in /$metadata
Error: "Invalid filter expression"
Solution: Verify syntax, especially:
- String values use single quotes: 'value'
- Property names are case-sensitive
- Operators are lowercase: eq, not EQ
Error: "The query is too complex"
Solution: Simplify the filter or split into multiple requests
Next Steps
- Learn about expanding related data
- Understand pagination strategies
- Review OData query syntax