forked from quickwit-oss/tantivy
-
Notifications
You must be signed in to change notification settings - Fork 10
feat: implemented filter aggregation #67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 42 commits
Commits
Show all changes
56 commits
Select commit
Hold shift + click to select a range
e3012b7
Initial impl
mdashti 1e0346a
Added `Filter` impl in `build_single_agg_segment_collector_with_reade…
mdashti 80dd75e
Added `Filter(FilterBucketResult)` + Made tests work.
mdashti a77343a
Fixed type issues.
mdashti 7c93dd1
Fixed a test.
mdashti 1cf56c0
8a7a73a: Pass `segment_reader`
mdashti 499d753
Added more tests.
mdashti 15baaa7
Improved parsing + tests
mdashti be46f6e
refactoring
mdashti 953b419
Added more tests.
mdashti 71edc1d
refactoring: moved parsing code under QueryParser
mdashti bca4a6b
Use Tantivy syntax instead of ES
mdashti f1e2e6b
Added a sanity check test.
mdashti 5f7d714
Simplified impl + tests
mdashti 49585c8
Added back tests in a more maintable way
mdashti aa6296d
nitz.
mdashti d534d72
nitz
mdashti 725c829
implemented very simple fast-path
mdashti 9ce3425
improved a comment
mdashti 22950df
implemented fast field support
mdashti bf3d3f6
Used `BoundsRange`
mdashti 621933a
Improved fast field impl + tests
mdashti a82877e
Simplified execution.
mdashti 22735f9
Fixed exports + nitz
mdashti 622c9c5
Improved the tests to check to the expected result.
mdashti 564ee32
Improved test by checking the whole result JSON
mdashti c6cb527
Removed brittle perf checks.
mdashti d249699
Added efficiency verification tests.
mdashti cb5cce3
Added one more efficiency check test.
mdashti 420c9d1
Improved the efficiency tests.
mdashti fecbe98
Removed unnecessary parsing code + added direct Query obj
mdashti 410d091
Fixed tests.
mdashti 767ec67
Improved tests
mdashti 576fd4f
Fixed code structure
mdashti 7aeba9e
Merge branch 'main' into paradedb-current-main/filter-impl
mdashti b19ede5
Fixed lint issues
mdashti a3712c1
nitz.
mdashti 271e5e1
nitz
mdashti 1ac2c6f
nitz.
mdashti c15cfa5
nitz.
mdashti 567ca87
nitz.
mdashti 4deca43
Added an example
mdashti dc100d3
Fixed PR comments.
mdashti c973235
Applied PR comments + nitz
mdashti 2f550d8
nitz.
mdashti 319d2b3
Improved the code.
mdashti 04eb526
Fixed a perf issue.
mdashti c8accb6
Added batch processing.
mdashti 0b84fb2
Made the example more interesting
mdashti 2c69c15
Fixed bucket count
mdashti b75a477
Renamed Direct to CustomQuery
mdashti 807b7de
Fixed lint issues.
mdashti b6305e9
No need for scorer to be an `Option`
mdashti 5660916
nitz
mdashti 5faf5e1
Used BitSet
mdashti fa374da
Added an optimization for AllQuery
mdashti File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| // # Filter Aggregation Example | ||
| // | ||
| // This example demonstrates filter aggregations - creating buckets of documents | ||
| // matching specific queries, with nested aggregations computed on each bucket. | ||
| // | ||
| // Filter aggregations are useful for computing metrics on different subsets of | ||
| // your data in a single query, like "average price overall + average price for | ||
| // electronics + count of in-stock items". | ||
|
|
||
| use serde_json::json; | ||
| use tantivy::aggregation::agg_req::Aggregations; | ||
| use tantivy::aggregation::AggregationCollector; | ||
| use tantivy::query::AllQuery; | ||
| use tantivy::schema::{Schema, FAST, INDEXED, TEXT}; | ||
| use tantivy::{doc, Index}; | ||
|
|
||
| fn main() -> tantivy::Result<()> { | ||
| // Create a simple product schema | ||
| let mut schema_builder = Schema::builder(); | ||
| schema_builder.add_text_field("category", TEXT | FAST); | ||
| schema_builder.add_text_field("brand", TEXT | FAST); | ||
| schema_builder.add_u64_field("price", FAST); | ||
| schema_builder.add_f64_field("rating", FAST); | ||
| schema_builder.add_bool_field("in_stock", FAST | INDEXED); | ||
| let schema = schema_builder.build(); | ||
|
|
||
| // Create index and add sample products | ||
| let index = Index::create_in_ram(schema.clone()); | ||
| let mut writer = index.writer(50_000_000)?; | ||
|
|
||
| writer.add_document(doc!( | ||
| schema.get_field("category")? => "electronics", | ||
| schema.get_field("brand")? => "apple", | ||
| schema.get_field("price")? => 999u64, | ||
| schema.get_field("rating")? => 4.5f64, | ||
| schema.get_field("in_stock")? => true | ||
| ))?; | ||
| writer.add_document(doc!( | ||
| schema.get_field("category")? => "electronics", | ||
| schema.get_field("brand")? => "samsung", | ||
| schema.get_field("price")? => 799u64, | ||
| schema.get_field("rating")? => 4.2f64, | ||
| schema.get_field("in_stock")? => true | ||
| ))?; | ||
| writer.add_document(doc!( | ||
| schema.get_field("category")? => "clothing", | ||
| schema.get_field("brand")? => "nike", | ||
| schema.get_field("price")? => 120u64, | ||
| schema.get_field("rating")? => 4.1f64, | ||
| schema.get_field("in_stock")? => false | ||
| ))?; | ||
| writer.add_document(doc!( | ||
| schema.get_field("category")? => "books", | ||
| schema.get_field("brand")? => "penguin", | ||
| schema.get_field("price")? => 25u64, | ||
| schema.get_field("rating")? => 4.8f64, | ||
| schema.get_field("in_stock")? => true | ||
| ))?; | ||
|
|
||
| writer.commit()?; | ||
|
|
||
| let reader = index.reader()?; | ||
| let searcher = reader.searcher(); | ||
|
|
||
| // Example 1: Basic filter with metric aggregation | ||
| println!("=== Example 1: Electronics average price ==="); | ||
| let agg_req = json!({ | ||
| "electronics": { | ||
| "filter": "category:electronics", | ||
| "aggs": { | ||
| "avg_price": { "avg": { "field": "price" } } | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| let agg: Aggregations = serde_json::from_value(agg_req)?; | ||
| let collector = AggregationCollector::from_aggs(agg, Default::default()); | ||
| let result = searcher.search(&AllQuery, &collector)?; | ||
| println!("{}\n", serde_json::to_string_pretty(&result)?); | ||
|
|
||
| // Example 2: Multiple independent filters | ||
| println!("=== Example 2: Multiple filters in one query ==="); | ||
| let agg_req = json!({ | ||
| "electronics": { | ||
| "filter": "category:electronics", | ||
| "aggs": { "avg_price": { "avg": { "field": "price" } } } | ||
| }, | ||
| "in_stock": { | ||
| "filter": "in_stock:true", | ||
| "aggs": { "count": { "value_count": { "field": "brand" } } } | ||
| }, | ||
| "high_rated": { | ||
| "filter": "rating:[4.5 TO *]", | ||
| "aggs": { "count": { "value_count": { "field": "brand" } } } | ||
| } | ||
| }); | ||
|
|
||
| let agg: Aggregations = serde_json::from_value(agg_req)?; | ||
| let collector = AggregationCollector::from_aggs(agg, Default::default()); | ||
| let result = searcher.search(&AllQuery, &collector)?; | ||
| println!("{}\n", serde_json::to_string_pretty(&result)?); | ||
|
|
||
| // Example 3: Nested filters | ||
| println!("=== Example 3: Nested filters ==="); | ||
| let agg_req = json!({ | ||
| "all_products": { | ||
| "filter": "*", | ||
| "aggs": { | ||
| "electronics": { | ||
| "filter": "category:electronics", | ||
| "aggs": { | ||
| "expensive": { | ||
| "filter": "price:[800 TO *]", | ||
| "aggs": { | ||
| "avg_rating": { "avg": { "field": "rating" } } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| let agg: Aggregations = serde_json::from_value(agg_req)?; | ||
| let collector = AggregationCollector::from_aggs(agg, Default::default()); | ||
| let result = searcher.search(&AllQuery, &collector)?; | ||
| println!("{}\n", serde_json::to_string_pretty(&result)?); | ||
|
|
||
| // Example 4: Filter with sub-aggregation (terms) | ||
| println!("=== Example 4: Filter with terms sub-aggregation ==="); | ||
| let agg_req = json!({ | ||
| "electronics": { | ||
| "filter": "category:electronics", | ||
| "aggs": { | ||
| "by_brand": { | ||
| "terms": { "field": "brand" }, | ||
| "aggs": { | ||
| "avg_price": { "avg": { "field": "price" } } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| let agg: Aggregations = serde_json::from_value(agg_req)?; | ||
| let collector = AggregationCollector::from_aggs(agg, Default::default()); | ||
| let result = searcher.search(&AllQuery, &collector)?; | ||
| println!("{}", serde_json::to_string_pretty(&result)?); | ||
|
|
||
| Ok(()) | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.