All Projects → leontoeides → indicium

leontoeides / indicium

Licence: Apache-2.0 license
🔎 A simple in-memory search for collections and key-value stores.

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to indicium

bootstrap-5-autocomplete
autocomplete/typeahead js plugin for bootstrap v5
Stars: ✭ 79 (+92.68%)
Mutual labels:  autocomplete, typeahead
React Input Enhancements
Set of enhancements for input control
Stars: ✭ 1,375 (+3253.66%)
Mutual labels:  autocomplete, typeahead
Bootstrap 4 Autocomplete
A simple autocomplete/typeahead for Bootstrap 4 and jQuery
Stars: ✭ 36 (-12.2%)
Mutual labels:  autocomplete, typeahead
Zsh Autocomplete
🤖 Real-time type-ahead completion for Zsh. Asynchronous find-as-you-type autocompletion.
Stars: ✭ 641 (+1463.41%)
Mutual labels:  autocomplete, typeahead
Ng Select
⭐ Native angular select component
Stars: ✭ 2,781 (+6682.93%)
Mutual labels:  autocomplete, typeahead
React Autosuggest
WAI-ARIA compliant React autosuggest component
Stars: ✭ 5,773 (+13980.49%)
Mutual labels:  autocomplete, typeahead
Completely
Java autocomplete library.
Stars: ✭ 90 (+119.51%)
Mutual labels:  autocomplete, text
Svelte Select
A select component for Svelte apps
Stars: ✭ 414 (+909.76%)
Mutual labels:  autocomplete, typeahead
Autosuggest Highlight
Utilities for highlighting text in autosuggest and autocomplete components
Stars: ✭ 176 (+329.27%)
Mutual labels:  autocomplete, typeahead
React Autowhatever
Accessible rendering layer for Autosuggest and Autocomplete components
Stars: ✭ 146 (+256.1%)
Mutual labels:  autocomplete, typeahead
Jquery Typeahead
Javascript Typeahead (autocomplete) plugin with more than 50 options and callbacks.
Stars: ✭ 527 (+1185.37%)
Mutual labels:  autocomplete, typeahead
react-native-autocomplete-dropdown
Dropdown Item picker with search and autocomplete (typeahead) functionality for react native
Stars: ✭ 87 (+112.2%)
Mutual labels:  autocomplete, typeahead
Vue Autosuggest
🔍 Vue autosuggest component.
Stars: ✭ 492 (+1100%)
Mutual labels:  autocomplete, typeahead
Autosuggest Trie
Minimalistic trie implementation for autosuggest and autocomplete components
Stars: ✭ 22 (-46.34%)
Mutual labels:  autocomplete, typeahead
Accessible Autocomplete
An autocomplete component, built to be accessible.
Stars: ✭ 474 (+1056.1%)
Mutual labels:  autocomplete, typeahead
Autocomplete
🔮 Fast and full-featured autocomplete library
Stars: ✭ 1,268 (+2992.68%)
Mutual labels:  autocomplete, typeahead
autocompletex
redis autocomplete for elixir
Stars: ✭ 22 (-46.34%)
Mutual labels:  autocomplete, typeahead
Autocomplete
Accessible autocomplete component for vanilla JavaScript and Vue.
Stars: ✭ 277 (+575.61%)
Mutual labels:  autocomplete, typeahead
React Autocomplete Hint
A React component for Autocomplete Hint.
Stars: ✭ 131 (+219.51%)
Mutual labels:  autocomplete, typeahead
Autocomplete
Blazing fast and lightweight autocomplete widget without dependencies. Only 1KB gzipped. Demo:
Stars: ✭ 244 (+495.12%)
Mutual labels:  autocomplete, typeahead

Indicium Search

🔎 A simple in-memory search for collections (Vec, HashMap, BTreeMap, etc) and key-value stores. Features autocompletion.

There are many incredible search engines available for Rust. Many seem to require compiling a separate server binary. I wanted something simple and light-weight - an easy-to-use crate that could conveniently search structs and collections within my own binary. So, I made indicium.

alt text

While indicium was made with web apps in mind, it is an in-memory search and it does not scale indefinitely or to cloud size (i.e. Facebook or Google size). Even in such an environment, it would still be a convenient way of searching large lists (such as currencies, languages, countries, etc.) It's also great for applications where there is an anticipated scale limit (i.e. searching a list of company assets, list of users in a corporate intranet, etc.)

Indicium easily can handle millions of records without breaking a sweat thanks to Rust's BTreeMap. This crate is primarily limited by available memory. However, depending on the nature your data-set and if there keywords that are repeated many times, performance may begin to degrade at a point.

What's New?

  • 0.5.0: Performance improvements. Some functions will now return an Iterator rather than return a Vec to help improve efficiency. Breaking change, bumping version to 0.5.

  • 0.4.2: Any type that implements ToString (and consequently any type that implements Display) now gets the Indexable implementation for free.

  • 0.4.1: Improved contextual fuzzy matching.

  • 0.4.0: Initial support for fuzzy searching. Fuzzy matching is applied to the last (partial) keyword in the search string for autocompletion and live search only. Keywords at the start or in the middle of the user's search string will not be substituted.

    • Some changes for an upcoming 0.5.0 release are being considered. This release could have some changes that would allow indicium to provide feedback to the user, including which keywords have been substituted.
  • 0.4.0: Breaking changes:

    • Builder pattern is now passed owned values.
    • K key type requires Hash trait for fuzzy string search feature.
    • New SearchIndex default settings.
  • 0.4.0: Any dependent software should see if (or how) the updated defaults change search behaviour and tweak accordingly before adopting the 0.4.0 update.

  • 0.3.7: An experimental feature is now disabled by default to reduce resource consumption.

  • 0.3.6: Implemented DerefMut which gives access to the search index's underlying BTreeMap. Implemented clear() which is a convenience method for clearing the search index.

  • 0.3.5: Peformance improvements.

  • 0.3.4: Peformance improvements.

  • 0.3.3: Fix: cargo test failed. Sorry.

  • 0.3.2: Fix: issue with search indexes that do not use keyword splitting.

  • 0.3.1: Autocomplete no longer offers previously used keywords as options.

  • 0.3.1: Added maximum_keys_per_keyword getter method.

  • 0.3.1: Added autocomplete_with and search_with methods which allow ad-hoc overrides of the AutocompleteType/SearchType and maximum results parameters.

  • 0.3.0: Added new search type SearchType::Live which is for "search as you type" interfaces. It is sort of a hybrid between autocomplete and SearchType::And. It will search using an (incomplete) string and return keys as the search results. Each resulting key can then be used to retrieve the full record from its collection to be rendered & displayed to the user.

Quick Start Guide

For our Quick Start Guide example, we will be searching inside of the following struct:

struct MyStruct {
    title: String,
    year: u16,
    body: String,
}

1. Implementing Indexable

To begin, we must make our record indexable. We'll do this by implementing the Indexable trait for our struct. The idea is to return a String for every field that we would like to be indexed. Example:

use indicium::simple::Indexable;

impl Indexable for MyStruct {
    fn strings(&self) -> Vec<String> {
        vec![
            self.title.clone(),
            self.year.to_string(),
            self.body.clone(),
        ]
    }
}

Don't forget that you may make numbers, numeric identifiers, enums, and other types in your struct (or other complex type) indexable by converting them to a String and including them in the returned Vec<String>.

2. Indexing a Collection

To index an existing collection, we can iterate over the collection. For each record, we will insert it into the search index. This should look something like these two examples:

Vec

use indicium::simple::SearchIndex;

let my_vec: Vec<MyStruct> = Vec::new();

// In the case of a `Vec` collection, we use the index as our key. A
// `Vec` index is a `usize` type. Therefore we will instantiate
// `SearchIndex` as `SearchIndex<usize>`.

let mut search_index: SearchIndex<usize> = SearchIndex::default();

my_vec
    .iter()
    .enumerate()
    .for_each(|(index, element)|
        search_index.insert(&index, element)
    );

HashMap

use std::collections::HashMap;
use indicium::simple::SearchIndex;

let my_hash_map: HashMap<String, MyStruct> = HashMap::new();

// In the case of a `HashMap` collection, we use the hash map's key as
// the `SearchIndex` key. In our hypothetical example, we will use
// MyStruct's `title` as a the key which is a `String` type. Therefore
// we will instantiate `HashMap<K, V>` as HashMap<String, MyStruct> and
// `SearchIndex<K>` as `SearchIndex<String>`.

let mut search_index: SearchIndex<String> = SearchIndex::default();

my_hash_map
    .iter()
    .for_each(|(key, value)|
        search_index.insert(key, value)
    );

As long as the Indexable trait was implemented for your value type, the above examples will index a previously populated Vec or HashMap. However, the preferred method for large collections is to insert into the SearchIndex as you insert into your collection (Vec, HashMap, etc.)

Once the index has been populated, you can use the search and autocomplete methods.

3. Searching

The search method will return keys as the search results. Each resulting key can then be used to retrieve the full record from its collection.

Basic usage:

let mut search_index: SearchIndex<usize> = SearchIndex::default();

search_index.insert(&0, &"Harold Godwinson");
search_index.insert(&1, &"Edgar Ætheling");
search_index.insert(&2, &"William the Conqueror");
search_index.insert(&3, &"William Rufus");
search_index.insert(&4, &"Henry Beauclerc");

let resulting_keys: Vec<&usize> = search_index.search("William");

assert_eq!(resulting_keys, vec![&2, &3]);

Search only supports exact keyword matches and does not use fuzzy matching. Consider providing the autocomplete feature to your users as an ergonomic alternative to fuzzy matching.

5. Autocompletion

The autocomplete method will provide several autocompletion options for the last keyword in the supplied string.

Basic usage:

let mut search_index: SearchIndex<usize> =
    SearchIndexBuilder::default()
        .autocomplete_type(&AutocompleteType::Global)
        .build();

search_index.insert(&0, &"apple");
search_index.insert(&1, &"ball");
search_index.insert(&3, &"bird");
search_index.insert(&4, &"birthday");
search_index.insert(&5, &"red");

let autocomplete_options: Vec<String> =
    search_index.autocomplete("a very big bi");

assert_eq!(
    autocomplete_options,
    vec!["a very big bird", "a very big birthday"]
);
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].