컬렉션 ( Vec , HashMap , BTreeMap 등) 및 키 가치 저장소에 대한 간단한 메모리 검색. 자동 완성 및 퍼지 매칭 기능.
Rust에 사용할 수있는 놀라운 검색 엔진이 많이 있습니다. 많은 사람들이 별도의 서버 바이너리를 컴파일 해야하는 것 같습니다. 나는 간단하고 가벼운 웨이트를 원했습니다. 이진 내에서 스트러크와 컬렉션을 편리하게 검색 할 수있는 사용하기 쉬운 상자입니다. 그래서 나는 indicium 만들었습니다.
indicium 웹 앱을 염두에두고 만들어졌지만 메모리 내 검색이며 무기한 또는 클라우드 크기 (예 : Facebook 또는 Google 크기)로 확장되지 않습니다. 이러한 환경에서도 여전히 대규모 목록 (통화, 언어, 국가 등)을 검색하는 편리한 방법 일 것입니다. 예상되는 스케일 제한이있는 응용 프로그램에도 좋습니다 (즉 회사 자산 목록, 회사 인트라넷의 사용자 목록 등).
Indicium은 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 ( ) ,
]
}
} struct String 변환하고 반환 된 Vec<String> 에 포함시켜 숫자, 숫자 식별자, 열거 및 기타 유형을 색인화 할 수 있다는 것을 잊지 마십시오.
기존 컬렉션을 색인하려면 컬렉션을 반복 할 수 있습니다. 각 레코드에 대해 검색 인덱스에 삽입합니다. 이것은이 두 가지 예처럼 보일 것입니다.
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" ]
) ;이 상자는 수동적으로 유지됩니다. 이 상자는 예상되는 일을 수행하고 제 생각에는 꽤 잘합니다. 빈번한 업데이트는 예상되지 않습니다.