Struct tantivy::collector::FacetCollector [] [src]

pub struct FacetCollector { /* fields omitted */ }

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 face t counts from it.

This implementation assumes you are working with a number of facets that is much hundreds of time lower than your number of documents.

#[macro_use]
extern crate tantivy;
use tantivy::schema::{Facet, SchemaBuilder, TEXT};
use tantivy::{Index, Result};
use tantivy::collector::FacetCollector;
use tantivy::query::AllQuery;

fn example() -> Result<()> {
    let mut schema_builder = SchemaBuilder::new();

    // 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");
    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(3_000_000)?;
        // a document can be associated to 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().unwrap();
    }

    index.load_searchers()?;
    let searcher = index.searcher();

    {
        let mut facet_collector = FacetCollector::for_field(facet);
        facet_collector.add_facet("/lang");
        facet_collector.add_facet("/category");
        searcher.search(&AllQuery, &mut facet_collector).unwrap();

        // this object contains count aggregate for all of the facets.
        let counts = facet_collector.harvest();

        // This lists all of the facet counts
        let facets: Vec<(&Facet, u64)> = 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");
        searcher.search(&AllQuery, &mut facet_collector).unwrap();

        // this object contains count aggregate for all of the facets.
        let counts = facet_collector.harvest();

        // This lists all of the facet counts
        let facets: Vec<(&Facet, u64)> = 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");
        searcher.search(&AllQuery, &mut facet_collector).unwrap();

        // this object contains count aggregate for all of the facets.
        let counts = facet_collector.harvest();

        // This lists all of the facet counts
        let facets: Vec<(&Facet, u64)> = counts.top_k("/category/fiction", 1);
        assert_eq!(facets, vec![
            (&Facet::from("/category/fiction/fantasy"), 2)
        ]);
    }

    Ok(())
}

Methods

impl FacetCollector
[src]

[src]

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.

[src]

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 separate FacetCollector.

[src]

Returns the results of the collection.

This method does not just return the counters, it also translates the facet ordinals of the last segment.

Trait Implementations

impl Collector for FacetCollector
[src]

[src]

set_segment is called before beginning to enumerate on this segment. Read more

[src]

The query pushes the scored document to the collector via this method.