Query Builder
The query builder provides a fluent interface for flexible searching.
Basic Usage
#![allow(unused)] fn main() { let results = store.query("heb") .limit(100) .execute()?; }
Filter Methods
By Lemma
#![allow(unused)] fn main() { // Exact match .lemma("כתב") // LIKE pattern (% = any chars, _ = single char) .lemma("כת%") // Starts with כת .lemma("%ב") // Ends with ב .lemma("%בר%") // Contains בר .lemma("___") // Exactly 3 characters }
By Form
#![allow(unused)] fn main() { // Exact match .form("כתבתי") // LIKE pattern .form("%ים") // Plural forms ending in ים .form("ה%") // Forms starting with ה }
By Part of Speech
#![allow(unused)] fn main() { .pos("V") // Verbs .pos("N") // Nouns .pos("ADJ") // Adjectives }
By Features (Pattern Match)
Position-dependent matching with wildcards:
#![allow(unused)] fn main() { // Match specific positions .features_match("V;1;SG;*") // 1st person singular verbs .features_match("V;*;*;PST;*") // Past tense verbs .features_match("N;*;PL;*") // Plural nouns }
By Features (Contains)
Position-independent matching:
#![allow(unused)] fn main() { // Has these features anywhere .features_contain(&["FUT"]) // Future tense .features_contain(&["PL", "MASC"]) // Plural masculine .features_contain(&["V", "1", "SG"]) // 1st person singular verbs }
Pagination
#![allow(unused)] fn main() { // First page .limit(20) .offset(0) // Second page .limit(20) .offset(20) // All results (careful with large datasets!) .limit(usize::MAX) }
Executing Queries
Get Results
#![allow(unused)] fn main() { let entries: Vec<Entry> = store.query("heb") .pos("V") .limit(100) .execute()?; for entry in &entries { println!("{} {} {}", entry.lemma, entry.form, entry.features); } }
Count Results
#![allow(unused)] fn main() { let count = store.query("heb") .pos("V") .count()?; println!("Found {} verbs", count); }
Check Existence
#![allow(unused)] fn main() { let exists = store.query("heb") .lemma("כתב") .exists()?; if exists { println!("Lemma found"); } }
Get First Result
#![allow(unused)] fn main() { if let Some(entry) = store.query("heb") .lemma("כתב") .first()? { println!("First form: {}", entry.form); } }
Chaining Filters
Filters are combined with AND logic:
#![allow(unused)] fn main() { let results = store.query("heb") .lemma("כת%") // AND .pos("V") // AND .features_contain(&["FUT"]) // AND .limit(10) .execute()?; }
Examples
Find All Verb Infinitives
#![allow(unused)] fn main() { let infinitives = store.query("heb") .pos("V") .features_contain(&["NFIN"]) .execute()?; }
Find Ambiguous Forms
Forms that could be multiple parts of speech:
#![allow(unused)] fn main() { let form = "שמר"; let as_verb = store.query("heb") .form(form) .pos("V") .execute()?; let as_noun = store.query("heb") .form(form) .pos("N") .execute()?; if !as_verb.is_empty() && !as_noun.is_empty() { println!("{} is ambiguous (verb and noun)", form); } }
Paginate Through All Results
#![allow(unused)] fn main() { let page_size = 100; let mut offset = 0; loop { let results = store.query("heb") .pos("V") .limit(page_size) .offset(offset) .execute()?; if results.is_empty() { break; } for entry in &results { // Process entry } offset += page_size; } }
Export Filtered Subset
#![allow(unused)] fn main() { use std::io::Write; let mut file = std::fs::File::create("verbs.tsv")?; let verbs = store.query("heb") .pos("V") .limit(usize::MAX) .execute()?; for entry in &verbs { writeln!(file, "{}\t{}\t{}", entry.lemma, entry.form, entry.features)?; } }
Performance Tips
- Use limits: Always set a reasonable limit
- Prefer specific filters: More filters = faster queries
- Use
count()first: Check result size before fetching all - Index-friendly queries: Lemma and form queries use indexes
#![allow(unused)] fn main() { // Good: Uses index .lemma("כתב") // Good: Uses index .form("כתבתי") // Slower: Full scan with pattern .lemma("%תב%") // Slower: Feature scan .features_contain(&["FUT"]) }