@@ -860,8 +860,10 @@ impl Collector for QuickwitCollector {
860
860
}
861
861
}
862
862
863
- fn map_error ( err : postcard:: Error ) -> TantivyError {
864
- TantivyError :: InternalError ( format ! ( "merge result Postcard error: {err}" ) )
863
+ fn map_error ( error : postcard:: Error ) -> TantivyError {
864
+ TantivyError :: InternalError ( format ! (
865
+ "failed to merge intermediate aggregation results: Postcard error: {error}"
866
+ ) )
865
867
}
866
868
867
869
/// Merges a set of Leaf Results.
@@ -883,24 +885,26 @@ fn merge_intermediate_aggregation_result<'a>(
883
885
Some ( serialized)
884
886
}
885
887
Some ( QuickwitAggregations :: TantivyAggregations ( _) ) => {
886
- let fruits: Vec < IntermediateAggregationResults > = intermediate_aggregation_results
887
- . map ( |intermediate_aggregation_result| {
888
- postcard:: from_bytes ( intermediate_aggregation_result) . map_err ( map_error)
889
- } )
890
- . collect :: < Result < _ , _ > > ( ) ?;
891
-
892
- let mut fruit_iter = fruits. into_iter ( ) ;
893
- if let Some ( first_fruit) = fruit_iter. next ( ) {
894
- let mut merged_fruit = first_fruit;
895
- for fruit in fruit_iter {
896
- merged_fruit. merge_fruits ( fruit) ?;
897
- }
898
- let serialized = postcard:: to_allocvec ( & merged_fruit) . map_err ( map_error) ?;
899
-
900
- Some ( serialized)
901
- } else {
902
- None
903
- }
888
+ let merged_opt = intermediate_aggregation_results
889
+ . map ( |bytes| postcard:: from_bytes ( bytes) . map_err ( map_error) )
890
+ . try_fold :: < _ , _ , Result < _ , TantivyError > > (
891
+ None ,
892
+ |acc : Option < IntermediateAggregationResults > , fruits_res| {
893
+ let fruits = fruits_res?;
894
+ match acc {
895
+ Some ( mut merged_fruits) => {
896
+ merged_fruits. merge_fruits ( fruits) ?;
897
+ Ok ( Some ( merged_fruits) )
898
+ }
899
+ None => Ok ( Some ( fruits) ) ,
900
+ }
901
+ } ,
902
+ ) ?;
903
+ let serialized = match merged_opt {
904
+ Some ( fruit) => postcard:: to_allocvec ( & fruit) . map_err ( map_error) ?,
905
+ None => Vec :: new ( ) ,
906
+ } ;
907
+ Some ( serialized)
904
908
}
905
909
None => None ,
906
910
} ;
@@ -1293,10 +1297,12 @@ mod tests {
1293
1297
SortOrder , SortValue , SplitSearchError ,
1294
1298
} ;
1295
1299
use tantivy:: TantivyDocument ;
1300
+ use tantivy:: aggregation:: agg_req:: Aggregations ;
1296
1301
use tantivy:: collector:: Collector ;
1297
1302
1298
1303
use super :: { IncrementalCollector , make_merge_collector} ;
1299
- use crate :: collector:: top_k_partial_hits;
1304
+ use crate :: QuickwitAggregations ;
1305
+ use crate :: collector:: { merge_intermediate_aggregation_result, top_k_partial_hits} ;
1300
1306
1301
1307
#[ test]
1302
1308
fn test_merge_partial_hits_no_tie ( ) {
@@ -2002,4 +2008,21 @@ mod tests {
2002
2008
) ;
2003
2009
// TODO would be nice to test aggregation too.
2004
2010
}
2011
+
2012
+ #[ test]
2013
+ fn test_merge_empty_intermediate_aggregation_result ( ) {
2014
+ let merged = merge_intermediate_aggregation_result ( & None , std:: iter:: empty ( ) ) . unwrap ( ) ;
2015
+ assert ! ( merged. is_none( ) ) ;
2016
+
2017
+ let aggregations_json = r#"{
2018
+ "avg_price": { "avg": { "field": "price" } }
2019
+ }"# ;
2020
+ let tantivy_aggregations: Aggregations = serde_json:: from_str ( aggregations_json) . unwrap ( ) ;
2021
+ let quickwit_aggregations = QuickwitAggregations :: TantivyAggregations ( tantivy_aggregations) ;
2022
+ let merged =
2023
+ merge_intermediate_aggregation_result ( & Some ( quickwit_aggregations) , std:: iter:: empty ( ) )
2024
+ . unwrap ( )
2025
+ . unwrap ( ) ;
2026
+ assert ! ( merged. is_empty( ) ) ;
2027
+ }
2005
2028
}
0 commit comments