simsearch

repository·main·Indexed 41 days ago

https://github.com/andylokandy/simsearch

A lightweight, in-memory fuzzy search index for Rust applications, designed for embedded autocomplete and search suggestions. Version 0.4.0 provides the Index<T> type for mapping unique identifiers to searchable strings, supporting multi-field indexing via insert_parts, Jaro-Winkler typo tolerance, and customizable search options including result limits and case sensitivity.

Tokens
1.4K
Snippets
8
Records
8
Agent score
2%

What's inside simsearch

  1. Perform fuzzy search with the Index type

    main

    The Index<T> type is the core of simsearch. It allows you to map unique identifiers of type T to string values for fuzzy searching.

    1. Initialize a new index using Index::new().
    2. Insert entries using .insert(id, text), where id is your unique identifier and text is the string to be indexed.
    3. Execute searches using .search(query), which returns a list of results containing the original id and a similarity score.
    use simsearch::Index;
    
    let mut engine: Index<u32> = Index::new();
    
    engine.insert(1, "Things Fall Apart");
    engine.insert(2, "The Old Man and the Sea");
    engine.insert(3, "James Joyce");
    
    let results = engine.search("thngs");
    
    assert_eq!(results[0].id, 1);
    assert!(results[0].score > 0.0);
  2. Configure the Index with Options

    main

    Use Index::with_options(options) to customize search behavior. The Options struct uses a builder pattern.

    Available configuration methods:

    • limit(usize): Sets the maximum number of results returned (default: 10).
    • prefix_search(bool): Enables/disables matching the last query token as a prefix (default: true).
    • typo_tolerance(bool): Enables/disables Jaro-Winkler similarity for typo tolerance (default: true).
    • case_sensitive(bool): Sets whether searches are case sensitive (default: false).
    • separators(I): Adds additional characters to be treated as token separators alongside whitespace.
    use simsearch::{Index, Options};
    
    let options = Options::new()
        .limit(20)
        .case_sensitive(true)
        .separators(['/', '\', '.']);
    
    let mut engine = Index::with_options(options);
  3. Remove or clear entries from the Index

    main

    To manage the lifecycle of indexed data:

    • remove(&id): Removes the entry associated with the specific ID.
    • clear(): Removes all entries and resets the internal ID counter.
    // Remove a specific item
    engine.remove(&1);
    
    // Wipe the entire index
    engine.clear();
  4. Search the Index and handle Hit results

    main

    The search(pattern) method returns a Vec<Hit<Id>> sorted by relevance.

    Each Hit<Id> contains:

    • id: The original identifier associated with the match.
    • score: A normalized relevance score in the 0.0..=1.0 range. Scores are relative; they are useful for comparing results within the same search query.
    let results = engine.search("martin");
    for hit in results {
        println!("ID: {:?}, Score: {}", hit.id, hit.score);
    }
  5. Insert searchable content into the Index

    main

    You can add data to the index using two primary methods:

    1. insert(id, content): Tokenizes a single string. By default, whitespace characters are separators.
    2. insert_parts(id, parts): Tokenizes multiple string parts (e.g., title, author, tags) and treats them as a single searchable entry for the given ID. This is useful for multi-field search.

    Note: The ID itself is not searchable. If you want the ID to be part of the search results, include it in the content string. Inserting an existing ID will update its content.

    use simsearch::Index;
    
    let mut engine: Index<&str> = Index::new();
    
    // Single content insertion
    engine.insert("item1", "A Game of Thrones");
    
    // Multiple parts insertion (e.g., title and author)
    engine.insert_parts("item2", [
        "A Game of Thrones",
        "George R. R. Martin",
        "fantasy",
    ]);
  6. Initialize and use the Index engine

    main

    The Index<Id> is an in-memory fuzzy search engine. It allows you to map unique identifiers (Id) to searchable string content. You can create an index using default settings or provide custom Options.

    use simsearch::Index;
    
    // Create an index with default options
    let mut engine: Index<u32> = Index::new();
    
    // Insert data
    engine.insert(1, "Things Fall Apart");
    engine.insert(2, "The Old Man and the Sea");
    
    // Perform a fuzzy search
    let results = engine.search("thngs");
    
    // Access results
    if let Some(hit) = results.first() {
        assert_eq!(hit.id, 1);
        println!("Found {} with score {}", hit.id, hit.score);
    }