19个版本 (11个重大更新)
新 0.12.2 | 2024年8月11日 |
---|---|
0.12.1 | 2024年6月21日 |
0.12.0 | 2024年4月12日 |
0.11.1 | 2024年2月28日 |
0.1.0 | 2022年3月22日 |
144 在 文本处理
每月94 次下载
290KB
7.5K SLoC
Tantivy分析
这是一个针对 Tantivy 的 Tokenizer
和 TokenFilters
的集合,旨在复制 Lucene 中的功能。
它依赖于Google的 Rust ICU。为了编译,需要安装 libicu-dev
和 clang。
破坏性单词规则来自 Lucene。
功能
icu
功能包括以下组件(它们也是功能)ICUTokenizer
ICUNormalizer2TokenFilter
ICUTransformTokenFilter
commons
功能包括以下组件LengthTokenFilter
LimitTokenCountFilter
PathTokenizer
ReverseTokenFilter
ElisionTokenFilter
EdgeNgramTokenFilter
phonetic
功能包括一些语音算法(Beider-Morse,Soundex,Metaphone等,请参阅Crate文档)PhoneticTokenFilter
embedded
启用 rphonetic crate 的嵌入式规则。此功能默认不包含。它有两个子功能embedded-bm
,它只启用嵌入式 Beider-Morse 规则,以及embedded-dm
,它只启用 Daitch-Mokotoff 规则。
请注意,语音支持可能需要改进。
默认情况下,包含 icu
、commons
和 phonetic
。
示例
use tantivy::collector::TopDocs;
use tantivy::query::QueryParser;
use tantivy::schema::{IndexRecordOption, SchemaBuilder, TextFieldIndexing, TextOptions, Value};
use tantivy::tokenizer::TextAnalyzer;
use tantivy::{doc, Index, ReloadPolicy, TantivyDocument};
use tantivy_analysis_contrib::icu::{Direction, ICUTokenizer, ICUTransformTokenFilter};
const ANALYSIS_NAME: &str = "test";
fn main() -> Result<(), Box<dyn std::error::Error>> {
let options = TextOptions::default()
.set_indexing_options(
TextFieldIndexing::default()
.set_tokenizer(ANALYSIS_NAME)
.set_index_option(IndexRecordOption::WithFreqsAndPositions),
)
.set_stored();
let mut schema = SchemaBuilder::new();
schema.add_text_field("field", options);
let schema = schema.build();
let transform = ICUTransformTokenFilter::new(
"Any-Latin; NFD; [:Nonspacing Mark:] Remove; Lower; NFC".to_string(),
None,
Direction::Forward,
)?;
let icu_analyzer = TextAnalyzer::builder(ICUTokenizer)
.filter(transform)
.build();
let field = schema.get_field("field").expect("Can't get field.");
let index = Index::create_in_ram(schema);
index.tokenizers().register(ANALYSIS_NAME, icu_analyzer);
let mut index_writer = index.writer(15_000_000)?;
index_writer.add_document(doc!(
field => "中国"
))?;
index_writer.add_document(doc!(
field => "Another Document"
))?;
index_writer.commit()?;
let reader = index
.reader_builder()
.reload_policy(ReloadPolicy::Manual)
.try_into()?;
let searcher = reader.searcher();
let query_parser = QueryParser::for_index(&index, vec![field]);
let query = query_parser.parse_query("zhong")?;
let top_docs = searcher.search(&query, &TopDocs::with_limit(10))?;
let mut result: Vec<String> = Vec::new();
for (_, doc_address) in top_docs {
let retrieved_doc = searcher.doc::<TantivyDocument>(doc_address)?;
result = retrieved_doc
.get_all(field)
.map(|v| v.as_str().unwrap().to_string())
.collect();
}
let expected: Vec<String> = vec!["中国".to_string()];
assert_eq!(expected, result);
let query = query_parser.parse_query("国")?;
let top_docs = searcher.search(&query, &TopDocs::with_limit(10))?;
let mut result: Vec<String> = Vec::new();
for (_, doc_address) in top_docs {
let retrieved_doc = searcher.doc::<TantivyDocument>(doc_address)?;
result = retrieved_doc
.get_all(field)
.map(|v| v.as_str().unwrap().to_string())
.collect();
}
let expected: Vec<String> = vec!["中国".to_string()];
assert_eq!(expected, result);
let query = query_parser.parse_query("document")?;
let top_docs = searcher.search(&query, &TopDocs::with_limit(10))?;
let mut result: Vec<String> = Vec::new();
for (_, doc_address) in top_docs {
let retrieved_doc = searcher.doc::<TantivyDocument>(doc_address)?;
result = retrieved_doc
.get_all(field)
.map(|v| v.as_str().unwrap().to_string())
.collect();
}
let expected: Vec<String> = vec!["Another Document".to_string()];
assert_eq!(expected, result);
Ok(())
}
许可
根据您的选择许可以下之一
- Apache许可证版本2.0(LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT许可证(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
。
贡献
除非您明确声明,否则根据Apache-2.0许可证定义,您有意提交并包含在作品中的任何贡献,均应双授权,且无任何附加条款或条件。
依赖项
~0.6–2.9MB
~56K SLoC