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

Commit f37c86e

Browse files
committed
Add some integration tests on the sort criterion
1 parent 098c410 commit f37c86e

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
@@ -294,3 +294,202 @@ fn iterative_facet_string_ordered_iter<'t>(
294294

295295
Ok(vec.into_iter())
296296
}
297+
298+
#[cfg(test)]
299+
mod tests {
300+
use std::str::FromStr;
301+
302+
use big_s::S;
303+
use maplit::hashset;
304+
305+
use crate::index::tests::TempIndex;
306+
use crate::{AscDesc, Filter, Search, SearchResult};
307+
308+
// Note that in this test, only the iterative sort algorithms are used. Set the CANDIDATES_THESHOLD
309+
// constant to 0 to ensure that the other sort algorithms are also correct.
310+
#[test]
311+
fn sort_criterion_placeholder() {
312+
let index = TempIndex::new();
313+
314+
index
315+
.update_settings(|settings| {
316+
settings.set_primary_key("id".to_owned());
317+
settings
318+
.set_sortable_fields(maplit::hashset! { S("id"), S("mod_10"), S("mod_20") });
319+
settings.set_criteria(vec!["sort".to_owned()]);
320+
})
321+
.unwrap();
322+
323+
let mut docs = vec![];
324+
for i in 0..100 {
325+
docs.push(
326+
serde_json::json!({ "id": i, "mod_10": format!("{}", i % 10), "mod_20": i % 20 }),
327+
);
328+
}
329+
330+
index.add_documents(documents!(docs)).unwrap();
331+
332+
let all_ids = (0..100).collect::<Vec<_>>();
333+
334+
let rtxn = index.read_txn().unwrap();
335+
336+
let mut search = Search::new(&rtxn, &index);
337+
search.sort_criteria(vec![AscDesc::from_str("mod_10:desc").unwrap()]);
338+
search.limit(100);
339+
340+
let SearchResult { mut documents_ids, .. } = search.execute().unwrap();
341+
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]");
342+
documents_ids.sort();
343+
assert_eq!(all_ids, documents_ids);
344+
345+
let mut search = Search::new(&rtxn, &index);
346+
search.sort_criteria(vec![
347+
AscDesc::from_str("mod_10:desc").unwrap(),
348+
AscDesc::from_str("id:desc").unwrap(),
349+
]);
350+
search.limit(100);
351+
352+
let SearchResult { mut documents_ids, .. } = search.execute().unwrap();
353+
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]");
354+
documents_ids.sort();
355+
assert_eq!(all_ids, documents_ids);
356+
357+
let mut search = Search::new(&rtxn, &index);
358+
search.sort_criteria(vec![
359+
AscDesc::from_str("mod_10:desc").unwrap(),
360+
AscDesc::from_str("mod_20:asc").unwrap(),
361+
]);
362+
search.limit(100);
363+
364+
let SearchResult { mut documents_ids, .. } = search.execute().unwrap();
365+
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]");
366+
documents_ids.sort();
367+
assert_eq!(all_ids, documents_ids);
368+
369+
let mut search = Search::new(&rtxn, &index);
370+
search.sort_criteria(vec![
371+
AscDesc::from_str("mod_10:desc").unwrap(),
372+
AscDesc::from_str("mod_20:desc").unwrap(),
373+
]);
374+
search.limit(100);
375+
376+
let SearchResult { mut documents_ids, .. } = search.execute().unwrap();
377+
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]");
378+
documents_ids.sort();
379+
assert_eq!(all_ids, documents_ids);
380+
381+
let mut search = Search::new(&rtxn, &index);
382+
search.sort_criteria(vec![
383+
AscDesc::from_str("mod_10:desc").unwrap(),
384+
AscDesc::from_str("mod_20:desc").unwrap(),
385+
AscDesc::from_str("id:desc").unwrap(),
386+
]);
387+
search.limit(100);
388+
389+
let SearchResult { mut documents_ids, .. } = search.execute().unwrap();
390+
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]");
391+
documents_ids.sort();
392+
assert_eq!(all_ids, documents_ids);
393+
}
394+
395+
// Note that in this test, only the iterative sort algorithms are used. Set the CANDIDATES_THESHOLD
396+
// constant to 0 to ensure that the other sort algorithms are also correct.
397+
#[test]
398+
fn sort_criterion_non_placeholder() {
399+
let index = TempIndex::new();
400+
401+
index
402+
.update_settings(|settings| {
403+
settings.set_primary_key("id".to_owned());
404+
settings.set_filterable_fields(hashset! { S("id"), S("mod_10"), S("mod_20") });
405+
settings.set_sortable_fields(hashset! { S("id"), S("mod_10"), S("mod_20") });
406+
settings.set_criteria(vec!["sort".to_owned()]);
407+
})
408+
.unwrap();
409+
410+
let mut docs = vec![];
411+
for i in 0..100 {
412+
docs.push(
413+
serde_json::json!({ "id": i, "mod_10": format!("{}", i % 10), "mod_20": i % 20 }),
414+
);
415+
}
416+
417+
index.add_documents(documents!(docs)).unwrap();
418+
419+
let rtxn = index.read_txn().unwrap();
420+
421+
let mut search = Search::new(&rtxn, &index);
422+
search.filter(
423+
Filter::from_str("mod_10 IN [1, 0, 2] OR mod_20 IN [10, 13] OR id IN [5, 6]")
424+
.unwrap()
425+
.unwrap(),
426+
);
427+
search.sort_criteria(vec![
428+
AscDesc::from_str("mod_10:desc").unwrap(),
429+
AscDesc::from_str("mod_20:asc").unwrap(),
430+
AscDesc::from_str("id:desc").unwrap(),
431+
]);
432+
search.limit(100);
433+
434+
let SearchResult { mut documents_ids, .. } = search.execute().unwrap();
435+
// 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
436+
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]");
437+
let expected_ids = (0..100)
438+
.filter(|id| {
439+
[1, 0, 2].contains(&(id % 10))
440+
|| [10, 13].contains(&(id % 20))
441+
|| [5, 6].contains(id)
442+
})
443+
.collect::<Vec<_>>();
444+
documents_ids.sort();
445+
assert_eq!(expected_ids, documents_ids);
446+
447+
let mut search = Search::new(&rtxn, &index);
448+
search.filter(
449+
Filter::from_str("mod_10 IN [7, 8, 0] OR mod_20 IN [1, 15, 16] OR id IN [0, 4]")
450+
.unwrap()
451+
.unwrap(),
452+
);
453+
search.sort_criteria(vec![
454+
AscDesc::from_str("mod_10:asc").unwrap(),
455+
AscDesc::from_str("mod_20:asc").unwrap(),
456+
AscDesc::from_str("id:desc").unwrap(),
457+
]);
458+
search.limit(100);
459+
460+
let SearchResult { mut documents_ids, .. } = search.execute().unwrap();
461+
// 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
462+
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]");
463+
let expected_ids = (0..100)
464+
.filter(|id| {
465+
[7, 8, 0].contains(&(id % 10))
466+
|| [1, 15, 16].contains(&(id % 20))
467+
|| [0, 4].contains(id)
468+
})
469+
.collect::<Vec<_>>();
470+
documents_ids.sort();
471+
assert_eq!(expected_ids, documents_ids);
472+
473+
let mut search = Search::new(&rtxn, &index);
474+
search.filter(
475+
Filter::from_str("mod_10 IN [1, 0, 2] OR mod_20 IN [10, 13] OR id IN [5, 6]")
476+
.unwrap()
477+
.unwrap(),
478+
);
479+
search.sort_criteria(vec![AscDesc::from_str("id:desc").unwrap()]);
480+
search.limit(100);
481+
482+
let SearchResult { documents_ids, .. } = search.execute().unwrap();
483+
// The order should be in decreasing value of the id
484+
let mut expected_ids = (0..100)
485+
.filter(|id| {
486+
[1, 0, 2].contains(&(id % 10))
487+
|| [10, 13].contains(&(id % 20))
488+
|| [5, 6].contains(id)
489+
})
490+
.collect::<Vec<_>>();
491+
expected_ids.sort();
492+
expected_ids.reverse();
493+
assert_eq!(expected_ids, documents_ids);
494+
}
495+
}

0 commit comments

Comments
 (0)