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);