2021-06-17 14:24:59 +02:00
use std ::collections ::HashSet ;
use big_s ::S ;
use milli ::update ::Settings ;
2022-08-18 17:36:08 +02:00
use milli ::{ Criterion , Search , SearchResult , TermsMatchingStrategy } ;
2021-06-17 14:24:59 +02:00
use Criterion ::* ;
use crate ::search ::{ self , EXTERNAL_DOCUMENTS_IDS } ;
macro_rules ! test_distinct {
2022-12-07 16:41:23 +01:00
( $func :ident , $distinct :ident , $exhaustive :ident , $limit :expr , $criteria :expr , $n_res :expr ) = > {
2021-06-17 14:24:59 +02:00
#[ test ]
fn $func ( ) {
let criteria = $criteria ;
let index = search ::setup_search_index_with_criteria ( & criteria ) ;
// update distinct attribute
let mut wtxn = index . write_txn ( ) . unwrap ( ) ;
2021-12-08 14:12:07 +01:00
let config = milli ::update ::IndexerConfig ::default ( ) ;
let mut builder = Settings ::new ( & mut wtxn , & index , & config ) ;
2021-06-17 14:24:59 +02:00
builder . set_distinct_field ( S ( stringify! ( $distinct ) ) ) ;
2022-10-05 17:41:07 +02:00
builder . execute ( | _ | ( ) , | | false ) . unwrap ( ) ;
2021-06-17 14:24:59 +02:00
wtxn . commit ( ) . unwrap ( ) ;
2021-06-17 15:19:03 +02:00
let rtxn = index . read_txn ( ) . unwrap ( ) ;
2021-06-17 14:24:59 +02:00
2021-06-17 15:19:03 +02:00
let mut search = Search ::new ( & rtxn , & index ) ;
2021-06-17 14:24:59 +02:00
search . query ( search ::TEST_QUERY ) ;
2022-12-07 16:41:23 +01:00
search . limit ( $limit ) ;
search . exhaustive_number_hits ( $exhaustive ) ;
2023-04-24 12:11:25 +02:00
2022-08-22 17:37:36 +02:00
search . terms_matching_strategy ( TermsMatchingStrategy ::default ( ) ) ;
2021-06-17 14:24:59 +02:00
2022-04-09 14:50:43 +02:00
let SearchResult { documents_ids , candidates , .. } = search . execute ( ) . unwrap ( ) ;
assert_eq! ( candidates . len ( ) , $n_res ) ;
2021-06-17 14:24:59 +02:00
let mut distinct_values = HashSet ::new ( ) ;
2022-08-18 17:36:08 +02:00
let expected_external_ids : Vec < _ > =
2023-04-24 12:11:25 +02:00
search ::expected_order ( & criteria , TermsMatchingStrategy ::default ( ) , & [ ] )
2022-08-18 17:36:08 +02:00
. into_iter ( )
. filter_map ( | d | {
if distinct_values . contains ( & d . $distinct ) {
None
} else {
distinct_values . insert ( d . $distinct . to_owned ( ) ) ;
Some ( d . id )
}
} )
2022-12-07 16:41:23 +01:00
. take ( $limit )
2022-08-18 17:36:08 +02:00
. collect ( ) ;
2021-06-17 14:24:59 +02:00
let documents_ids = search ::internal_to_external_ids ( & index , & documents_ids ) ;
assert_eq! ( documents_ids , expected_external_ids ) ;
}
} ;
}
2022-12-07 16:41:23 +01:00
test_distinct! (
exhaustive_distinct_string_default_criteria ,
tag ,
true ,
1 ,
vec! [ Words , Typo , Proximity , Attribute , Exactness ] ,
3
) ;
test_distinct! (
exhaustive_distinct_number_default_criteria ,
asc_desc_rank ,
true ,
1 ,
vec! [ Words , Typo , Proximity , Attribute , Exactness ] ,
7
) ;
2022-12-13 15:54:43 +01:00
test_distinct! (
exhaustive_distinct_number_weird_order_criteria ,
asc_desc_rank ,
true ,
0 ,
vec! [ Desc ( S ( " attribute_rank " ) ) , Desc ( S ( " exactness_rank " ) ) , Exactness , Typo ] ,
7
) ;
2022-12-07 16:41:23 +01:00
2021-06-17 15:19:03 +02:00
test_distinct! (
distinct_string_default_criteria ,
tag ,
2022-12-07 16:41:23 +01:00
false ,
EXTERNAL_DOCUMENTS_IDS . len ( ) ,
2022-04-09 14:50:43 +02:00
vec! [ Words , Typo , Proximity , Attribute , Exactness ] ,
3
2021-06-17 15:19:03 +02:00
) ;
test_distinct! (
distinct_number_default_criteria ,
asc_desc_rank ,
2022-12-07 16:41:23 +01:00
false ,
EXTERNAL_DOCUMENTS_IDS . len ( ) ,
2022-04-09 14:50:43 +02:00
vec! [ Words , Typo , Proximity , Attribute , Exactness ] ,
7
2021-06-17 15:19:03 +02:00
) ;
2022-12-07 16:41:23 +01:00
test_distinct! (
distinct_string_criterion_words ,
tag ,
false ,
EXTERNAL_DOCUMENTS_IDS . len ( ) ,
vec! [ Words ] ,
3
) ;
test_distinct! (
distinct_number_criterion_words ,
asc_desc_rank ,
false ,
EXTERNAL_DOCUMENTS_IDS . len ( ) ,
vec! [ Words ] ,
7
) ;
test_distinct! (
distinct_string_criterion_words_typo ,
tag ,
false ,
EXTERNAL_DOCUMENTS_IDS . len ( ) ,
vec! [ Words , Typo ] ,
3
) ;
test_distinct! (
distinct_number_criterion_words_typo ,
asc_desc_rank ,
false ,
EXTERNAL_DOCUMENTS_IDS . len ( ) ,
vec! [ Words , Typo ] ,
7
) ;
test_distinct! (
distinct_string_criterion_words_proximity ,
tag ,
false ,
EXTERNAL_DOCUMENTS_IDS . len ( ) ,
vec! [ Words , Proximity ] ,
3
) ;
test_distinct! (
distinct_number_criterion_words_proximity ,
asc_desc_rank ,
false ,
EXTERNAL_DOCUMENTS_IDS . len ( ) ,
vec! [ Words , Proximity ] ,
7
) ;
test_distinct! (
distinct_string_criterion_words_attribute ,
tag ,
false ,
EXTERNAL_DOCUMENTS_IDS . len ( ) ,
vec! [ Words , Attribute ] ,
3
) ;
test_distinct! (
distinct_number_criterion_words_attribute ,
asc_desc_rank ,
false ,
EXTERNAL_DOCUMENTS_IDS . len ( ) ,
vec! [ Words , Attribute ] ,
7
) ;
test_distinct! (
distinct_string_criterion_words_exactness ,
tag ,
false ,
EXTERNAL_DOCUMENTS_IDS . len ( ) ,
vec! [ Words , Exactness ] ,
3
) ;
test_distinct! (
distinct_number_criterion_words_exactness ,
asc_desc_rank ,
false ,
EXTERNAL_DOCUMENTS_IDS . len ( ) ,
vec! [ Words , Exactness ] ,
7
) ;