Une bibliothèque de recherche en texte intégral, écrite en rouille, optimisée pour la vitesse d'insertion, qui fournit un contrôle total sur les calculs de notation.
Cela commence initialement comme un port de la bibliothèque de nœuds NDX.
Recette (titre) Recherche avec des documents 50K.
https://quantleaf.github.io/probly-search-demo/
Trois façons de faire un score
ScoreCalculator .Index inversé dynamique basé sur Trie.
Plusieurs champs Indexation et recherche de texte intégral.
Score par champ augmentant.
Tokenizer configurable.
Requêtes de texte libre avec extension de requête.
Allocation rapide, mais suppression latente.
Wasm compatible
Voir les tests d'intégration.
Voir le projet de démonstration de recherche de recettes
Création d'un index avec un document qui a 2 champs. Remettre en question des documents et supprimer un document.
use std :: collections :: HashSet ;
use probly_search :: {
index :: Index ,
query :: {
score :: default :: { bm25 , zero_to_one } ,
QueryResult ,
} ,
} ;
// A white space tokenizer
fn tokenizer ( s : & str ) -> Vec < Cow < str > > {
s . split ( ' ' ) . map ( Cow :: from ) . collect :: < Vec < _ > > ( )
}
// We have to provide extraction functions for the fields we want to index
// Title
fn title_extract ( d : & Doc ) -> Vec < & str > {
vec ! [ d.title.as_str ( ) ]
}
// Description
fn description_extract ( d : & Doc ) -> Vec < & str > {
vec ! [ d.description.as_str ( ) ]
}
// Create index with 2 fields
let mut index = Index :: < usize > :: new ( 2 ) ;
// Create docs from a custom Doc struct
let doc_1 = Doc {
id : 0 ,
title : "abc" . to_string ( ) ,
description : "dfg" . to_string ( ) ,
} ;
let doc_2 = Doc {
id : 1 ,
title : "dfgh" . to_string ( ) ,
description : "abcd" . to_string ( ) ,
} ;
// Add documents to index
index . add_document (
& [ title_extract , description_extract ] ,
tokenizer ,
doc_1 . id ,
& doc_1 ,
) ;
index . add_document (
& [ title_extract , description_extract ] ,
tokenizer ,
doc_2 . id ,
& doc_2 ,
) ;
// Search, expected 2 results
let mut result = index . query (
& "abc" ,
& mut bm25 :: new ( ) ,
tokenizer ,
& [ 1. , 1. ] ,
) ;
assert_eq ! ( result.len ( ) , 2 ) ;
assert_eq ! (
result [ 0 ] ,
QueryResult {
key: 0 ,
score: 0.6931471805599453
}
) ;
assert_eq ! (
result [ 1 ] ,
QueryResult {
key: 1 ,
score: 0.28104699650060755
}
) ;
// Remove documents from index
index . remove_document ( doc_1 . id ) ;
// Vacuum to remove completely
index . vacuum ( ) ;
// Search, expect 1 result
result = index . query (
& "abc" ,
& mut bm25 :: new ( ) ,
tokenizer ,
& [ 1. , 1. ] ,
) ;
assert_eq ! ( result.len ( ) , 1 ) ;
assert_eq ! (
result [ 0 ] ,
QueryResult {
key: 1 ,
score: 0.1166450426074421
}
) ;Passez par les tests source dans l'implémentation BM25 et la mise en œuvre de zéro à un pour plus d'exemples de requête.
Exécutez tous les tests avec
cargo testExécuter tous les benchmarks avec
cargo benchMit