use luci::index::Index;
use luci::mapping::{FieldType, Mapping};
use luci::search::expression::parse_search;
use serde_json::json;
fn main() {
let schema = Mapping::builder()
.field("title", FieldType::Text)
.field("body", FieldType::Text)
.field("tag", FieldType::Keyword)
.build();
let path = std::env::temp_dir().join("luci_quickstart");
let _ = std::fs::remove_dir_all(&path);
let mut index = Index::create_with_mapping(&path, schema).expect("failed to create index");
let docs = vec![
json!({"title": "The Rust Programming Language", "body": "Rust is a systems programming language focused on safety and performance.", "tag": "programming"}),
json!({"title": "Search Engine Design", "body": "Building a search engine requires inverted indexes, scoring algorithms, and query parsing.", "tag": "search"}),
json!({"title": "Database Internals", "body": "Understanding storage engines, B-trees, and write-ahead logs.", "tag": "databases"}),
json!({"title": "Information Retrieval", "body": "The science of searching for information in documents, including BM25 scoring and relevance ranking.", "tag": "search"}),
json!({"title": "Systems Programming in Rust", "body": "Using Rust to build high-performance systems like databases and search engines.", "tag": "programming"}),
];
index.bulk(docs).expect("failed to add documents");
println!("Indexed 5 documents.\n");
println!("=== Term query: tag = \"search\" ===");
let expr = parse_search(json!({"term": {"tag": "search"}}), 10).unwrap();
let results = index.search(&expr).expect("search failed");
println!("Hits: {}", results.total_hits().value);
for i in 0..results.len() {
let hit = results.hit(i).unwrap();
let src = hit.source().unwrap();
println!(" [{:.3}] {}", hit.score(), src["title"]);
}
println!("\n=== Match query: body = \"search engine\" ===");
let expr = parse_search(json!({"match": {"body": "search engine"}}), 10).unwrap();
let results = index.search(&expr).expect("search failed");
println!("Hits: {}", results.total_hits().value);
for i in 0..results.len() {
let hit = results.hit(i).unwrap();
let src = hit.source().unwrap();
println!(" [{:.3}] {}", hit.score(), src["title"]);
}
println!("\n=== Phrase query: body = \"search engine\" ===");
let expr = parse_search(json!({"match_phrase": {"body": "search engine"}}), 10).unwrap();
let results = index.search(&expr).expect("search failed");
println!("Hits: {}", results.total_hits().value);
for i in 0..results.len() {
let hit = results.hit(i).unwrap();
let src = hit.source().unwrap();
println!(" [{:.3}] {}", hit.score(), src["title"]);
}
println!("\n=== Bool query: match \"rust\" AND tag = \"programming\" ===");
let expr = parse_search(
json!({
"bool": {
"must": [{"match": {"body": "rust"}}],
"filter": [{"term": {"tag": "programming"}}]
}
}),
10,
)
.unwrap();
let results = index.search(&expr).expect("search failed");
println!("Hits: {}", results.total_hits().value);
for i in 0..results.len() {
let hit = results.hit(i).unwrap();
let src = hit.source().unwrap();
println!(" [{:.3}] {}", hit.score(), src["title"]);
}
println!("\n=== Match all ===");
let expr = parse_search(json!({"match_all": {}}), 10).unwrap();
let results = index.search(&expr).expect("search failed");
println!("Hits: {}", results.total_hits().value);
let _ = std::fs::remove_dir_all(&path);
println!("\nDone.");
}