コレクション( Vec 、 HashMap 、 BTreeMapなど)の簡単なインメモリ検索とキー価値ストア。オートコンプリートとファジーマッチングを特徴とします。
さびに利用できる多くの信じられないほどの検索エンジンがあります。多くは、個別のサーバーバイナリをコンパイルする必要があるようです。私はシンプルで軽量なものが欲しかった - 自分のバイナリ内で構造体とコレクションを便利に検索できる使いやすいクレート。それで、私はindiciumを作りました。
indicium Webアプリを念頭に置いて作られていますが、それはメモリ内検索であり、無期限にもクラウドサイズ(つまりFacebookまたはGoogleサイズ)にスケーリングしません。このような環境でさえ、それはまだ大きなリスト(通貨、言語、国など)を検索するのに便利な方法です。また、予想される尺度制限があるアプリケーションにも最適です(つまり、企業資産のリスト、企業イントラネットのユーザーのリストなど)
Indiciumは、RustのBreemapのおかげで汗をかくことなく、何百万ものレコードを簡単に処理できます。このクレートは、主に利用可能なメモリによって制限されています。ただし、データセットの性質に応じて、何度も繰り返されるキーワードがある場合、パフォーマンスは時点で劣化し始める可能性があります。
プロジェクトの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 (または他の複雑なタイプ)に数値、数値識別子、列挙、およびその他のタイプを作成できることを忘れないでください。
既存のコレクションをインデックス化するために、コレクションを繰り返すことができます。各レコードについて、検索インデックスに挿入します。これは、これらの2つの例のように見えるはずです:
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をインデックス化します。ただし、大規模なコレクションに適した方法は、コレクションに挿入するときにSearchIndexにinsertことです(VEC、Hashmapなど)
ターゲットコレクション( 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" ]
) ;この木枠は受動的に維持されています。私の意見では、この木枠はそれが期待されていることを行い、かなりうまくやっています。頻繁な更新は予想されていません。