mirror of
https://github.com/quickwit-oss/tantivy.git
synced 2025-12-23 02:29:57 +00:00
130 lines
4.0 KiB
Rust
130 lines
4.0 KiB
Rust
// # Aggregation example
|
|
//
|
|
// This example shows how you can use built-in aggregations.
|
|
// We will use range buckets and compute the average in each bucket.
|
|
//
|
|
|
|
use serde_json::Value;
|
|
use tantivy::aggregation::agg_req::{
|
|
Aggregation, Aggregations, BucketAggregation, BucketAggregationType, MetricAggregation,
|
|
RangeAggregation,
|
|
};
|
|
use tantivy::aggregation::agg_result::AggregationResults;
|
|
use tantivy::aggregation::metric::AverageAggregation;
|
|
use tantivy::aggregation::AggregationCollector;
|
|
use tantivy::query::TermQuery;
|
|
use tantivy::schema::{self, IndexRecordOption, Schema, TextFieldIndexing};
|
|
use tantivy::{doc, Index, Term};
|
|
|
|
fn main() -> tantivy::Result<()> {
|
|
let mut schema_builder = Schema::builder();
|
|
let text_fieldtype = schema::TextOptions::default()
|
|
.set_indexing_options(
|
|
TextFieldIndexing::default().set_index_option(IndexRecordOption::WithFreqs),
|
|
)
|
|
.set_stored();
|
|
let text_field = schema_builder.add_text_field("text", text_fieldtype);
|
|
let score_fieldtype = crate::schema::NumericOptions::default().set_fast();
|
|
let highscore_field = schema_builder.add_f64_field("highscore", score_fieldtype.clone());
|
|
let price_field = schema_builder.add_f64_field("price", score_fieldtype);
|
|
|
|
let schema = schema_builder.build();
|
|
|
|
// # Indexing documents
|
|
//
|
|
// Lets index a bunch of documents for this example.
|
|
let index = Index::create_in_ram(schema);
|
|
|
|
let mut index_writer = index.writer(50_000_000)?;
|
|
// writing the segment
|
|
index_writer.add_document(doc!(
|
|
text_field => "cool",
|
|
highscore_field => 1f64,
|
|
price_field => 0f64,
|
|
))?;
|
|
index_writer.add_document(doc!(
|
|
text_field => "cool",
|
|
highscore_field => 3f64,
|
|
price_field => 1f64,
|
|
))?;
|
|
index_writer.add_document(doc!(
|
|
text_field => "cool",
|
|
highscore_field => 5f64,
|
|
price_field => 1f64,
|
|
))?;
|
|
index_writer.add_document(doc!(
|
|
text_field => "nohit",
|
|
highscore_field => 6f64,
|
|
price_field => 2f64,
|
|
))?;
|
|
index_writer.add_document(doc!(
|
|
text_field => "cool",
|
|
highscore_field => 7f64,
|
|
price_field => 2f64,
|
|
))?;
|
|
index_writer.commit()?;
|
|
index_writer.add_document(doc!(
|
|
text_field => "cool",
|
|
highscore_field => 11f64,
|
|
price_field => 10f64,
|
|
))?;
|
|
index_writer.add_document(doc!(
|
|
text_field => "cool",
|
|
highscore_field => 14f64,
|
|
price_field => 15f64,
|
|
))?;
|
|
|
|
index_writer.add_document(doc!(
|
|
text_field => "cool",
|
|
highscore_field => 15f64,
|
|
price_field => 20f64,
|
|
))?;
|
|
|
|
index_writer.commit()?;
|
|
|
|
let reader = index.reader()?;
|
|
let text_field = reader.searcher().schema().get_field("text").unwrap();
|
|
|
|
let term_query = TermQuery::new(
|
|
Term::from_field_text(text_field, "cool"),
|
|
IndexRecordOption::Basic,
|
|
);
|
|
|
|
let sub_agg_req_1: Aggregations = vec![(
|
|
"average_price".to_string(),
|
|
Aggregation::Metric(MetricAggregation::Average(
|
|
AverageAggregation::from_field_name("price".to_string()),
|
|
)),
|
|
)]
|
|
.into_iter()
|
|
.collect();
|
|
|
|
let agg_req_1: Aggregations = vec![(
|
|
"score_ranges".to_string(),
|
|
Aggregation::Bucket(BucketAggregation {
|
|
bucket_agg: BucketAggregationType::Range(RangeAggregation {
|
|
field: "highscore".to_string(),
|
|
ranges: vec![
|
|
(-1f64..9f64).into(),
|
|
(9f64..14f64).into(),
|
|
(14f64..20f64).into(),
|
|
],
|
|
..Default::default()
|
|
}),
|
|
sub_aggregation: sub_agg_req_1,
|
|
}),
|
|
)]
|
|
.into_iter()
|
|
.collect();
|
|
|
|
let collector = AggregationCollector::from_aggs(agg_req_1, None, index.schema());
|
|
|
|
let searcher = reader.searcher();
|
|
let agg_res: AggregationResults = searcher.search(&term_query, &collector).unwrap();
|
|
|
|
let res: Value = serde_json::to_value(agg_res)?;
|
|
println!("{}", serde_json::to_string_pretty(&res)?);
|
|
|
|
Ok(())
|
|
}
|