Struct tantivy::collector::FacetCollector
source · pub struct FacetCollector { /* private fields */ }
Expand description
Collector for faceting
The collector collects all facets. You need to configure it beforehand with the facet you want to extract.
This is done by calling .add_facet(...)
with the root of the
facet you want to extract as argument.
Facet counts will only be computed for the facet that are direct children of such a root facet.
For instance, if your index represents books, your hierarchy of facets
may contain category
, language
.
The category facet may include subcategories
. For instance, a book
could belong to /category/fiction/fantasy
.
If you request the facet counts for /category
, the result will be
the breakdown of counts for the direct children of /category
(e.g. /category/fiction
, /category/biography
, /category/personal_development
).
Once collection is finished, you can harvest its results in the form
of a FacetCounts
object, and extract your facet counts from it.
This implementation assumes you are working with a number of facets that is many hundreds of times smaller than your number of documents.
use tantivy::collector::FacetCollector;
use tantivy::query::AllQuery;
use tantivy::schema::{Facet, Schema, FacetOptions, TEXT};
use tantivy::{doc, Index};
fn example() -> tantivy::Result<()> {
let mut schema_builder = Schema::builder();
// Facet have their own specific type.
// It is not a bad practise to put all of your
// facet information in the same field.
let facet = schema_builder.add_facet_field("facet", FacetOptions::default());
let title = schema_builder.add_text_field("title", TEXT);
let schema = schema_builder.build();
let index = Index::create_in_ram(schema);
{
let mut index_writer = index.writer(15_000_000)?;
// a document can be associated with any number of facets
index_writer.add_document(doc!(
title => "The Name of the Wind",
facet => Facet::from("/lang/en"),
facet => Facet::from("/category/fiction/fantasy")
))?;
index_writer.add_document(doc!(
title => "Dune",
facet => Facet::from("/lang/en"),
facet => Facet::from("/category/fiction/sci-fi")
))?;
index_writer.add_document(doc!(
title => "La Vénus d'Ille",
facet => Facet::from("/lang/fr"),
facet => Facet::from("/category/fiction/fantasy"),
facet => Facet::from("/category/fiction/horror")
))?;
index_writer.add_document(doc!(
title => "The Diary of a Young Girl",
facet => Facet::from("/lang/en"),
facet => Facet::from("/category/biography")
))?;
index_writer.commit()?;
}
let reader = index.reader()?;
let searcher = reader.searcher();
{
let mut facet_collector = FacetCollector::for_field("facet");
facet_collector.add_facet("/lang");
facet_collector.add_facet("/category");
let facet_counts = searcher.search(&AllQuery, &facet_collector)?;
// This lists all of the facet counts
let facets: Vec<(&Facet, u64)> = facet_counts
.get("/category")
.collect();
assert_eq!(facets, vec![
(&Facet::from("/category/biography"), 1),
(&Facet::from("/category/fiction"), 3)
]);
}
{
let mut facet_collector = FacetCollector::for_field("facet");
facet_collector.add_facet("/category/fiction");
let facet_counts = searcher.search(&AllQuery, &facet_collector)?;
// This lists all of the facet counts
let facets: Vec<(&Facet, u64)> = facet_counts
.get("/category/fiction")
.collect();
assert_eq!(facets, vec![
(&Facet::from("/category/fiction/fantasy"), 2),
(&Facet::from("/category/fiction/horror"), 1),
(&Facet::from("/category/fiction/sci-fi"), 1)
]);
}
{
let mut facet_collector = FacetCollector::for_field("facet");
facet_collector.add_facet("/category/fiction");
let facet_counts = searcher.search(&AllQuery, &facet_collector)?;
// This lists all of the facet counts
let facets: Vec<(&Facet, u64)> = facet_counts.top_k("/category/fiction", 1);
assert_eq!(facets, vec![
(&Facet::from("/category/fiction/fantasy"), 2)
]);
}
{
let mut facet_collector = FacetCollector::for_field("facet");
facet_collector.add_facet("/");
let facet_counts = searcher.search(&AllQuery, &facet_collector)?;
// This lists all of the facet counts
let facets: Vec<(&Facet, u64)> = facet_counts
.get("/")
.collect();
assert_eq!(facets, vec![
(&Facet::from("/category"), 4),
(&Facet::from("/lang"), 4)
]);
}
Ok(())
}
Implementations§
source§impl FacetCollector
impl FacetCollector
sourcepub fn for_field(field_name: impl ToString) -> FacetCollector
pub fn for_field(field_name: impl ToString) -> FacetCollector
Create a facet collector to collect the facets
from a specific facet Field
.
This function does not check whether the field is of the proper type.
sourcepub fn add_facet<T>(&mut self, facet_from: T)
pub fn add_facet<T>(&mut self, facet_from: T)
Adds a facet that we want to record counts
Adding facet Facet::from("/country")
for instance,
will record the counts of all of the direct children of the facet country
(e.g. /country/FR
, /country/UK
).
Adding two facets within which one is the prefix of the other is forbidden.
If you need the correct number of unique documents for two such facets,
just add them in a separate FacetCollector
.
Trait Implementations§
source§impl Collector for FacetCollector
impl Collector for FacetCollector
§type Fruit = FacetCounts
type Fruit = FacetCounts
Fruit
is the type for the result of our collection.
e.g. usize
for the Count
collector.source§fn for_segment(
&self,
_: SegmentOrdinal,
reader: &SegmentReader
) -> Result<FacetSegmentCollector>
fn for_segment( &self, _: SegmentOrdinal, reader: &SegmentReader ) -> Result<FacetSegmentCollector>
set_segment
is called before beginning to enumerate
on this segment.source§fn requires_scoring(&self) -> bool
fn requires_scoring(&self) -> bool
source§fn merge_fruits(
&self,
segments_facet_counts: Vec<FacetCounts>
) -> Result<FacetCounts>
fn merge_fruits( &self, segments_facet_counts: Vec<FacetCounts> ) -> Result<FacetCounts>
source§fn collect_segment(
&self,
weight: &dyn Weight,
segment_ord: u32,
reader: &SegmentReader
) -> Result<<Self::Child as SegmentCollector>::Fruit>
fn collect_segment( &self, weight: &dyn Weight, segment_ord: u32, reader: &SegmentReader ) -> Result<<Self::Child as SegmentCollector>::Fruit>
Auto Trait Implementations§
impl Freeze for FacetCollector
impl RefUnwindSafe for FacetCollector
impl Send for FacetCollector
impl Sync for FacetCollector
impl Unpin for FacetCollector
impl UnwindSafe for FacetCollector
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.