簡單的內存搜索集合( Vec , HashMap , BTreeMap等)和鑰匙值商店。功能自動完成和模糊匹配。
Rust有許多令人難以置信的搜索引擎。許多似乎需要編譯單獨的服務器二進製文件。我想要一些簡單且輕巧的東西 - 一種易於使用的板條箱,可以方便地搜索我自己的二進制中的結構和收藏。所以,我做了indicium 。
考慮到Web應用程序的indicium ,這是一種內存搜索,並且不會無限地擴展到雲大小(即Facebook或Google大小)。即使在這樣的環境中,它仍然是搜索大量列表(例如貨幣,語言,國家等)的便捷方法。對於有預期的規模限制的應用程序也非常有用(即搜索公司資產列表,公司Interanet中的用戶列表,等等)
由於Rust的Btreemap,很容易處理數百萬張唱片而不會破壞汗水。該板條箱主要受可用內存的限制。但是,根據您的數據集的性質以及多次重複的關鍵字,在某個時候,性能可能會開始降級。
配置項目貨物中的依賴項: Cargo.toml文件:
[ dependencies ]
indicium = " 0.6 "發行說明可在GitHub上找到。
完整的更改日誌可在GitHub上獲得。
對於我們的快速啟動指南示例,我們將在以下struct內進行搜索:
struct MyStruct {
title : String ,
year : u16 ,
body : String ,
} 首先,我們必須使我們的記錄索引。我們將通過為我們的struct實現Indexable特徵來做到這一點。這個想法是返回我們希望被索引的每個字段的String 。例子:
use indicium :: simple :: Indexable ;
impl Indexable for MyStruct {
fn strings ( & self ) -> Vec < String > {
vec ! [
self .title.clone ( ) ,
self .year.to_string ( ) ,
self .body.clone ( ) ,
]
}
}不要忘記,您可以通過將它們轉換為String並將其包含在返回的Vec<String>中,可以在struct (或其他復雜類型)中製作數字,數字標識符,枚舉和其他類型。
要索引現有的集合,我們可以迭代集合。對於每個記錄,我們將其將其插入搜索索引中。這應該看起來像這兩個示例:
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 )
) ; 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 )
) ;只要為您的價值類型實現Indexable性狀,上述示例就會索引先前填充的Vec或HashMap 。但是,大型集合的首選方法是將您插入集合(VEC,HashMap等)時insert SearchIndex index中。
建議包裝您的目標集合(您的Vec , HashMap等),並將此SearchIndex一起使用新的struct類型。然後,實現insert , replace , remove等。該新struct類型的方法將同時更新集合和搜索索引。這將確保您的收集和索引始終同步。
索引填充後,您可以使用search和autocomplete方法。
search方法將在搜索結果中返回密鑰。然後,每個結果鍵可用於從其集合中檢索完整記錄。
基本用法:
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 ] ) ;
// Demonstrating fuzzy matching:
let resulting_keys : Vec < & usize > = search_index . search ( "Harry" ) ;
assert_eq ! ( resulting_keys, vec! [ & 0 ] ) ;搜索僅支持確切的關鍵字匹配。對於Live搜索,模糊匹配僅應用於最後一個關鍵字。考慮為用戶提供autocomplete功能,作為模糊匹配的符合人體工程學的替代方案。
autocomplete方法將為所提供的字符串中的最後一個關鍵字提供幾個自動完成選項。
基本用法:
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" ]
) ;
// Demonstrating fuzzy matching:
let autocomplete_options : Vec < String > =
search_index . autocomplete ( "a very big birf" ) ;
assert_eq ! (
autocomplete_options,
vec! [ "a very big bird" , "a very big birthday" ]
) ;該板條箱被動地維護。在我看來,這個板條箱做了它的期望,並且做得很好。頻繁的更新不會預期。