Skip to content

Query Examples ​

This guide demonstrates various query patterns using PocketDB's filter system.

Setup ​

rust
use pocketdb::{Database, doc, Filter, PocketValue};

fn main() -> pocketdb::Result<()> {
    let db = Database::open("queries_example.pdb")?;
    let products = db.collection("products")?;

    products.insert(doc! { "name" => "Laptop", "price" => 999, "category" => "electronics", "stock" => 50 })?;
    products.insert(doc! { "name" => "Mouse", "price" => 25, "category" => "electronics", "stock" => 200 })?;
    products.insert(doc! { "name" => "Book", "price" => 20, "category" => "books", "stock" => 100 })?;
    products.insert(doc! { "name" => "Desk", "price" => 300, "category" => "furniture", "stock" => 15 })?;
    products.insert(doc! { "name" => "Chair", "price" => 150, "category" => "furniture", "stock" => 30 })?;

    Ok(())
}

Comparison Operators ​

Equality ​

rust
let results = products.find(&Filter::eq("category", PocketValue::String("electronics".into())));

Range Queries ​

rust
// Products under $100
let cheap = products.find(&Filter::lt("price", PocketValue::Int(100)));

// Products between $50 and $300
let mid_range = products.find(&Filter::and(
    Filter::gte("price", PocketValue::Int(50)),
    Filter::lte("price", PocketValue::Int(300)),
));

// Products with more than 50 in stock
let well_stocked = products.find(&Filter::gt("stock", PocketValue::Int(50)));

In List ​

rust
let results = products.find(&Filter::in_list("category", vec![
    PocketValue::String("electronics".into()),
    PocketValue::String("furniture".into()),
]));

Logical Operators ​

AND ​

rust
// Electronics with stock > 100
let results = products.find(&Filter::and(
    Filter::eq("category", PocketValue::String("electronics".into())),
    Filter::gt("stock", PocketValue::Int(100)),
));

OR ​

rust
// Electronics or furniture
let results = products.find(&Filter::or(
    Filter::eq("category", PocketValue::String("electronics".into())),
    Filter::eq("category", PocketValue::String("furniture".into())),
));

NOT ​

rust
// Not electronics
let results = products.find(&Filter::not(
    Filter::eq("category", PocketValue::String("electronics".into())),
));

NOR ​

rust
// Neither electronics nor books
let results = products.find(&Filter::nor(
    Filter::eq("category", PocketValue::String("electronics".into())),
    Filter::eq("category", PocketValue::String("books".into())),
));

String Operators ​

Starts With ​

rust
let results = products.find(&Filter::starts_with("name", "L"));
// Matches: "Laptop"

Ends With ​

rust
let results = products.find(&Filter::ends_with("name", "e"));
// Matches: "Laptop", "Mouse", "Book", "Desk"

Contains (Substring) ​

rust
let results = products.find(&Filter::contains("name", PocketValue::String("o".into())));
// Matches: "Laptop", "Mouse", "Book", "Chair"

Element Operators ​

Field Exists ​

rust
// Products with a "discount" field
let discounted = products.find(&Filter::exists("discount", true));

// Products without a "discount" field
let full_price = products.find(&Filter::exists("discount", false));

Sorting ​

rust
use pocketdb::query::SortDirection;

// Sort by price ascending
let mut results = products.find(&Filter::always_true());
results.sort_by(|a, b| {
    let pa = a.get("price").and_then(|v| v.as_i64()).unwrap_or(0);
    let pb = b.get("price").and_then(|v| v.as_i64()).unwrap_or(0);
    pa.cmp(&pb)
});

// Sort by price descending
let mut results = products.find(&Filter::always_true());
results.sort_by(|a, b| {
    let pa = a.get("price").and_then(|v| v.as_i64()).unwrap_or(0);
    let pb = b.get("price").and_then(|v| v.as_i64()).unwrap_or(0);
    pb.cmp(&pa)
});

Pagination ​

rust
// Page 1: items 1-10
let mut all = products.find(&Filter::always_true());
all.sort_by(|a, b| {
    let pa = a.get("price").and_then(|v| v.as_i64()).unwrap_or(0);
    let pb = b.get("price").and_then(|v| v.as_i64()).unwrap_or(0);
    pa.cmp(&pb)
});
let page1: Vec<_> = all.iter().take(10).cloned().collect();

// Page 2: items 11-20
let page2: Vec<_> = all.iter().skip(10).take(10).cloned().collect();

Complex Queries ​

Electronics Under $100 OR Furniture Over $200 ​

rust
let results = products.find(&Filter::or(
    Filter::and(
        Filter::eq("category", PocketValue::String("electronics".into())),
        Filter::lt("price", PocketValue::Int(100)),
    ),
    Filter::and(
        Filter::eq("category", PocketValue::String("furniture".into())),
        Filter::gt("price", PocketValue::Int(200)),
    ),
));

Active Products With Stock ​

rust
let results = products.find(&Filter::and(
    Filter::eq("active", PocketValue::Bool(true)),
    Filter::gt("stock", PocketValue::Int(0)),
));

Query Plans ​

Check which index is used:

rust
let plan = products.explain(&Filter::eq("name", PocketValue::String("Laptop".into())));
println!("Scan: {:?}", plan.scan);
println!("Index: {:?}", plan.index);

Released under the MIT License. Built by Muhammad Fiaz.