meilisearch/raptor/src/lib.rs

121 lines
3.3 KiB
Rust
Raw Normal View History

#[macro_use] extern crate serde_derive;
2018-04-22 23:34:41 +08:00
extern crate bincode;
2018-04-22 21:54:34 +08:00
extern crate fst;
2018-05-27 21:23:43 +08:00
extern crate group_by;
2018-05-13 18:38:24 +08:00
extern crate levenshtein_automata;
extern crate serde;
2018-04-22 21:54:34 +08:00
2018-05-12 19:28:43 +08:00
pub mod map;
2018-05-27 21:23:43 +08:00
pub mod rank;
2018-05-13 18:38:24 +08:00
mod levenshtein;
2018-04-22 21:54:34 +08:00
2018-06-24 21:10:13 +08:00
use std::path::Path;
use std::fs;
2018-05-12 19:22:07 +08:00
pub use self::map::{Map, MapBuilder, Values};
pub use self::map::{
OpBuilder, IndexedValues,
OpWithStateBuilder, IndexedValuesWithState,
};
2018-05-27 21:23:43 +08:00
pub use self::rank::{RankedStream};
2018-05-13 18:38:24 +08:00
pub use self::levenshtein::LevBuilder;
2018-05-27 17:15:05 +08:00
pub type DocIndexMap = Map<DocIndex>;
pub type DocIndexMapBuilder = MapBuilder<DocIndex>;
2018-05-27 21:23:43 +08:00
pub type DocumentId = u64;
2018-05-27 17:15:05 +08:00
/// This structure represent the position of a word
/// in a document and its attributes.
///
/// This is stored in the map, generated at index time,
/// extracted and interpreted at search time.
#[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct DocIndex {
/// The document identifier where the word was found.
2018-05-27 21:23:43 +08:00
pub document: DocumentId,
2018-05-27 17:15:05 +08:00
/// The attribute identifier in the document
/// where the word was found.
///
/// This is an `u8` therefore a document
/// can not have more than `2^8` attributes.
pub attribute: u8,
/// The index where the word was found in the attribute.
///
/// Only the first 1000 words are indexed.
pub attribute_index: u32,
}
2018-05-27 17:15:05 +08:00
/// This structure represent a matching word with informations
/// on the location of the word in the document.
///
/// The order of the field is important because it defines
/// the way these structures are ordered between themselves.
///
/// The word in itself is not important.
2018-05-27 21:23:43 +08:00
// TODO do data oriented programming ? very arrays ?
2018-05-27 17:15:05 +08:00
#[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct Match {
2018-05-27 21:23:43 +08:00
/// The word index in the query sentence.
/// Same as the `attribute_index` but for the query words.
///
/// Used to retrieve the automaton that match this word.
pub query_index: u32,
2018-05-27 17:15:05 +08:00
/// The distance the word has with the query word
/// (i.e. the Levenshtein distance).
pub distance: u8,
/// The attribute in which the word is located
/// (i.e. Title is 0, Description is 1).
///
/// This is an `u8` therefore a document
/// can not have more than `2^8` attributes.
pub attribute: u8,
2018-05-27 17:15:05 +08:00
/// Where does this word is located in the attribute string
/// (i.e. at the start or the end of the attribute).
///
/// The index in the attribute is limited to a maximum of `2^32`
/// this is because we index only the first 1000 words in an attribute.
pub attribute_index: u32,
/// Whether the word that match is an exact match or a prefix.
pub is_exact: bool,
}
2018-05-27 21:23:43 +08:00
impl Match {
pub fn zero() -> Self {
Match {
query_index: 0,
distance: 0,
attribute: 0,
attribute_index: 0,
is_exact: false,
2018-05-27 21:23:43 +08:00
}
}
pub fn max() -> Self {
Match {
query_index: u32::max_value(),
distance: u8::max_value(),
attribute: u8::max_value(),
attribute_index: u32::max_value(),
is_exact: true,
2018-05-27 21:23:43 +08:00
}
}
}
2018-06-24 21:10:13 +08:00
pub fn load_map<P, Q>(map: P, values: Q) -> fst::Result<DocIndexMap>
where P: AsRef<Path>, Q: AsRef<Path>,
{
let fst = fs::read(map)?;
let values = fs::read(values)?;
DocIndexMap::from_bytes(fst, &values)
}