mirror of
https://github.com/quickwit-oss/tantivy.git
synced 2026-01-06 09:12:55 +00:00
@@ -6,6 +6,7 @@ Tantivy 0.14.0
|
||||
- Large API Change in the Directory API. Tantivy used to assume that all files could be somehow memory mapped. After this change, Directory return a `FileSlice` that can be reduced and eventually read into an `OwnedBytes` object. Long and blocking io operation are still required by they do not span over the entire file.
|
||||
- Added support for Brotli compression in the DocStore. (@ppodolsky)
|
||||
- Added helper for building intersections and unions in BooleanQuery (@guilload)
|
||||
- Bugfix in `Query::explain`
|
||||
|
||||
Tantivy 0.13.2
|
||||
===================
|
||||
|
||||
@@ -33,13 +33,11 @@ mod tests {
|
||||
{
|
||||
// writing the segment
|
||||
let mut index_writer = index.writer_for_tests().unwrap();
|
||||
{
|
||||
index_writer.add_document(doc!(text_field => "a b c"));
|
||||
index_writer.add_document(doc!(text_field => "a c"));
|
||||
index_writer.add_document(doc!(text_field => "b c"));
|
||||
index_writer.add_document(doc!(text_field => "a b c d"));
|
||||
index_writer.add_document(doc!(text_field => "d"));
|
||||
}
|
||||
index_writer.add_document(doc!(text_field => "a b c"));
|
||||
index_writer.add_document(doc!(text_field => "a c"));
|
||||
index_writer.add_document(doc!(text_field => "b c"));
|
||||
index_writer.add_document(doc!(text_field => "a b c d"));
|
||||
index_writer.add_document(doc!(text_field => "d"));
|
||||
assert!(index_writer.commit().is_ok());
|
||||
}
|
||||
(index, text_field)
|
||||
@@ -290,4 +288,29 @@ mod tests {
|
||||
assert_nearly_equals!(scores[1], 0.84699446);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_explain() -> crate::Result<()> {
|
||||
let mut schema_builder = Schema::builder();
|
||||
let text = schema_builder.add_text_field("text", STRING);
|
||||
let schema = schema_builder.build();
|
||||
let index = Index::create_in_ram(schema);
|
||||
let mut index_writer = index.writer_with_num_threads(1, 5_000_000)?;
|
||||
index_writer.add_document(doc!(text=>"a"));
|
||||
index_writer.add_document(doc!(text=>"b"));
|
||||
index_writer.commit()?;
|
||||
let searcher = index.reader()?.searcher();
|
||||
let term_a: Box<dyn Query> = Box::new(TermQuery::new(
|
||||
Term::from_field_text(text, "a"),
|
||||
IndexRecordOption::Basic,
|
||||
));
|
||||
let term_b: Box<dyn Query> = Box::new(TermQuery::new(
|
||||
Term::from_field_text(text, "b"),
|
||||
IndexRecordOption::Basic,
|
||||
));
|
||||
let query = BooleanQuery::from(vec![(Occur::Should, term_a), (Occur::Should, term_b)]);
|
||||
let explanation = query.explain(&searcher, DocAddress(0, 0u32))?;
|
||||
assert_nearly_equals!(explanation.value(), 0.6931472f32);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ mod tests {
|
||||
let explanation = query.explain(&searcher, DocAddress(0, 0u32)).unwrap();
|
||||
assert_eq!(
|
||||
explanation.to_pretty_json(),
|
||||
"{\n \"value\": 0.2,\n \"description\": \"Boost x0.2 of ...\",\n \"details\": [\n {\n \"value\": 1.0,\n \"description\": \"AllQuery\"\n }\n ]\n}"
|
||||
"{\n \"value\": 0.2,\n \"description\": \"Boost x0.2 of ...\",\n \"details\": [\n {\n \"value\": 1.0,\n \"description\": \"AllQuery\",\n \"context\": []\n }\n ],\n \"context\": []\n}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ pub struct Explanation {
|
||||
description: String,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||
details: Vec<Explanation>,
|
||||
context: Vec<String>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Explanation {
|
||||
@@ -32,6 +33,7 @@ impl Explanation {
|
||||
value,
|
||||
description: description.to_string(),
|
||||
details: vec![],
|
||||
context: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +49,11 @@ impl Explanation {
|
||||
self.details.push(child_explanation);
|
||||
}
|
||||
|
||||
/// Adds some extra context to the explanation.
|
||||
pub fn add_context(&mut self, context: String) {
|
||||
self.context.push(context);
|
||||
}
|
||||
|
||||
/// Shortcut for `self.details.push(Explanation::new(name, value));`
|
||||
pub fn add_const<T: ToString>(&mut self, name: T, value: Score) {
|
||||
self.details.push(Explanation::new(name, value));
|
||||
|
||||
@@ -9,12 +9,12 @@ pub use self::term_weight::TermWeight;
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use crate::assert_nearly_equals;
|
||||
use crate::collector::TopDocs;
|
||||
use crate::docset::DocSet;
|
||||
use crate::postings::compression::COMPRESSION_BLOCK_SIZE;
|
||||
use crate::query::{Query, QueryParser, Scorer, TermQuery};
|
||||
use crate::schema::{Field, IndexRecordOption, Schema, STRING, TEXT};
|
||||
use crate::{assert_nearly_equals, DocAddress};
|
||||
use crate::{Index, Term, TERMINATED};
|
||||
|
||||
#[test]
|
||||
@@ -179,4 +179,40 @@ mod tests {
|
||||
"TermQuery(Term(field=1,bytes=[104, 101, 108, 108, 111]))"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_term_query_explain() -> crate::Result<()> {
|
||||
let mut schema_builder = Schema::builder();
|
||||
let text_field = schema_builder.add_text_field("text", TEXT);
|
||||
let schema = schema_builder.build();
|
||||
let index = Index::create_in_ram(schema);
|
||||
let mut index_writer = index.writer_for_tests().unwrap();
|
||||
index_writer.add_document(doc!(text_field=>"b"));
|
||||
index_writer.add_document(doc!(text_field=>"a"));
|
||||
index_writer.add_document(doc!(text_field=>"a"));
|
||||
index_writer.add_document(doc!(text_field=>"b"));
|
||||
index_writer.commit()?;
|
||||
let term_a = Term::from_field_text(text_field, "a");
|
||||
let term_query = TermQuery::new(term_a, IndexRecordOption::Basic);
|
||||
let searcher = index.reader()?.searcher();
|
||||
{
|
||||
let explanation = term_query.explain(&searcher, DocAddress(0u32, 1u32))?;
|
||||
assert_nearly_equals!(explanation.value(), 0.6931472f32);
|
||||
}
|
||||
{
|
||||
let explanation_err = term_query.explain(&searcher, DocAddress(0u32, 0u32));
|
||||
assert!(matches!(
|
||||
explanation_err,
|
||||
Err(crate::TantivyError::InvalidArgument(_msg))
|
||||
));
|
||||
}
|
||||
{
|
||||
let explanation_err = term_query.explain(&searcher, DocAddress(0u32, 3u32));
|
||||
assert!(matches!(
|
||||
explanation_err,
|
||||
Err(crate::TantivyError::InvalidArgument(_msg))
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,16 @@ impl Weight for TermWeight {
|
||||
|
||||
fn explain(&self, reader: &SegmentReader, doc: DocId) -> crate::Result<Explanation> {
|
||||
let mut scorer = self.specialized_scorer(reader, 1.0)?;
|
||||
if scorer.seek(doc) != doc {
|
||||
if scorer.doc() > doc || scorer.seek(doc) != doc {
|
||||
return Err(does_not_match(doc));
|
||||
}
|
||||
Ok(scorer.explain())
|
||||
let mut explanation = scorer.explain();
|
||||
explanation.add_context(format!(
|
||||
"Term ={:?}:{:?}",
|
||||
self.term.field(),
|
||||
self.term.value_bytes()
|
||||
));
|
||||
Ok(explanation)
|
||||
}
|
||||
|
||||
fn count(&self, reader: &SegmentReader) -> crate::Result<u32> {
|
||||
|
||||
Reference in New Issue
Block a user