Documentation Index
Fetch the complete documentation index at: https://docs.snackbase.dev/llms.txt
Use this file to discover all available pages before exploring further.
The Query Builder’s filter() method allows you to add conditions to your queries for precise data retrieval.
Overview
Filtering allows you to retrieve only the records that match specific conditions:
const results = await client.records
.query("posts")
.filter("status", "=", "published")
.get();
Filter Operators
| Operator | Description | Example |
|---|
= | Equals | filter("status", "=", "published") |
!= | Not equals | filter("status", "!=", "draft") |
> | Greater than | filter("views", ">", 100) |
>= | Greater than or equal | filter("views", ">=", 100) |
< | Less than | filter("views", "<", 1000) |
<= | Less than or equal | filter("views", "<=", 1000) |
~ | Contains (text search) | filter("title", "~", "tutorial") |
!~ | Does not contain | filter("title", "!~", "draft") |
?= | Is empty/null | filter("excerpt", "?=") |
?! | Is not empty/null | filter("excerpt", "?!=") |
String Filtering
// Exact match
const results = await client.records
.query("posts")
.filter("status", "=", "published")
.get();
// Contains text
const results = await client.records
.query("posts")
.filter("title", "~", "tutorial")
.get();
// Does not contain
const results = await client.records
.query("posts")
.filter("title", "!~", "draft")
.get();
Number Filtering
// Greater than
const popularPosts = await client.records
.query("posts")
.filter("views", ">", 1000)
.get();
// Range
const recentPopularPosts = await client.records
.query("posts")
.filter("views", ">=", 100)
.filter("views", "<=", 10000)
.get();
Date Filtering
// After a date
const recentPosts = await client.records
.query("posts")
.filter("createdAt", ">", "2024-01-01")
.get();
// Before a date
const oldPosts = await client.records
.query("posts")
.filter("createdAt", "<", "2023-01-01")
.get();
// Date range
const postsFrom2024 = await client.records
.query("posts")
.filter("createdAt", ">=", "2024-01-01")
.filter("createdAt", "<", "2025-01-01")
.get();
Boolean Filtering
// Is true
const activePosts = await client.records
.query("posts")
.filter("isPublished", "=", true)
.get();
// Is false/null
const draftPosts = await client.records
.query("posts")
.filter("isPublished", "?=")
.get();
Multiple Filters
Multiple filters are combined with AND logic:
const results = await client.records
.query("posts")
.filter("status", "=", "published")
.filter("views", ">", 100)
.filter("createdAt", ">=", "2024-01-01")
.get();
// SQL equivalent:
// WHERE status = 'published' AND views > 100 AND createdAt >= '2024-01-01'
Raw Filter Strings
For complex conditions, use raw filter strings:
const results = await client.records
.query("posts")
.filter("(status = 'published' || status = 'featured') && views > 100")
.get();
Raw Filter Operators
| Operator | Description | Example |
|---|
&& | AND | status = 'published' && views > 100 |
|| | OR | status = 'published' || status = 'featured' |
() | Grouping | (status = 'published' || status = 'featured') && views > 100 |
Complex Examples
OR Condition
const results = await client.records
.query("posts")
.filter("(status = 'published' || status = 'featured') && views > 100")
.get();
Nested Conditions
const results = await client.records
.query("posts")
.filter("((status = 'published' || status = 'featured') && views > 100) || (author.id = 'user-id' && status = 'draft')")
.get();
Select Fields in Filter
const results = await client.records
.query("posts")
.filter("author.role", "=", "editor")
.get();
Filter on Relations
Filter on expanded relations:
const results = await client.records
.query("posts")
.expand("author")
.filter("author.role", "=", "editor")
.get();
Case Sensitivity
Text filters are case-insensitive by default:
// Matches "Tutorial", "TUTORIAL", "tutorial", etc.
const results = await client.records
.query("posts")
.filter("title", "~", "tutorial")
.get();
Null Handling
Check for null/empty values:
// Is null
const postsWithoutExcerpt = await client.records
.query("posts")
.filter("excerpt", "?=")
.get();
// Is not null
const postsWithExcerpt = await client.records
.query("posts")
.filter("excerpt", "?!")
.get();
Filter Best Practices
1. Use Specific Filters
// Good - specific filter
const posts = await client.records
.query("posts")
.filter("status", "=", "published")
.filter("authorId", "=", user.id)
.get();
// Avoid - fetch all and filter in code
const allPosts = await client.records.list("posts");
const userPosts = allPosts.filter(p => p.authorId === user.id);
2. Combine with Indexes
Filter on indexed fields when possible for better performance:
// Assuming 'slug' and 'status' are indexed
const post = await client.records
.query("posts")
.filter("slug", "=", "my-post")
.filter("status", "=", "published")
.first();
Always paginate filtered queries:
const results = await client.records
.query("posts")
.filter("status", "=", "published")
.page(1, 20)
.get();
Complete Example
import { SnackBaseClient } from "@snackbase/sdk";
const client = new SnackBaseClient({
baseUrl: "https://api.example.com",
});
async function searchPosts() {
// Find published posts from 2024 with "tutorial" in title
const results = await client.records
.query("posts")
.expand("author")
.filter("status", "=", "published")
.filter("createdAt", ">=", "2024-01-01")
.filter("createdAt", "<", "2025-01-01")
.filter("title", "~", "tutorial")
.sort("createdAt", "desc")
.page(1, 20)
.get();
console.log(`Found ${results.total} posts`);
return results.items;
}
Next Steps