Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Laurus

A fast, featureful hybrid search library for Rust.

Laurus is a pure-Rust library that combines lexical search (keyword matching via inverted index) and vector search (semantic similarity via embeddings) into a single, unified engine. It is designed to be embedded directly into your Rust application — no external server required.

Key Features

FeatureDescription
Lexical SearchFull-text search powered by an inverted index with BM25 scoring
Vector SearchApproximate nearest neighbor (ANN) search using Flat, HNSW, or IVF indexes
Hybrid SearchCombine lexical and vector results with fusion algorithms (RRF, WeightedSum)
Text AnalysisPluggable analyzer pipeline — tokenizers, filters, stemmers, synonyms
EmbeddingsBuilt-in support for Candle (local BERT/CLIP), OpenAI API, or custom embedders
StoragePluggable backends — in-memory, file-based, or memory-mapped
Query DSLHuman-readable query syntax for lexical, vector, and hybrid search
Pure RustNo C/C++ dependencies in the core — safe, portable, easy to build

How It Works

graph LR
    subgraph Your Application
        D["Document"]
        Q["Query"]
    end

    subgraph Laurus Engine
        SCH["Schema"]
        AN["Analyzer"]
        EM["Embedder"]
        LI["Lexical Index\n(Inverted Index)"]
        VI["Vector Index\n(HNSW / Flat / IVF)"]
        FU["Fusion\n(RRF / WeightedSum)"]
    end

    D --> SCH
    SCH --> AN --> LI
    SCH --> EM --> VI
    Q --> LI --> FU
    Q --> VI --> FU
    FU --> R["Ranked Results"]
  1. Define a Schema — declare your fields and their types (text, integer, vector, etc.)
  2. Build an Engine — attach an analyzer for text and an embedder for vectors
  3. Index Documents — the engine routes each field to the correct index automatically
  4. Search — run lexical, vector, or hybrid queries and get ranked results

Document Map

SectionWhat You Will Learn
Getting StartedInstall Laurus and run your first search in minutes
ArchitectureUnderstand the Engine, its components, and data flow
Core ConceptsSchema, text analysis, embeddings, and storage
IndexingHow inverted indexes and vector indexes work internally
SearchQuery types, vector search, and hybrid fusion
Advanced FeaturesQuery DSL, ID management, WAL, and compaction
API ReferenceKey types and methods at a glance

Quick Example

use std::sync::Arc;
use laurus::{Document, Engine, Schema, SearchRequestBuilder, Result};
use laurus::lexical::{TextOption, TermQuery};
use laurus::storage::memory::MemoryStorage;

#[tokio::main]
async fn main() -> Result<()> {
    // 1. Storage
    let storage = Arc::new(MemoryStorage::new(Default::default()));

    // 2. Schema
    let schema = Schema::builder()
        .add_text_field("title", TextOption::default())
        .add_text_field("body", TextOption::default())
        .add_default_field("body")
        .build();

    // 3. Engine
    let engine = Engine::builder(storage, schema).build().await?;

    // 4. Index a document
    let doc = Document::builder()
        .add_text("title", "Hello Laurus")
        .add_text("body", "A fast search library for Rust")
        .build();
    engine.add_document("doc-1", doc).await?;
    engine.commit().await?;

    // 5. Search
    let request = SearchRequestBuilder::new()
        .lexical_search_request(
            laurus::LexicalSearchRequest::new(
                Box::new(TermQuery::new("body", "rust"))
            )
        )
        .limit(10)
        .build();
    let results = engine.search(request).await?;

    for r in &results {
        println!("{}: score={:.4}", r.id, r.score);
    }
    Ok(())
}

License

Laurus is dual-licensed under MIT and Apache 2.0.