Skip to main content
The QueryBuilder provides a fluent API for constructing complex queries with filtering, sorting, pagination, and field projection.

Creating a query

Get a query builder from a collection:
let users = db.collection("users");
let query = users.query();

Filtering

filter

Filter documents using a query string.
pub fn filter(self, query: &str) -> Self
query
&str
required
Query string (e.g., “age > 25 and city is “NYC"")
Example:
let results = users.query()
    .filter("age >= 18 and city is \"New York\"")
    .execute()?;

Sorting

sort_by

Sort results by a field.
pub fn sort_by(self, field: &str, order: SortOrder) -> Self
field
&str
required
Field name (supports nested fields with dot notation)
order
SortOrder
required
Sort order (SortOrder::Asc or SortOrder::Desc)
Example:
use jasonisnthappy::SortOrder;

// Sort by age ascending
let results = users.query()
    .sort_by("age", SortOrder::Asc)
    .execute()?;

// Sort by multiple fields
let results = users.query()
    .sort_by("city", SortOrder::Asc)
    .sort_by("age", SortOrder::Desc)
    .execute()?;

SortOrder

SortOrder::Asc
enum variant
Sort in ascending order
SortOrder::Desc
enum variant
Sort in descending order

Pagination

limit

Limit the number of results.
pub fn limit(self, n: usize) -> Self
n
usize
required
Maximum number of results to return
Example:
// Get first 10 users
let results = users.query()
    .limit(10)
    .execute()?;

skip

Skip the first N results.
pub fn skip(self, n: usize) -> Self
n
usize
required
Number of results to skip
Example:
// Get page 2 (results 11-20)
let results = users.query()
    .sort_by("name", SortOrder::Asc)
    .skip(10)
    .limit(10)
    .execute()?;

Field projection

project

Include only specified fields in results.
pub fn project(self, fields: &[&str]) -> Self
fields
&[&str]
required
Array of field names to include
Example:
// Get only name and email fields
let results = users.query()
    .project(&["name", "email"])
    .execute()?;

// _id is always included unless explicitly excluded
// Supports nested fields
let results = users.query()
    .project(&["name", "address.city"])
    .execute()?;

exclude

Exclude specified fields from results.
pub fn exclude(self, fields: &[&str]) -> Self
fields
&[&str]
required
Array of field names to exclude
Example:
// Get all fields except password and secret
let results = users.query()
    .exclude(&["password", "secret_key"])
    .execute()?;

// Exclude nested fields
let results = users.query()
    .exclude(&["address.street"])
    .execute()?;

Executing queries

execute

Execute the query and return all matching documents.
pub fn execute(self) -> Result<Vec<Value>>
Returns: Result<Vec<Value>> - Vector of matching documents Example:
let results = users.query()
    .filter("age >= 21")
    .sort_by("name", SortOrder::Asc)
    .limit(50)
    .execute()?;

for user in results {
    println!("{}: {}", user["name"], user["age"]);
}

first

Execute the query and return only the first result.
pub fn first(self) -> Result<Option<Value>>
Returns: Result<Option<Value>> - The first matching document, or None Example:
if let Some(user) = users.query()
    .filter("email is \"[email protected]\"")
    .first()? 
{
    println!("Found user: {}", user["name"]);
}

count

Count matching documents without fetching them.
pub fn count(self) -> Result<usize>
Returns: Result<usize> - Number of matching documents Example:
let total = users.query()
    .filter("age >= 18")
    .count()?;

println!("Found {} adults", total);

Complete examples

Pagination

use jasonisnthappy::SortOrder;

let page_size = 20;
let page_number = 2; // 0-indexed

let results = users.query()
    .filter("status is \"active\"")
    .sort_by("created_at", SortOrder::Desc)
    .skip(page_number * page_size)
    .limit(page_size)
    .execute()?;

println!("Page {} has {} results", page_number + 1, results.len());

Filtering and sorting

use jasonisnthappy::SortOrder;

// Find active users in NYC, sorted by age (oldest first)
let results = users.query()
    .filter("city is \"NYC\" and status is \"active\"")
    .sort_by("age", SortOrder::Desc)
    .execute()?;

Field projection

// Get only essential user info for a list view
let users_list = users.query()
    .filter("status is \"active\"")
    .project(&["name", "email", "avatar_url"])
    .sort_by("name", SortOrder::Asc)
    .execute()?;

// Or exclude sensitive fields
let public_profiles = users.query()
    .exclude(&["password", "api_key", "email"])
    .execute()?;

Complex query

use jasonisnthappy::SortOrder;

// Get top 10 premium users in a specific city
let results = users.query()
    .filter("city is \"San Francisco\" and plan is \"premium\" and age >= 18")
    .sort_by("signup_date", SortOrder::Asc)
    .project(&["name", "email", "plan", "signup_date"])
    .limit(10)
    .execute()?;

for (i, user) in results.iter().enumerate() {
    println!("{}. {} ({})", i + 1, user["name"], user["email"]);
}

Nested field sorting and projection

use jasonisnthappy::SortOrder;

// Sort by nested field
let results = users.query()
    .sort_by("address.city", SortOrder::Asc)
    .sort_by("profile.score", SortOrder::Desc)
    .execute()?;

// Project nested fields
let results = users.query()
    .project(&["name", "address.city", "address.zip"])
    .execute()?;

Getting total count with pagination

use jasonisnthappy::SortOrder;

let page_size = 20;
let page = 0;

// Get total count
let total = users.query()
    .filter("status is \"active\"")
    .count()?;

// Get page of results
let results = users.query()
    .filter("status is \"active\"")
    .sort_by("name", SortOrder::Asc)
    .skip(page * page_size)
    .limit(page_size)
    .execute()?;

let total_pages = (total + page_size - 1) / page_size;
println!("Page {}/{} ({} total results)", page + 1, total_pages, total);

Build docs developers (and LLMs) love