Skip to content
This repository was archived by the owner on Apr 4, 2023. It is now read-only.

Commit 0276d52

Browse files
bors[bot]loiclec
andauthored
Merge #728
728: Add some integration tests on the sort criterion r=ManyTheFish a=loiclec This is simply an integration test ensuring that the sort criterion works properly. However, only one version of the algorithm is tested here (the iterative one). To test the version that uses the facet DB, one has to manually set the `CANDIDATES_THRESHOLD` constant to `0`. I have done that and ensured that the test still succeeds. However, in the future, we will probably want to have an option to force which algorithm is used at runtime, for testing purposes. Co-authored-by: Loïc Lecrenier <[email protected]>
2 parents e2ffc3d + f37c86e commit 0276d52

File tree

1 file changed

+199
-0
lines changed

1 file changed

+199
-0
lines changed

milli/src/search/criteria/asc_desc.rs

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,3 +296,202 @@ fn iterative_facet_string_ordered_iter<'t>(
296296

297297
Ok(vec.into_iter())
298298
}
299+
300+
#[cfg(test)]
301+
mod tests {
302+
use std::str::FromStr;
303+
304+
use big_s::S;
305+
use maplit::hashset;
306+
307+
use crate::index::tests::TempIndex;
308+
use crate::{AscDesc, Filter, Search, SearchResult};
309+
310+
// Note that in this test, only the iterative sort algorithms are used. Set the CANDIDATES_THESHOLD
311+
// constant to 0 to ensure that the other sort algorithms are also correct.
312+
#[test]
313+
fn sort_criterion_placeholder() {
314+
let index = TempIndex::new();
315+
316+
index
317+
.update_settings(|settings| {
318+
settings.set_primary_key("id".to_owned());
319+
settings
320+
.set_sortable_fields(maplit::hashset! { S("id"), S("mod_10"), S("mod_20") });
321+
settings.set_criteria(vec!["sort".to_owned()]);
322+
})
323+
.unwrap();
324+
325+
let mut docs = vec![];
326+
for i in 0..100 {
327+
docs.push(
328+
serde_json::json!({ "id": i, "mod_10": format!("{}", i % 10), "mod_20": i % 20 }),
329+
);
330+
}
331+
332+
index.add_documents(documents!(docs)).unwrap();
333+
334+
let all_ids = (0..100).collect::<Vec<_>>();
335+
336+
let rtxn = index.read_txn().unwrap();
337+
338+
let mut search = Search::new(&rtxn, &index);
339+
search.sort_criteria(vec![AscDesc::from_str("mod_10:desc").unwrap()]);
340+
search.limit(100);
341+
342+
let SearchResult { mut documents_ids, .. } = search.execute().unwrap();
343+
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 19, 29, 39, 49, 59, 69, 79, 89, 99, 8, 18, 28, 38, 48, 58, 68, 78, 88, 98, 7, 17, 27, 37, 47, 57, 67, 77, 87, 97, 6, 16, 26, 36, 46, 56, 66, 76, 86, 96, 5, 15, 25, 35, 45, 55, 65, 75, 85, 95, 4, 14, 24, 34, 44, 54, 64, 74, 84, 94, 3, 13, 23, 33, 43, 53, 63, 73, 83, 93, 2, 12, 22, 32, 42, 52, 62, 72, 82, 92, 1, 11, 21, 31, 41, 51, 61, 71, 81, 91, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90]");
344+
documents_ids.sort();
345+
assert_eq!(all_ids, documents_ids);
346+
347+
let mut search = Search::new(&rtxn, &index);
348+
search.sort_criteria(vec![
349+
AscDesc::from_str("mod_10:desc").unwrap(),
350+
AscDesc::from_str("id:desc").unwrap(),
351+
]);
352+
search.limit(100);
353+
354+
let SearchResult { mut documents_ids, .. } = search.execute().unwrap();
355+
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[99, 89, 79, 69, 59, 49, 39, 29, 19, 9, 98, 88, 78, 68, 58, 48, 38, 28, 18, 8, 97, 87, 77, 67, 57, 47, 37, 27, 17, 7, 96, 86, 76, 66, 56, 46, 36, 26, 16, 6, 95, 85, 75, 65, 55, 45, 35, 25, 15, 5, 94, 84, 74, 64, 54, 44, 34, 24, 14, 4, 93, 83, 73, 63, 53, 43, 33, 23, 13, 3, 92, 82, 72, 62, 52, 42, 32, 22, 12, 2, 91, 81, 71, 61, 51, 41, 31, 21, 11, 1, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0]");
356+
documents_ids.sort();
357+
assert_eq!(all_ids, documents_ids);
358+
359+
let mut search = Search::new(&rtxn, &index);
360+
search.sort_criteria(vec![
361+
AscDesc::from_str("mod_10:desc").unwrap(),
362+
AscDesc::from_str("mod_20:asc").unwrap(),
363+
]);
364+
search.limit(100);
365+
366+
let SearchResult { mut documents_ids, .. } = search.execute().unwrap();
367+
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 29, 49, 69, 89, 19, 39, 59, 79, 99, 8, 28, 48, 68, 88, 18, 38, 58, 78, 98, 7, 27, 47, 67, 87, 17, 37, 57, 77, 97, 6, 26, 46, 66, 86, 16, 36, 56, 76, 96, 5, 25, 45, 65, 85, 15, 35, 55, 75, 95, 4, 24, 44, 64, 84, 14, 34, 54, 74, 94, 3, 23, 43, 63, 83, 13, 33, 53, 73, 93, 2, 22, 42, 62, 82, 12, 32, 52, 72, 92, 1, 21, 41, 61, 81, 11, 31, 51, 71, 91, 0, 20, 40, 60, 80, 10, 30, 50, 70, 90]");
368+
documents_ids.sort();
369+
assert_eq!(all_ids, documents_ids);
370+
371+
let mut search = Search::new(&rtxn, &index);
372+
search.sort_criteria(vec![
373+
AscDesc::from_str("mod_10:desc").unwrap(),
374+
AscDesc::from_str("mod_20:desc").unwrap(),
375+
]);
376+
search.limit(100);
377+
378+
let SearchResult { mut documents_ids, .. } = search.execute().unwrap();
379+
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[19, 39, 59, 79, 99, 9, 29, 49, 69, 89, 18, 38, 58, 78, 98, 8, 28, 48, 68, 88, 17, 37, 57, 77, 97, 7, 27, 47, 67, 87, 16, 36, 56, 76, 96, 6, 26, 46, 66, 86, 15, 35, 55, 75, 95, 5, 25, 45, 65, 85, 14, 34, 54, 74, 94, 4, 24, 44, 64, 84, 13, 33, 53, 73, 93, 3, 23, 43, 63, 83, 12, 32, 52, 72, 92, 2, 22, 42, 62, 82, 11, 31, 51, 71, 91, 1, 21, 41, 61, 81, 10, 30, 50, 70, 90, 0, 20, 40, 60, 80]");
380+
documents_ids.sort();
381+
assert_eq!(all_ids, documents_ids);
382+
383+
let mut search = Search::new(&rtxn, &index);
384+
search.sort_criteria(vec![
385+
AscDesc::from_str("mod_10:desc").unwrap(),
386+
AscDesc::from_str("mod_20:desc").unwrap(),
387+
AscDesc::from_str("id:desc").unwrap(),
388+
]);
389+
search.limit(100);
390+
391+
let SearchResult { mut documents_ids, .. } = search.execute().unwrap();
392+
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[99, 79, 59, 39, 19, 89, 69, 49, 29, 9, 98, 78, 58, 38, 18, 88, 68, 48, 28, 8, 97, 77, 57, 37, 17, 87, 67, 47, 27, 7, 96, 76, 56, 36, 16, 86, 66, 46, 26, 6, 95, 75, 55, 35, 15, 85, 65, 45, 25, 5, 94, 74, 54, 34, 14, 84, 64, 44, 24, 4, 93, 73, 53, 33, 13, 83, 63, 43, 23, 3, 92, 72, 52, 32, 12, 82, 62, 42, 22, 2, 91, 71, 51, 31, 11, 81, 61, 41, 21, 1, 90, 70, 50, 30, 10, 80, 60, 40, 20, 0]");
393+
documents_ids.sort();
394+
assert_eq!(all_ids, documents_ids);
395+
}
396+
397+
// Note that in this test, only the iterative sort algorithms are used. Set the CANDIDATES_THESHOLD
398+
// constant to 0 to ensure that the other sort algorithms are also correct.
399+
#[test]
400+
fn sort_criterion_non_placeholder() {
401+
let index = TempIndex::new();
402+
403+
index
404+
.update_settings(|settings| {
405+
settings.set_primary_key("id".to_owned());
406+
settings.set_filterable_fields(hashset! { S("id"), S("mod_10"), S("mod_20") });
407+
settings.set_sortable_fields(hashset! { S("id"), S("mod_10"), S("mod_20") });
408+
settings.set_criteria(vec!["sort".to_owned()]);
409+
})
410+
.unwrap();
411+
412+
let mut docs = vec![];
413+
for i in 0..100 {
414+
docs.push(
415+
serde_json::json!({ "id": i, "mod_10": format!("{}", i % 10), "mod_20": i % 20 }),
416+
);
417+
}
418+
419+
index.add_documents(documents!(docs)).unwrap();
420+
421+
let rtxn = index.read_txn().unwrap();
422+
423+
let mut search = Search::new(&rtxn, &index);
424+
search.filter(
425+
Filter::from_str("mod_10 IN [1, 0, 2] OR mod_20 IN [10, 13] OR id IN [5, 6]")
426+
.unwrap()
427+
.unwrap(),
428+
);
429+
search.sort_criteria(vec![
430+
AscDesc::from_str("mod_10:desc").unwrap(),
431+
AscDesc::from_str("mod_20:asc").unwrap(),
432+
AscDesc::from_str("id:desc").unwrap(),
433+
]);
434+
search.limit(100);
435+
436+
let SearchResult { mut documents_ids, .. } = search.execute().unwrap();
437+
// The order should be in increasing value of the id modulo 10, followed by increasing value of the id modulo 20, followed by decreasing value of the id
438+
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[6, 5, 93, 73, 53, 33, 13, 82, 62, 42, 22, 2, 92, 72, 52, 32, 12, 81, 61, 41, 21, 1, 91, 71, 51, 31, 11, 80, 60, 40, 20, 0, 90, 70, 50, 30, 10]");
439+
let expected_ids = (0..100)
440+
.filter(|id| {
441+
[1, 0, 2].contains(&(id % 10))
442+
|| [10, 13].contains(&(id % 20))
443+
|| [5, 6].contains(id)
444+
})
445+
.collect::<Vec<_>>();
446+
documents_ids.sort();
447+
assert_eq!(expected_ids, documents_ids);
448+
449+
let mut search = Search::new(&rtxn, &index);
450+
search.filter(
451+
Filter::from_str("mod_10 IN [7, 8, 0] OR mod_20 IN [1, 15, 16] OR id IN [0, 4]")
452+
.unwrap()
453+
.unwrap(),
454+
);
455+
search.sort_criteria(vec![
456+
AscDesc::from_str("mod_10:asc").unwrap(),
457+
AscDesc::from_str("mod_20:asc").unwrap(),
458+
AscDesc::from_str("id:desc").unwrap(),
459+
]);
460+
search.limit(100);
461+
462+
let SearchResult { mut documents_ids, .. } = search.execute().unwrap();
463+
// The order should be in increasing value of the id modulo 10, followed by increasing value of the id modulo 20, followed by decreasing value of the id
464+
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[80, 60, 40, 20, 0, 90, 70, 50, 30, 10, 81, 61, 41, 21, 1, 4, 95, 75, 55, 35, 15, 96, 76, 56, 36, 16, 87, 67, 47, 27, 7, 97, 77, 57, 37, 17, 88, 68, 48, 28, 8, 98, 78, 58, 38, 18]");
465+
let expected_ids = (0..100)
466+
.filter(|id| {
467+
[7, 8, 0].contains(&(id % 10))
468+
|| [1, 15, 16].contains(&(id % 20))
469+
|| [0, 4].contains(id)
470+
})
471+
.collect::<Vec<_>>();
472+
documents_ids.sort();
473+
assert_eq!(expected_ids, documents_ids);
474+
475+
let mut search = Search::new(&rtxn, &index);
476+
search.filter(
477+
Filter::from_str("mod_10 IN [1, 0, 2] OR mod_20 IN [10, 13] OR id IN [5, 6]")
478+
.unwrap()
479+
.unwrap(),
480+
);
481+
search.sort_criteria(vec![AscDesc::from_str("id:desc").unwrap()]);
482+
search.limit(100);
483+
484+
let SearchResult { documents_ids, .. } = search.execute().unwrap();
485+
// The order should be in decreasing value of the id
486+
let mut expected_ids = (0..100)
487+
.filter(|id| {
488+
[1, 0, 2].contains(&(id % 10))
489+
|| [10, 13].contains(&(id % 20))
490+
|| [5, 6].contains(id)
491+
})
492+
.collect::<Vec<_>>();
493+
expected_ids.sort();
494+
expected_ids.reverse();
495+
assert_eq!(expected_ids, documents_ids);
496+
}
497+
}

0 commit comments

Comments
 (0)