Compare commits

...

17 Commits

Author SHA1 Message Date
e563676ce5 Add score details to new search tests 2023-06-15 17:52:30 +02:00
513649a955 Fix tests 2023-06-15 17:52:29 +02:00
61265e2830 Expose the scores and detailed scores in the API 2023-06-15 17:52:29 +02:00
f5e77419f4 Store the scores for each bucket
Remove optimization where ranking rules are not executed on buckets of a single document
when the score needs to be computed
2023-06-15 17:52:29 +02:00
fd82ea828c Score for graph based ranking rules
Count phrases in matchingWords and maxMatchingWords
2023-06-15 17:52:29 +02:00
7daa9049d8 Add rank_to_score for graph based ranking rules 2023-06-15 17:52:29 +02:00
42075d3a12 Score for sort 2023-06-15 17:52:29 +02:00
efdd5b3551 Score for geosort 2023-06-15 17:52:29 +02:00
1ead3d87b5 Score for exact_attributes 2023-06-15 17:52:29 +02:00
bb6cba8c26 RankingRuleOutput now contains a Score 2023-06-15 17:52:29 +02:00
80e038be6c Add score_details 2023-06-15 17:52:29 +02:00
5883e8b621 add virtual conditions to fid and position to always have the max cost 2023-06-15 17:38:55 +02:00
fefa6ae92c Change how the cost of removing words is computed 2023-06-15 17:19:39 +02:00
46554f764d Remove out-of-date comment 2023-06-15 17:19:39 +02:00
0709c02307 Position now takes into account the distance to the position of the word in the query
it used to be based on the distance to the position 0
2023-06-15 17:19:39 +02:00
5e64294d21 Proximity costs 0 for documents that are perfectly matching 2023-06-15 17:19:39 +02:00
d5edc38a34 Fix sort id 2023-06-15 17:19:39 +02:00
109 changed files with 10684 additions and 479 deletions

View File

@ -240,6 +240,8 @@ InvalidSearchOffset , InvalidRequest , BAD_REQUEST ;
InvalidSearchPage , InvalidRequest , BAD_REQUEST ;
InvalidSearchQ , InvalidRequest , BAD_REQUEST ;
InvalidSearchShowMatchesPosition , InvalidRequest , BAD_REQUEST ;
InvalidSearchShowRankingScore , InvalidRequest , BAD_REQUEST ;
InvalidSearchShowRankingScoreDetails , InvalidRequest , BAD_REQUEST ;
InvalidSearchSort , InvalidRequest , BAD_REQUEST ;
InvalidSettingsDisplayedAttributes , InvalidRequest , BAD_REQUEST ;
InvalidSettingsDistinctAttribute , InvalidRequest , BAD_REQUEST ;

View File

@ -56,6 +56,10 @@ pub struct SearchQueryGet {
sort: Option<String>,
#[deserr(default, error = DeserrQueryParamError<InvalidSearchShowMatchesPosition>)]
show_matches_position: Param<bool>,
#[deserr(default, error = DeserrQueryParamError<InvalidSearchShowRankingScore>)]
show_ranking_score: Param<bool>,
#[deserr(default, error = DeserrQueryParamError<InvalidSearchShowRankingScoreDetails>)]
show_ranking_score_details: Param<bool>,
#[deserr(default, error = DeserrQueryParamError<InvalidSearchFacets>)]
facets: Option<CS<String>>,
#[deserr( default = DEFAULT_HIGHLIGHT_PRE_TAG(), error = DeserrQueryParamError<InvalidSearchHighlightPreTag>)]
@ -91,6 +95,8 @@ impl From<SearchQueryGet> for SearchQuery {
filter,
sort: other.sort.map(|attr| fix_sort_query_parameters(&attr)),
show_matches_position: other.show_matches_position.0,
show_ranking_score: other.show_ranking_score.0,
show_ranking_score_details: other.show_ranking_score_details.0,
facets: other.facets.map(|o| o.into_iter().collect()),
highlight_pre_tag: other.highlight_pre_tag,
highlight_post_tag: other.highlight_post_tag,

View File

@ -9,6 +9,7 @@ use meilisearch_auth::IndexSearchRules;
use meilisearch_types::deserr::DeserrJsonError;
use meilisearch_types::error::deserr_codes::*;
use meilisearch_types::index_uid::IndexUid;
use meilisearch_types::milli::score_details::{ScoreDetails, ScoringStrategy};
use meilisearch_types::settings::DEFAULT_PAGINATION_MAX_TOTAL_HITS;
use meilisearch_types::{milli, Document};
use milli::tokenizer::TokenizerBuilder;
@ -54,6 +55,10 @@ pub struct SearchQuery {
pub attributes_to_highlight: Option<HashSet<String>>,
#[deserr(default, error = DeserrJsonError<InvalidSearchShowMatchesPosition>, default)]
pub show_matches_position: bool,
#[deserr(default, error = DeserrJsonError<InvalidSearchShowRankingScore>, default)]
pub show_ranking_score: bool,
#[deserr(default, error = DeserrJsonError<InvalidSearchShowRankingScoreDetails>, default)]
pub show_ranking_score_details: bool,
#[deserr(default, error = DeserrJsonError<InvalidSearchFilter>)]
pub filter: Option<Value>,
#[deserr(default, error = DeserrJsonError<InvalidSearchSort>)]
@ -103,6 +108,10 @@ pub struct SearchQueryWithIndex {
pub crop_length: usize,
#[deserr(default, error = DeserrJsonError<InvalidSearchAttributesToHighlight>)]
pub attributes_to_highlight: Option<HashSet<String>>,
#[deserr(default, error = DeserrJsonError<InvalidSearchShowRankingScore>, default)]
pub show_ranking_score: bool,
#[deserr(default, error = DeserrJsonError<InvalidSearchShowRankingScoreDetails>, default)]
pub show_ranking_score_details: bool,
#[deserr(default, error = DeserrJsonError<InvalidSearchShowMatchesPosition>, default)]
pub show_matches_position: bool,
#[deserr(default, error = DeserrJsonError<InvalidSearchFilter>)]
@ -134,6 +143,8 @@ impl SearchQueryWithIndex {
attributes_to_crop,
crop_length,
attributes_to_highlight,
show_ranking_score,
show_ranking_score_details,
show_matches_position,
filter,
sort,
@ -155,6 +166,8 @@ impl SearchQueryWithIndex {
attributes_to_crop,
crop_length,
attributes_to_highlight,
show_ranking_score,
show_ranking_score_details,
show_matches_position,
filter,
sort,
@ -194,7 +207,7 @@ impl From<MatchingStrategy> for TermsMatchingStrategy {
}
}
#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
#[derive(Debug, Clone, Serialize, PartialEq)]
pub struct SearchHit {
#[serde(flatten)]
pub document: Document,
@ -202,6 +215,10 @@ pub struct SearchHit {
pub formatted: Document,
#[serde(rename = "_matchesPosition", skip_serializing_if = "Option::is_none")]
pub matches_position: Option<MatchesPosition>,
#[serde(rename = "_rankingScore", skip_serializing_if = "Option::is_none")]
pub ranking_score: Option<f64>,
#[serde(rename = "_rankingScoreDetails", skip_serializing_if = "Option::is_none")]
pub ranking_score_details: Option<serde_json::Map<String, serde_json::Value>>,
}
#[derive(Serialize, Debug, Clone, PartialEq)]
@ -283,6 +300,11 @@ pub fn perform_search(
.unwrap_or(DEFAULT_PAGINATION_MAX_TOTAL_HITS);
search.exhaustive_number_hits(is_finite_pagination);
search.scoring_strategy(if query.show_ranking_score || query.show_ranking_score_details {
ScoringStrategy::Detailed
} else {
ScoringStrategy::Skip
});
// compute the offset on the limit depending on the pagination mode.
let (offset, limit) = if is_finite_pagination {
@ -320,7 +342,8 @@ pub fn perform_search(
search.sort_criteria(sort);
}
let milli::SearchResult { documents_ids, matching_words, candidates, .. } = search.execute()?;
let milli::SearchResult { documents_ids, matching_words, candidates, document_scores, .. } =
search.execute()?;
let fields_ids_map = index.fields_ids_map(&rtxn).unwrap();
@ -392,7 +415,7 @@ pub fn perform_search(
let documents_iter = index.documents(&rtxn, documents_ids)?;
for (_id, obkv) in documents_iter {
for ((_id, obkv), score) in documents_iter.into_iter().zip(document_scores.into_iter()) {
// First generate a document with all the displayed fields
let displayed_document = make_document(&displayed_ids, &fields_ids_map, obkv)?;
@ -416,7 +439,18 @@ pub fn perform_search(
insert_geo_distance(sort, &mut document);
}
let hit = SearchHit { document, formatted, matches_position };
let ranking_score =
query.show_ranking_score.then(|| ScoreDetails::global_score(score.iter()));
let ranking_score_details =
query.show_ranking_score_details.then(|| ScoreDetails::to_json_map(score.iter()));
let hit = SearchHit {
document,
formatted,
matches_position,
ranking_score_details,
ranking_score,
};
documents.push(hit);
}

View File

@ -1,3 +1,4 @@
use insta::{allow_duplicates, assert_json_snapshot};
use serde_json::json;
use super::*;
@ -18,30 +19,43 @@ async fn formatted_contain_wildcard() {
|response, code|
{
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"_formatted": {
"id": "852",
"cattos": "<em>pésti</em>",
},
"_matchesPosition": {"cattos": [{"start": 0, "length": 5}]},
})
);
}
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"_formatted": {
"id": "852",
"cattos": "<em>pésti</em>"
},
"_matchesPosition": {
"cattos": [
{
"start": 0,
"length": 5
}
]
}
}
"###);
}
}
)
.await;
index
.search(json!({ "q": "pésti", "attributesToRetrieve": ["*"] }), |response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"id": 852,
"cattos": "pésti",
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852,
"cattos": "pésti"
}
"###)
}
})
.await;
@ -50,20 +64,29 @@ async fn formatted_contain_wildcard() {
json!({ "q": "pésti", "attributesToRetrieve": ["*"], "attributesToHighlight": ["id"], "showMatchesPosition": true }),
|response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"id": 852,
"cattos": "pésti",
"_formatted": {
"id": "852",
"cattos": "pésti",
},
"_matchesPosition": {"cattos": [{"start": 0, "length": 5}]},
})
);
}
)
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852,
"cattos": "pésti",
"_formatted": {
"id": "852",
"cattos": "pésti"
},
"_matchesPosition": {
"cattos": [
{
"start": 0,
"length": 5
}
]
}
}
"###)
}
})
.await;
index
@ -71,17 +94,20 @@ async fn formatted_contain_wildcard() {
json!({ "q": "pésti", "attributesToRetrieve": ["*"], "attributesToCrop": ["*"] }),
|response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"id": 852,
"cattos": "pésti",
"_formatted": {
"id": "852",
"cattos": "pésti",
}
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852,
"cattos": "pésti",
"_formatted": {
"id": "852",
"cattos": "pésti"
}
}
"###);
}
},
)
.await;
@ -89,17 +115,20 @@ async fn formatted_contain_wildcard() {
index
.search(json!({ "q": "pésti", "attributesToCrop": ["*"] }), |response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"id": 852,
"cattos": "pésti",
"_formatted": {
"id": "852",
"cattos": "pésti",
}
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852,
"cattos": "pésti",
"_formatted": {
"id": "852",
"cattos": "pésti"
}
}
"###)
}
})
.await;
}
@ -116,21 +145,24 @@ async fn format_nested() {
index
.search(json!({ "q": "pésti", "attributesToRetrieve": ["doggos"] }), |response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"doggos": [
{
"name": "bobby",
"age": 2,
},
{
"name": "buddy",
"age": 4,
},
],
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"doggos": [
{
"name": "bobby",
"age": 2
},
{
"name": "buddy",
"age": 4
}
]
}
"###)
}
})
.await;
@ -139,19 +171,22 @@ async fn format_nested() {
json!({ "q": "pésti", "attributesToRetrieve": ["doggos.name"] }),
|response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"doggos": [
{
"name": "bobby",
},
{
"name": "buddy",
},
],
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"doggos": [
{
"name": "bobby"
},
{
"name": "buddy"
}
]
}
"###)
}
},
)
.await;
@ -161,20 +196,30 @@ async fn format_nested() {
json!({ "q": "bobby", "attributesToRetrieve": ["doggos.name"], "showMatchesPosition": true }),
|response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"doggos": [
{
"name": "bobby",
},
{
"name": "buddy",
},
],
"_matchesPosition": {"doggos.name": [{"start": 0, "length": 5}]},
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"doggos": [
{
"name": "bobby"
},
{
"name": "buddy"
}
],
"_matchesPosition": {
"doggos.name": [
{
"start": 0,
"length": 5
}
]
}
}
"###)
}
}
)
.await;
@ -183,21 +228,24 @@ async fn format_nested() {
.search(json!({ "q": "pésti", "attributesToRetrieve": [], "attributesToHighlight": ["doggos.name"] }),
|response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"_formatted": {
"doggos": [
{
"name": "bobby",
},
{
"name": "buddy",
},
],
},
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"_formatted": {
"doggos": [
{
"name": "bobby"
},
{
"name": "buddy"
}
]
}
}
"###)
}
})
.await;
@ -205,21 +253,24 @@ async fn format_nested() {
.search(json!({ "q": "pésti", "attributesToRetrieve": [], "attributesToCrop": ["doggos.name"] }),
|response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"_formatted": {
"doggos": [
{
"name": "bobby",
},
{
"name": "buddy",
},
],
},
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"_formatted": {
"doggos": [
{
"name": "bobby"
},
{
"name": "buddy"
}
]
}
}
"###)
}
})
.await;
@ -227,55 +278,61 @@ async fn format_nested() {
.search(json!({ "q": "pésti", "attributesToRetrieve": ["doggos.name"], "attributesToHighlight": ["doggos.age"] }),
|response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"doggos": [
{
"name": "bobby",
},
{
"name": "buddy",
},
],
"_formatted": {
"doggos": [
{
"name": "bobby",
"age": "2",
},
{
"name": "buddy",
"age": "4",
},
],
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"doggos": [
{
"name": "bobby"
},
})
);
})
{
"name": "buddy"
}
],
"_formatted": {
"doggos": [
{
"name": "bobby",
"age": "2"
},
{
"name": "buddy",
"age": "4"
}
]
}
}
"###)
}
})
.await;
index
.search(json!({ "q": "pésti", "attributesToRetrieve": [], "attributesToHighlight": ["doggos.age"], "attributesToCrop": ["doggos.name"] }),
|response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"_formatted": {
"doggos": [
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"name": "bobby",
"age": "2",
},
{
"name": "buddy",
"age": "4",
},
],
},
})
);
"_formatted": {
"doggos": [
{
"name": "bobby",
"age": "2"
},
{
"name": "buddy",
"age": "4"
}
]
}
}
"###)
}
}
)
.await;
@ -297,54 +354,66 @@ async fn displayedattr_2_smol() {
.search(json!({ "attributesToRetrieve": ["father", "id"], "attributesToHighlight": ["mother"], "attributesToCrop": ["cattos"] }),
|response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"id": 852,
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852
}
"###)
}
})
.await;
index
.search(json!({ "attributesToRetrieve": ["id"] }), |response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"id": 852,
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852
}
"###)
}
})
.await;
index
.search(json!({ "attributesToHighlight": ["id"] }), |response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"id": 852,
"_formatted": {
"id": "852",
}
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852,
"_formatted": {
"id": "852"
}
}
"###)
}
})
.await;
index
.search(json!({ "attributesToCrop": ["id"] }), |response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"id": 852,
"_formatted": {
"id": "852",
}
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852,
"_formatted": {
"id": "852"
}
}
"###)
}
})
.await;
@ -353,15 +422,18 @@ async fn displayedattr_2_smol() {
json!({ "attributesToHighlight": ["id"], "attributesToCrop": ["id"] }),
|response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"id": 852,
"_formatted": {
"id": "852",
}
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852,
"_formatted": {
"id": "852"
}
}
"###)
}
},
)
.await;
@ -369,31 +441,41 @@ async fn displayedattr_2_smol() {
index
.search(json!({ "attributesToHighlight": ["cattos"] }), |response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"id": 852,
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852
}
"###)
}
})
.await;
index
.search(json!({ "attributesToCrop": ["cattos"] }), |response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"id": 852,
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852
}
"###)
}
})
.await;
index
.search(json!({ "attributesToRetrieve": ["cattos"] }), |response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(response["hits"][0], json!({}));
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@"{}")
}
})
.await;
@ -402,7 +484,11 @@ async fn displayedattr_2_smol() {
json!({ "attributesToRetrieve": ["cattos"], "attributesToHighlight": ["cattos"], "attributesToCrop": ["cattos"] }),
|response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(response["hits"][0], json!({}));
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@"{}")
}
}
)
@ -413,14 +499,17 @@ async fn displayedattr_2_smol() {
json!({ "attributesToRetrieve": ["cattos"], "attributesToHighlight": ["id"] }),
|response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"_formatted": {
"id": "852",
}
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"_formatted": {
"id": "852"
}
}
"###)
}
},
)
.await;
@ -430,14 +519,17 @@ async fn displayedattr_2_smol() {
json!({ "attributesToRetrieve": ["cattos"], "attributesToCrop": ["id"] }),
|response, code| {
assert_eq!(code, 200, "{}", response);
assert_eq!(
response["hits"][0],
json!({
"_formatted": {
"id": "852",
}
})
);
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"_formatted": {
"id": "852"
}
}
"###)
}
},
)
.await;

View File

@ -65,7 +65,7 @@ async fn simple_search_single_index() {
]}))
.await;
snapshot!(code, @"200 OK");
insta::assert_json_snapshot!(response["results"], { "[].processingTimeMs" => "[time]" }, @r###"
insta::assert_json_snapshot!(response["results"], { "[].processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###"
[
{
"indexUid": "test",
@ -170,7 +170,7 @@ async fn simple_search_two_indexes() {
]}))
.await;
snapshot!(code, @"200 OK");
insta::assert_json_snapshot!(response["results"], { "[].processingTimeMs" => "[time]" }, @r###"
insta::assert_json_snapshot!(response["results"], { "[].processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###"
[
{
"indexUid": "test",

View File

@ -53,6 +53,7 @@ fn main() -> Result<(), Box<dyn Error>> {
&mut ctx,
&(!query.trim().is_empty()).then(|| query.trim().to_owned()),
TermsMatchingStrategy::Last,
milli::score_details::ScoringStrategy::Skip,
false,
&None,
&None,

View File

@ -2488,8 +2488,12 @@ pub(crate) mod tests {
let rtxn = index.read_txn().unwrap();
let search = Search::new(&rtxn, &index);
let SearchResult { matching_words: _, candidates: _, mut documents_ids } =
search.execute().unwrap();
let SearchResult {
matching_words: _,
candidates: _,
document_scores: _,
mut documents_ids,
} = search.execute().unwrap();
let primary_key_id = index.fields_ids_map(&rtxn).unwrap().id("primary_key").unwrap();
documents_ids.sort_unstable();
let docs = index.documents(&rtxn, documents_ids).unwrap();

View File

@ -17,6 +17,7 @@ mod fields_ids_map;
pub mod heed_codec;
pub mod index;
pub mod proximity;
pub mod score_details;
mod search;
pub mod update;

316
milli/src/score_details.rs Normal file
View File

@ -0,0 +1,316 @@
use serde::Serialize;
use crate::distance_between_two_points;
#[derive(Debug, Clone, PartialEq)]
pub enum ScoreDetails {
Words(Words),
Typo(Typo),
Proximity(Rank),
Fid(Rank),
Position(Rank),
ExactAttribute(ExactAttribute),
Exactness(Rank),
Sort(Sort),
GeoSort(GeoSort),
}
impl ScoreDetails {
pub fn local_score(&self) -> Option<f64> {
self.rank().map(Rank::local_score)
}
pub fn rank(&self) -> Option<Rank> {
match self {
ScoreDetails::Words(details) => Some(details.rank()),
ScoreDetails::Typo(details) => Some(details.rank()),
ScoreDetails::Proximity(details) => Some(*details),
ScoreDetails::Fid(details) => Some(*details),
ScoreDetails::Position(details) => Some(*details),
ScoreDetails::ExactAttribute(details) => Some(details.rank()),
ScoreDetails::Exactness(details) => Some(*details),
ScoreDetails::Sort(_) => None,
ScoreDetails::GeoSort(_) => None,
}
}
pub fn global_score<'a>(details: impl Iterator<Item = &'a Self>) -> f64 {
Rank::global_score(details.filter_map(Self::rank))
}
/// Panics
///
/// - If Position is not preceded by Fid
/// - If Exactness is not preceded by ExactAttribute
pub fn to_json_map<'a>(
details: impl Iterator<Item = &'a Self>,
) -> serde_json::Map<String, serde_json::Value> {
let mut order = 0;
let mut fid_details = None;
let mut details_map = serde_json::Map::default();
for details in details {
match details {
ScoreDetails::Words(words) => {
let words_details = serde_json::json!({
"order": order,
"matchingWords": words.matching_words,
"maxMatchingWords": words.max_matching_words,
"score": words.rank().local_score(),
});
details_map.insert("words".into(), words_details);
order += 1;
}
ScoreDetails::Typo(typo) => {
let typo_details = serde_json::json!({
"order": order,
"typoCount": typo.typo_count,
"maxTypoCount": typo.max_typo_count,
"score": typo.rank().local_score(),
});
details_map.insert("typo".into(), typo_details);
order += 1;
}
ScoreDetails::Proximity(proximity) => {
let proximity_details = serde_json::json!({
"order": order,
"score": proximity.local_score(),
});
details_map.insert("proximity".into(), proximity_details);
order += 1;
}
ScoreDetails::Fid(fid) => {
// copy the rank for future use in Position.
fid_details = Some(*fid);
// For now, fid is a virtual rule always followed by the "position" rule
let fid_details = serde_json::json!({
"order": order,
"attributes_ranking_order": fid.local_score(),
});
details_map.insert("attribute".into(), fid_details);
order += 1;
}
ScoreDetails::Position(position) => {
// For now, position is a virtual rule always preceded by the "fid" rule
let attribute_details = details_map
.get_mut("attribute")
.expect("position not preceded by attribute");
let attribute_details = attribute_details
.as_object_mut()
.expect("attribute details was not an object");
let Some(fid_details) = fid_details
else {
panic!("position not preceded by attribute");
};
attribute_details.insert(
"attributes_query_word_order".into(),
position.local_score().into(),
);
let score = Rank::global_score([fid_details, *position].iter().copied());
attribute_details.insert("score".into(), score.into());
// do not update the order since this was already done by fid
}
ScoreDetails::ExactAttribute(exact_attribute) => {
let exactness_details = serde_json::json!({
"order": order,
"matchType": exact_attribute,
"score": exact_attribute.rank().local_score(),
});
details_map.insert("exactness".into(), exactness_details);
order += 1;
}
ScoreDetails::Exactness(details) => {
// For now, exactness is a virtual rule always preceded by the "ExactAttribute" rule
let exactness_details = details_map
.get_mut("exactness")
.expect("Exactness not preceded by exactAttribute");
let exactness_details = exactness_details
.as_object_mut()
.expect("exactness details was not an object");
if exactness_details.get("matchType").expect("missing 'matchType'")
== &serde_json::json!(ExactAttribute::NoExactMatch)
{
let score = Rank::global_score(
[ExactAttribute::NoExactMatch.rank(), *details].iter().copied(),
);
*exactness_details.get_mut("score").expect("missing score") = score.into();
}
// do not update the order since this was already done by exactAttribute
}
ScoreDetails::Sort(details) => {
let sort = if details.redacted {
format!("<hidden-rule-{order}>")
} else {
format!(
"{}:{}",
details.field_name,
if details.ascending { "asc" } else { "desc" }
)
};
let value =
if details.redacted { "<hidden>".into() } else { details.value.clone() };
let sort_details = serde_json::json!({
"order": order,
"value": value,
});
details_map.insert(sort, sort_details);
order += 1;
}
ScoreDetails::GeoSort(details) => {
let sort = format!(
"_geoPoint({}, {}):{}",
details.target_point[0],
details.target_point[1],
if details.ascending { "asc" } else { "desc" }
);
let point = if let Some(value) = details.value {
serde_json::json!({ "lat": value[0], "lng": value[1]})
} else {
serde_json::Value::Null
};
let sort_details = serde_json::json!({
"order": order,
"value": point,
"distance": details.distance(),
});
details_map.insert(sort, sort_details);
order += 1;
}
}
}
details_map
}
}
/// The strategy to compute scores.
///
/// It makes sense to pass down this strategy to the internals of the search, because
/// some optimizations (today, mainly skipping ranking rules for universes of a single document)
/// are not correct to do when computing the scores.
///
/// This strategy could feasibly be extended to differentiate between the normalized score and the
/// detailed scores, but it is not useful today as the normalized score is *derived from* the
/// detailed scores.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ScoringStrategy {
/// Don't compute scores
#[default]
Skip,
/// Compute detailed scores
Detailed,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Words {
pub matching_words: u32,
pub max_matching_words: u32,
}
impl Words {
pub fn rank(&self) -> Rank {
Rank { rank: self.matching_words, max_rank: self.max_matching_words }
}
pub(crate) fn from_rank(rank: Rank) -> Words {
Words { matching_words: rank.rank, max_matching_words: rank.max_rank }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Typo {
pub typo_count: u32,
pub max_typo_count: u32,
}
impl Typo {
pub fn rank(&self) -> Rank {
Rank {
rank: self.max_typo_count - self.typo_count + 1,
max_rank: (self.max_typo_count + 1),
}
}
// max_rank = max_typo + 1
// max_typo = max_rank - 1
//
// rank = max_typo - typo + 1
// rank = max_rank - 1 - typo + 1
// rank + typo = max_rank
// typo = max_rank - rank
pub fn from_rank(rank: Rank) -> Typo {
Typo { typo_count: rank.max_rank - rank.rank, max_typo_count: rank.max_rank - 1 }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Rank {
/// The ordinal rank, such that `max_rank` is the first rank, and 0 is the last rank.
///
/// The higher the better. Documents with a rank of 0 have a score of 0 and are typically never returned
/// (they don't match the query).
pub rank: u32,
/// The maximum possible rank. Documents with this rank have a score of 1.
///
/// The max rank should not be 0.
pub max_rank: u32,
}
impl Rank {
pub fn local_score(self) -> f64 {
self.rank as f64 / self.max_rank as f64
}
pub fn global_score(details: impl Iterator<Item = Self>) -> f64 {
let mut rank = Rank { rank: 1, max_rank: 1 };
for inner_rank in details {
rank.rank -= 1;
rank.rank *= inner_rank.max_rank;
rank.max_rank *= inner_rank.max_rank;
rank.rank += inner_rank.rank;
}
rank.local_score()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum ExactAttribute {
ExactMatch,
MatchesStart,
NoExactMatch,
}
impl ExactAttribute {
pub fn rank(&self) -> Rank {
let rank = match self {
ExactAttribute::ExactMatch => 3,
ExactAttribute::MatchesStart => 2,
ExactAttribute::NoExactMatch => 1,
};
Rank { rank, max_rank: 3 }
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Sort {
pub field_name: String,
pub ascending: bool,
pub redacted: bool,
pub value: serde_json::Value,
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct GeoSort {
pub target_point: [f64; 2],
pub ascending: bool,
pub value: Option<[f64; 2]>,
}
impl GeoSort {
pub fn distance(&self) -> Option<f64> {
self.value.map(|value| distance_between_two_points(&self.target_point, &value))
}
}

View File

@ -7,6 +7,7 @@ use roaring::bitmap::RoaringBitmap;
pub use self::facet::{FacetDistribution, Filter, DEFAULT_VALUES_PER_FACET};
pub use self::new::matches::{FormatOptions, MatchBounds, Matcher, MatcherBuilder, MatchingWords};
use self::new::PartialSearchResult;
use crate::score_details::{ScoreDetails, ScoringStrategy};
use crate::{
execute_search, AscDesc, DefaultSearchLogger, DocumentId, Index, Result, SearchContext,
};
@ -29,6 +30,7 @@ pub struct Search<'a> {
sort_criteria: Option<Vec<AscDesc>>,
geo_strategy: new::GeoSortStrategy,
terms_matching_strategy: TermsMatchingStrategy,
scoring_strategy: ScoringStrategy,
words_limit: usize,
exhaustive_number_hits: bool,
rtxn: &'a heed::RoTxn<'a>,
@ -45,6 +47,7 @@ impl<'a> Search<'a> {
sort_criteria: None,
geo_strategy: new::GeoSortStrategy::default(),
terms_matching_strategy: TermsMatchingStrategy::default(),
scoring_strategy: Default::default(),
exhaustive_number_hits: false,
words_limit: 10,
rtxn,
@ -77,6 +80,11 @@ impl<'a> Search<'a> {
self
}
pub fn scoring_strategy(&mut self, value: ScoringStrategy) -> &mut Search<'a> {
self.scoring_strategy = value;
self
}
pub fn words_limit(&mut self, value: usize) -> &mut Search<'a> {
self.words_limit = value;
self
@ -93,7 +101,7 @@ impl<'a> Search<'a> {
self
}
/// Force the search to exhastivelly compute the number of candidates,
/// Forces the search to exhaustively compute the number of candidates,
/// this will increase the search time but allows finite pagination.
pub fn exhaustive_number_hits(&mut self, exhaustive_number_hits: bool) -> &mut Search<'a> {
self.exhaustive_number_hits = exhaustive_number_hits;
@ -102,11 +110,12 @@ impl<'a> Search<'a> {
pub fn execute(&self) -> Result<SearchResult> {
let mut ctx = SearchContext::new(self.index, self.rtxn);
let PartialSearchResult { located_query_terms, candidates, documents_ids } =
let PartialSearchResult { located_query_terms, candidates, documents_ids, document_scores } =
execute_search(
&mut ctx,
&self.query,
self.terms_matching_strategy,
self.scoring_strategy,
self.exhaustive_number_hits,
&self.filter,
&self.sort_criteria,
@ -124,7 +133,7 @@ impl<'a> Search<'a> {
None => MatchingWords::default(),
};
Ok(SearchResult { matching_words, candidates, documents_ids })
Ok(SearchResult { matching_words, candidates, document_scores, documents_ids })
}
}
@ -138,6 +147,7 @@ impl fmt::Debug for Search<'_> {
sort_criteria,
geo_strategy: _,
terms_matching_strategy,
scoring_strategy,
words_limit,
exhaustive_number_hits,
rtxn: _,
@ -150,6 +160,7 @@ impl fmt::Debug for Search<'_> {
.field("limit", limit)
.field("sort_criteria", sort_criteria)
.field("terms_matching_strategy", terms_matching_strategy)
.field("scoring_strategy", scoring_strategy)
.field("exhaustive_number_hits", exhaustive_number_hits)
.field("words_limit", words_limit)
.finish()
@ -160,8 +171,8 @@ impl fmt::Debug for Search<'_> {
pub struct SearchResult {
pub matching_words: MatchingWords,
pub candidates: RoaringBitmap,
// TODO those documents ids should be associated with their criteria scores.
pub documents_ids: Vec<DocumentId>,
pub document_scores: Vec<Vec<ScoreDetails>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]

View File

@ -3,14 +3,18 @@ use roaring::RoaringBitmap;
use super::logger::SearchLogger;
use super::ranking_rules::{BoxRankingRule, RankingRuleQueryTrait};
use super::SearchContext;
use crate::score_details::{ScoreDetails, ScoringStrategy};
use crate::search::new::distinct::{apply_distinct_rule, distinct_single_docid, DistinctOutput};
use crate::Result;
pub struct BucketSortOutput {
pub docids: Vec<u32>,
pub scores: Vec<Vec<ScoreDetails>>,
pub all_candidates: RoaringBitmap,
}
// TODO: would probably be good to regroup some of these inside of a struct?
#[allow(clippy::too_many_arguments)]
pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
ctx: &mut SearchContext<'ctx>,
mut ranking_rules: Vec<BoxRankingRule<'ctx, Q>>,
@ -18,6 +22,7 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
universe: &RoaringBitmap,
from: usize,
length: usize,
scoring_strategy: ScoringStrategy,
logger: &mut dyn SearchLogger<Q>,
) -> Result<BucketSortOutput> {
logger.initial_query(query);
@ -31,7 +36,11 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
};
if universe.len() < from as u64 {
return Ok(BucketSortOutput { docids: vec![], all_candidates: universe.clone() });
return Ok(BucketSortOutput {
docids: vec![],
scores: vec![],
all_candidates: universe.clone(),
});
}
if ranking_rules.is_empty() {
if let Some(distinct_fid) = distinct_fid {
@ -49,22 +58,32 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
}
let mut all_candidates = universe - excluded;
all_candidates.extend(results.iter().copied());
return Ok(BucketSortOutput { docids: results, all_candidates });
return Ok(BucketSortOutput {
scores: vec![Default::default(); results.len()],
docids: results,
all_candidates,
});
} else {
let docids = universe.iter().skip(from).take(length).collect();
return Ok(BucketSortOutput { docids, all_candidates: universe.clone() });
let docids: Vec<u32> = universe.iter().skip(from).take(length).collect();
return Ok(BucketSortOutput {
scores: vec![Default::default(); docids.len()],
docids,
all_candidates: universe.clone(),
});
};
}
let ranking_rules_len = ranking_rules.len();
logger.start_iteration_ranking_rule(0, ranking_rules[0].as_ref(), query, universe);
ranking_rules[0].start_iteration(ctx, logger, universe, query)?;
let mut ranking_rule_scores: Vec<ScoreDetails> = vec![];
let mut ranking_rule_universes: Vec<RoaringBitmap> =
vec![RoaringBitmap::default(); ranking_rules_len];
ranking_rule_universes[0] = universe.clone();
let mut cur_ranking_rule_index = 0;
/// Finish iterating over the current ranking rule, yielding
@ -89,11 +108,16 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
} else {
cur_ranking_rule_index -= 1;
}
// FIXME: check off by one
if ranking_rule_scores.len() > cur_ranking_rule_index {
ranking_rule_scores.pop();
}
};
}
let mut all_candidates = universe.clone();
let mut valid_docids = vec![];
let mut valid_scores = vec![];
let mut cur_offset = 0usize;
macro_rules! maybe_add_to_results {
@ -104,21 +128,26 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
length,
logger,
&mut valid_docids,
&mut valid_scores,
&mut all_candidates,
&mut ranking_rule_universes,
&mut ranking_rules,
cur_ranking_rule_index,
&mut cur_offset,
distinct_fid,
&ranking_rule_scores,
$candidates,
)?;
};
}
while valid_docids.len() < length {
// The universe for this bucket is zero or one element, so we don't need to sort
// anything, just extend the results and go back to the parent ranking rule.
if ranking_rule_universes[cur_ranking_rule_index].len() <= 1 {
// The universe for this bucket is zero, so we don't need to sort
// anything, just go back to the parent ranking rule.
if ranking_rule_universes[cur_ranking_rule_index].is_empty()
|| (scoring_strategy == ScoringStrategy::Skip
&& ranking_rule_universes[cur_ranking_rule_index].len() == 1)
{
let bucket = std::mem::take(&mut ranking_rule_universes[cur_ranking_rule_index]);
maybe_add_to_results!(bucket);
back!();
@ -130,6 +159,8 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
continue;
};
ranking_rule_scores.push(next_bucket.score);
logger.next_bucket_ranking_rule(
cur_ranking_rule_index,
ranking_rules[cur_ranking_rule_index].as_ref(),
@ -143,10 +174,12 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
ranking_rule_universes[cur_ranking_rule_index] -= &next_bucket.candidates;
if cur_ranking_rule_index == ranking_rules_len - 1
|| next_bucket.candidates.len() <= 1
|| (scoring_strategy == ScoringStrategy::Skip && next_bucket.candidates.len() <= 1)
|| cur_offset + (next_bucket.candidates.len() as usize) < from
{
maybe_add_to_results!(next_bucket.candidates);
// FIXME: use index based logic like all the other rules so that you don't have to maintain the pop/push?
ranking_rule_scores.pop();
continue;
}
@ -166,7 +199,7 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
)?;
}
Ok(BucketSortOutput { docids: valid_docids, all_candidates })
Ok(BucketSortOutput { docids: valid_docids, scores: valid_scores, all_candidates })
}
/// Add the candidates to the results. Take `distinct`, `from`, `length`, and `cur_offset`
@ -179,14 +212,18 @@ fn maybe_add_to_results<'ctx, Q: RankingRuleQueryTrait>(
logger: &mut dyn SearchLogger<Q>,
valid_docids: &mut Vec<u32>,
valid_scores: &mut Vec<Vec<ScoreDetails>>,
all_candidates: &mut RoaringBitmap,
ranking_rule_universes: &mut [RoaringBitmap],
ranking_rules: &mut [BoxRankingRule<'ctx, Q>],
cur_ranking_rule_index: usize,
cur_offset: &mut usize,
distinct_fid: Option<u16>,
ranking_rule_scores: &[ScoreDetails],
candidates: RoaringBitmap,
) -> Result<()> {
// First apply the distinct rule on the candidates, reducing the universes if necessary
@ -231,13 +268,17 @@ fn maybe_add_to_results<'ctx, Q: RankingRuleQueryTrait>(
let candidates =
candidates.iter().take(length - valid_docids.len()).copied().collect::<Vec<_>>();
logger.add_to_results(&candidates);
valid_docids.extend(&candidates);
valid_docids.extend_from_slice(&candidates);
valid_scores
.extend(std::iter::repeat(ranking_rule_scores.to_owned()).take(candidates.len()));
}
} else {
// if we have passed the offset already, add some of the documents (up to the limit)
let candidates = candidates.iter().take(length - valid_docids.len()).collect::<Vec<u32>>();
logger.add_to_results(&candidates);
valid_docids.extend(&candidates);
valid_docids.extend_from_slice(&candidates);
valid_scores
.extend(std::iter::repeat(ranking_rule_scores.to_owned()).take(candidates.len()));
}
*cur_offset += candidates.len() as usize;

View File

@ -2,6 +2,7 @@ use roaring::{MultiOps, RoaringBitmap};
use super::query_graph::QueryGraph;
use super::ranking_rules::{RankingRule, RankingRuleOutput};
use crate::score_details::{self, ScoreDetails};
use crate::search::new::query_graph::QueryNodeData;
use crate::search::new::query_term::ExactTerm;
use crate::{Result, SearchContext, SearchLogger};
@ -244,7 +245,13 @@ impl State {
candidates &= universe;
(
State::AttributeStarts(query_graph.clone(), candidates_per_attribute),
Some(RankingRuleOutput { query: query_graph, candidates }),
Some(RankingRuleOutput {
query: query_graph,
candidates,
score: ScoreDetails::ExactAttribute(
score_details::ExactAttribute::ExactMatch,
),
}),
)
}
State::AttributeStarts(query_graph, candidates_per_attribute) => {
@ -257,12 +264,24 @@ impl State {
candidates &= universe;
(
State::Empty(query_graph.clone()),
Some(RankingRuleOutput { query: query_graph, candidates }),
Some(RankingRuleOutput {
query: query_graph,
candidates,
score: ScoreDetails::ExactAttribute(
score_details::ExactAttribute::MatchesStart,
),
}),
)
}
State::Empty(query_graph) => (
State::Empty(query_graph.clone()),
Some(RankingRuleOutput { query: query_graph, candidates: universe.clone() }),
Some(RankingRuleOutput {
query: query_graph,
candidates: universe.clone(),
score: ScoreDetails::ExactAttribute(
score_details::ExactAttribute::NoExactMatch,
),
}),
),
};
(state, output)

View File

@ -8,6 +8,7 @@ use rstar::RTree;
use super::ranking_rules::{RankingRule, RankingRuleOutput, RankingRuleQueryTrait};
use crate::heed_codec::facet::{FieldDocIdFacetCodec, OrderedF64Codec};
use crate::score_details::{self, ScoreDetails};
use crate::{
distance_between_two_points, lat_lng_to_xyz, GeoPoint, Index, Result, SearchContext,
SearchLogger,
@ -80,7 +81,7 @@ pub struct GeoSort<Q: RankingRuleQueryTrait> {
field_ids: Option<[u16; 2]>,
rtree: Option<RTree<GeoPoint>>,
cached_sorted_docids: VecDeque<u32>,
cached_sorted_docids: VecDeque<(u32, [f64; 2])>,
geo_candidates: RoaringBitmap,
}
@ -130,7 +131,7 @@ impl<Q: RankingRuleQueryTrait> GeoSort<Q> {
let point = lat_lng_to_xyz(&self.point);
for point in rtree.nearest_neighbor_iter(&point) {
if self.geo_candidates.contains(point.data.0) {
self.cached_sorted_docids.push_back(point.data.0);
self.cached_sorted_docids.push_back(point.data);
if self.cached_sorted_docids.len() >= cache_size {
break;
}
@ -142,7 +143,7 @@ impl<Q: RankingRuleQueryTrait> GeoSort<Q> {
let point = lat_lng_to_xyz(&opposite_of(self.point));
for point in rtree.nearest_neighbor_iter(&point) {
if self.geo_candidates.contains(point.data.0) {
self.cached_sorted_docids.push_front(point.data.0);
self.cached_sorted_docids.push_front(point.data);
if self.cached_sorted_docids.len() >= cache_size {
break;
}
@ -177,7 +178,7 @@ impl<Q: RankingRuleQueryTrait> GeoSort<Q> {
// computing the distance between two points is expensive thus we cache the result
documents
.sort_by_cached_key(|(_, p)| distance_between_two_points(&self.point, p) as usize);
self.cached_sorted_docids.extend(documents.into_iter().map(|(doc_id, _)| doc_id));
self.cached_sorted_docids.extend(documents.into_iter());
};
Ok(())
@ -220,12 +221,19 @@ impl<'ctx, Q: RankingRuleQueryTrait> RankingRule<'ctx, Q> for GeoSort<Q> {
logger: &mut dyn SearchLogger<Q>,
universe: &RoaringBitmap,
) -> Result<Option<RankingRuleOutput<Q>>> {
assert!(universe.len() > 1);
let query = self.query.as_ref().unwrap().clone();
self.geo_candidates &= universe;
if self.geo_candidates.is_empty() {
return Ok(Some(RankingRuleOutput { query, candidates: universe.clone() }));
return Ok(Some(RankingRuleOutput {
query,
candidates: universe.clone(),
score: ScoreDetails::GeoSort(score_details::GeoSort {
target_point: self.point,
ascending: self.ascending,
value: None,
}),
}));
}
let ascending = self.ascending;
@ -236,11 +244,16 @@ impl<'ctx, Q: RankingRuleQueryTrait> RankingRule<'ctx, Q> for GeoSort<Q> {
cache.pop_back()
}
};
while let Some(id) = next(&mut self.cached_sorted_docids) {
while let Some((id, point)) = next(&mut self.cached_sorted_docids) {
if self.geo_candidates.contains(id) {
return Ok(Some(RankingRuleOutput {
query,
candidates: RoaringBitmap::from_iter([id]),
score: ScoreDetails::GeoSort(score_details::GeoSort {
target_point: self.point,
ascending: self.ascending,
value: Some(point),
}),
}));
}
}

View File

@ -50,6 +50,7 @@ use super::ranking_rule_graph::{
};
use super::small_bitmap::SmallBitmap;
use super::{QueryGraph, RankingRule, RankingRuleOutput, SearchContext};
use crate::score_details::Rank;
use crate::search::new::query_term::LocatedQueryTermSubset;
use crate::search::new::ranking_rule_graph::PathVisitor;
use crate::{Result, TermsMatchingStrategy};
@ -118,6 +119,8 @@ pub struct GraphBasedRankingRuleState<G: RankingRuleGraphTrait> {
all_costs: MappedInterner<QueryNode, Vec<u64>>,
/// An index in the first element of `all_distances`, giving the cost of the next bucket
cur_cost: u64,
/// One above the highest possible cost for this rule
next_max_cost: u64,
}
impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBasedRankingRule<G> {
@ -131,7 +134,20 @@ impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBase
_universe: &RoaringBitmap,
query_graph: &QueryGraph,
) -> Result<()> {
// the `next_max_cost` is the successor integer to the maximum cost of the paths in the graph.
//
// When there is a matching strategy, it also factors the additional costs of:
// 1. The words that are matched in phrases
// 2. Skipping words (by adding them to the paths with a cost)
let mut next_max_cost = 1;
let removal_cost = if let Some(terms_matching_strategy) = self.terms_matching_strategy {
// add the cost of the phrase to the next_max_cost
next_max_cost += query_graph
.words_in_phrases_count(ctx)
// remove 1 from the words in phrases count, because when there is a phrase we can now have a document
// where only the phrase is matching, and none of the non-phrase words.
// With the `1` that `next_max_cost` is initialized with, this gets counted twice.
.saturating_sub(1) as u64;
match terms_matching_strategy {
TermsMatchingStrategy::Last => {
let removal_order =
@ -139,13 +155,12 @@ impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBase
let mut forbidden_nodes =
SmallBitmap::for_interned_values_in(&query_graph.nodes);
let mut costs = query_graph.nodes.map(|_| None);
let mut cost = 100;
// FIXME: this works because only words uses termsmatchingstrategy at the moment.
for ns in removal_order {
for n in ns.iter() {
*costs.get_mut(n) = Some((cost, forbidden_nodes.clone()));
*costs.get_mut(n) = Some((1, forbidden_nodes.clone()));
}
forbidden_nodes.union(&ns);
cost += 100;
}
costs
}
@ -162,12 +177,16 @@ impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBase
// Then pre-compute the cost of all paths from each node to the end node
let all_costs = graph.find_all_costs_to_end();
next_max_cost +=
all_costs.get(graph.query_graph.root_node).iter().copied().max().unwrap_or(0);
let state = GraphBasedRankingRuleState {
graph,
conditions_cache: condition_docids_cache,
dead_ends_cache,
all_costs,
cur_cost: 0,
next_max_cost,
};
self.state = Some(state);
@ -181,17 +200,13 @@ impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBase
logger: &mut dyn SearchLogger<QueryGraph>,
universe: &RoaringBitmap,
) -> Result<Option<RankingRuleOutput<QueryGraph>>> {
// If universe.len() <= 1, the bucket sort algorithm
// should not have called this function.
assert!(universe.len() > 1);
// Will crash if `next_bucket` is called before `start_iteration` or after `end_iteration`,
// should never happen
let mut state = self.state.take().unwrap();
let all_costs = state.all_costs.get(state.graph.query_graph.root_node);
// Retrieve the cost of the paths to compute
let Some(&cost) = state
.all_costs
.get(state.graph.query_graph.root_node)
let Some(&cost) = all_costs
.iter()
.find(|c| **c >= state.cur_cost) else {
self.state = None;
@ -207,8 +222,12 @@ impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBase
dead_ends_cache,
all_costs,
cur_cost: _,
next_max_cost,
} = &mut state;
let rank = *next_max_cost - cost;
let score = G::rank_to_score(Rank { rank: rank as u32, max_rank: *next_max_cost as u32 });
let mut universe = universe.clone();
let mut used_conditions = SmallBitmap::for_interned_values_in(&graph.conditions_interner);
@ -295,8 +314,6 @@ impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBase
// We modify the next query graph so that it only contains the subgraph
// that was used to compute this bucket
// But we only do it in case the bucket length is >1, because otherwise
// we know the child ranking rule won't be called anyway
let paths: Vec<Vec<(Option<LocatedQueryTermSubset>, LocatedQueryTermSubset)>> = good_paths
.into_iter()
@ -325,7 +342,7 @@ impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBase
self.state = Some(state);
Ok(Some(RankingRuleOutput { query: next_query_graph, candidates: bucket }))
Ok(Some(RankingRuleOutput { query: next_query_graph, candidates: bucket, score }))
}
fn end_iteration(

View File

@ -510,6 +510,7 @@ mod tests {
&mut ctx,
&Some(query.to_string()),
crate::TermsMatchingStrategy::default(),
crate::score_details::ScoringStrategy::Skip,
false,
&None,
&None,

View File

@ -44,6 +44,7 @@ use self::geo_sort::GeoSort;
pub use self::geo_sort::Strategy as GeoSortStrategy;
use self::graph_based_ranking_rule::Words;
use self::interner::Interned;
use crate::score_details::{ScoreDetails, ScoringStrategy};
use crate::search::new::distinct::apply_distinct_rule;
use crate::{AscDesc, DocumentId, Filter, Index, Member, Result, TermsMatchingStrategy, UserError};
@ -350,6 +351,7 @@ pub fn execute_search(
ctx: &mut SearchContext,
query: &Option<String>,
terms_matching_strategy: TermsMatchingStrategy,
scoring_strategy: ScoringStrategy,
exhaustive_number_hits: bool,
filters: &Option<Filter>,
sort_criteria: &Option<Vec<AscDesc>>,
@ -411,7 +413,16 @@ pub fn execute_search(
universe =
resolve_universe(ctx, &universe, &graph, terms_matching_strategy, query_graph_logger)?;
bucket_sort(ctx, ranking_rules, &graph, &universe, from, length, query_graph_logger)?
bucket_sort(
ctx,
ranking_rules,
&graph,
&universe,
from,
length,
scoring_strategy,
query_graph_logger,
)?
} else {
let ranking_rules =
get_ranking_rules_for_placeholder_search(ctx, sort_criteria, geo_strategy)?;
@ -422,17 +433,20 @@ pub fn execute_search(
&universe,
from,
length,
scoring_strategy,
placeholder_search_logger,
)?
};
let BucketSortOutput { docids, mut all_candidates } = bucket_sort_output;
let BucketSortOutput { docids, scores, mut all_candidates } = bucket_sort_output;
let fields_ids_map = ctx.index.fields_ids_map(ctx.txn)?;
// The candidates is the universe unless the exhaustive number of hits
// is requested and a distinct attribute is set.
if exhaustive_number_hits {
if let Some(f) = ctx.index.distinct_field(ctx.txn)? {
if let Some(distinct_fid) = ctx.index.fields_ids_map(ctx.txn)?.id(f) {
if let Some(distinct_fid) = fields_ids_map.id(f) {
all_candidates = apply_distinct_rule(ctx, distinct_fid, &all_candidates)?.remaining;
}
}
@ -440,6 +454,7 @@ pub fn execute_search(
Ok(PartialSearchResult {
candidates: all_candidates,
document_scores: scores,
documents_ids: docids,
located_query_terms,
})
@ -491,4 +506,5 @@ pub struct PartialSearchResult {
pub located_query_terms: Option<Vec<LocatedQueryTerm>>,
pub candidates: RoaringBitmap,
pub documents_ids: Vec<DocumentId>,
pub document_scores: Vec<Vec<ScoreDetails>>,
}

View File

@ -342,6 +342,25 @@ impl QueryGraph {
}
res
}
/// Number of words in the phrases in this query graph
pub(crate) fn words_in_phrases_count(&self, ctx: &SearchContext) -> usize {
let mut word_count = 0;
for (_, node) in self.nodes.iter() {
match &node.data {
QueryNodeData::Term(term) => {
let Some(phrase) = term.term_subset.original_phrase(ctx)
else {
continue
};
let phrase = ctx.phrase_interner.get(phrase);
word_count += phrase.words.iter().copied().filter(|a| a.is_some()).count()
}
_ => continue,
}
}
word_count
}
}
fn add_node(nodes_data: &mut Vec<QueryNodeData>, node_data: QueryNodeData) -> u16 {

View File

@ -49,10 +49,15 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
if let Some((cost_of_ignoring, forbidden_nodes)) =
cost_of_ignoring_node.get(dest_idx)
{
let dest = graph_nodes.get(dest_idx);
let dest_size = match &dest.data {
QueryNodeData::Term(term) => term.term_ids.len(),
_ => panic!(),
};
let new_edge_id = edges_store.insert(Some(Edge {
source_node: source_id,
dest_node: dest_idx,
cost: *cost_of_ignoring,
cost: *cost_of_ignoring * dest_size as u32,
condition: None,
nodes_to_skip: forbidden_nodes.clone(),
}));

View File

@ -1,6 +1,7 @@
use roaring::RoaringBitmap;
use super::{ComputedCondition, RankingRuleGraphTrait};
use crate::score_details::{Rank, ScoreDetails};
use crate::search::new::interner::{DedupInterner, Interned};
use crate::search::new::query_term::{ExactTerm, LocatedQueryTermSubset};
use crate::search::new::resolve_query_graph::compute_query_term_subset_docids;
@ -84,4 +85,8 @@ impl RankingRuleGraphTrait for ExactnessGraph {
Ok(vec![(0, exact_condition), (dest_node.term_ids.len() as u32, skip_condition)])
}
fn rank_to_score(rank: Rank) -> ScoreDetails {
ScoreDetails::Exactness(rank)
}
}

View File

@ -2,6 +2,7 @@ use fxhash::FxHashSet;
use roaring::RoaringBitmap;
use super::{ComputedCondition, RankingRuleGraphTrait};
use crate::score_details::{Rank, ScoreDetails};
use crate::search::new::interner::{DedupInterner, Interned};
use crate::search::new::query_term::LocatedQueryTermSubset;
use crate::search::new::resolve_query_graph::compute_query_term_subset_docids_within_field_id;
@ -68,7 +69,7 @@ impl RankingRuleGraphTrait for FidGraph {
}
let mut edges = vec![];
for fid in all_fields {
for fid in all_fields.iter().copied() {
// TODO: We can improve performances and relevancy by storing
// the term subsets associated to each field ids fetched.
edges.push((
@ -80,6 +81,35 @@ impl RankingRuleGraphTrait for FidGraph {
));
}
// always lookup the max_fid if we don't already and add an artificial condition for max scoring
let max_fid: Option<u16> = {
if let Some(max_fid) = ctx
.index
.searchable_fields_ids(ctx.txn)?
.map(|field_ids| field_ids.into_iter().max())
{
max_fid
} else {
ctx.index.fields_ids_map(ctx.txn)?.ids().max()
}
};
if let Some(max_fid) = max_fid {
if !all_fields.contains(&max_fid) {
edges.push((
max_fid as u32 * term.term_ids.len() as u32, // TODO improve the fid score i.e. fid^10.
conditions_interner.insert(FidCondition {
term: term.clone(), // TODO remove this ugly clone
fid: max_fid,
}),
));
}
}
Ok(edges)
}
fn rank_to_score(rank: Rank) -> ScoreDetails {
ScoreDetails::Fid(rank)
}
}

View File

@ -41,6 +41,7 @@ use super::interner::{DedupInterner, FixedSizeInterner, Interned, MappedInterner
use super::query_term::LocatedQueryTermSubset;
use super::small_bitmap::SmallBitmap;
use super::{QueryGraph, QueryNode, SearchContext};
use crate::score_details::{Rank, ScoreDetails};
use crate::Result;
pub struct ComputedCondition {
@ -110,6 +111,9 @@ pub trait RankingRuleGraphTrait: Sized + 'static {
source_node: Option<&LocatedQueryTermSubset>,
dest_node: &LocatedQueryTermSubset,
) -> Result<Vec<(u32, Interned<Self::Condition>)>>;
/// Convert the rank of a path to its corresponding score for the ranking rule
fn rank_to_score(rank: Rank) -> ScoreDetails;
}
/// The graph used by graph-based ranking rules.

View File

@ -2,6 +2,7 @@ use fxhash::{FxHashMap, FxHashSet};
use roaring::RoaringBitmap;
use super::{ComputedCondition, RankingRuleGraphTrait};
use crate::score_details::{Rank, ScoreDetails};
use crate::search::new::interner::{DedupInterner, Interned};
use crate::search::new::query_term::LocatedQueryTermSubset;
use crate::search::new::resolve_query_graph::compute_query_term_subset_docids_within_position;
@ -77,6 +78,8 @@ impl RankingRuleGraphTrait for PositionGraph {
let mut positions_for_costs = FxHashMap::<u32, Vec<u16>>::default();
for position in all_positions {
// FIXME: bucketed position???
let distance = position.abs_diff(*term.positions.start());
let cost = {
let mut cost = 0;
for i in 0..term.term_ids.len() {
@ -84,15 +87,17 @@ impl RankingRuleGraphTrait for PositionGraph {
// Because if two words are in the same bucketed position (e.g. 32) and consecutive,
// then their position cost will be 32+32=64, but an ngram of these two words at the
// same position will have a cost of 32+32+1=65
cost += cost_from_position(position as u32 + i as u32);
cost += cost_from_distance(distance as u32 + i as u32);
}
cost
};
positions_for_costs.entry(cost).or_default().push(position);
}
let mut edges = vec![];
let max_cost = term.term_ids.len() as u32 * 10;
let max_cost_exists = positions_for_costs.contains_key(&max_cost);
let mut edges = vec![];
for (cost, positions) in positions_for_costs {
// TODO: We can improve performances and relevancy by storing
// the term subsets associated to each position fetched
@ -105,12 +110,25 @@ impl RankingRuleGraphTrait for PositionGraph {
));
}
if !max_cost_exists {
// artificial empty condition for computing max cost
edges.push((
max_cost,
conditions_interner
.insert(PositionCondition { term: term.clone(), positions: Vec::default() }),
));
}
Ok(edges)
}
fn rank_to_score(rank: Rank) -> ScoreDetails {
ScoreDetails::Position(rank)
}
}
fn cost_from_position(sum_positions: u32) -> u32 {
match sum_positions {
fn cost_from_distance(distance: u32) -> u32 {
match distance {
0 => 0,
1 => 1,
2..=4 => 2,

View File

@ -12,11 +12,11 @@ pub fn build_edges(
left_term: Option<&LocatedQueryTermSubset>,
right_term: &LocatedQueryTermSubset,
) -> Result<Vec<(u32, Interned<ProximityCondition>)>> {
let right_ngram_length = right_term.term_ids.len();
let right_ngram_max = right_term.term_ids.len().saturating_sub(1);
let Some(left_term) = left_term else {
return Ok(vec![(
(right_ngram_length - 1) as u32,
right_ngram_max as u32,
conditions_interner.insert(ProximityCondition::Term { term: right_term.clone() }),
)])
};
@ -29,25 +29,25 @@ pub fn build_edges(
// The remaining query graph represents `the sun .. are beautiful`
// but `sun` and `are` have no proximity condition between them
return Ok(vec![(
(right_ngram_length - 1) as u32,
right_ngram_max as u32,
conditions_interner.insert(ProximityCondition::Term { term: right_term.clone() }),
)]);
}
let mut conditions = vec![];
for cost in right_ngram_length..(7 + right_ngram_length) {
for cost in right_ngram_max..(7 + right_ngram_max) {
conditions.push((
cost as u32,
conditions_interner.insert(ProximityCondition::Uninit {
left_term: left_term.clone(),
right_term: right_term.clone(),
cost: cost as u8,
cost: (cost + 1) as u8,
}),
))
}
conditions.push((
(7 + right_ngram_length) as u32,
(7 + right_ngram_max) as u32,
conditions_interner.insert(ProximityCondition::Term { term: right_term.clone() }),
));

View File

@ -4,6 +4,7 @@ pub mod compute_docids;
use roaring::RoaringBitmap;
use super::{ComputedCondition, RankingRuleGraphTrait};
use crate::score_details::{Rank, ScoreDetails};
use crate::search::new::interner::{DedupInterner, Interned};
use crate::search::new::query_term::LocatedQueryTermSubset;
use crate::search::new::SearchContext;
@ -36,4 +37,8 @@ impl RankingRuleGraphTrait for ProximityGraph {
) -> Result<Vec<(u32, Interned<Self::Condition>)>> {
build::build_edges(ctx, conditions_interner, source_term, dest_term)
}
fn rank_to_score(rank: Rank) -> ScoreDetails {
ScoreDetails::Proximity(rank)
}
}

View File

@ -1,6 +1,7 @@
use roaring::RoaringBitmap;
use super::{ComputedCondition, RankingRuleGraphTrait};
use crate::score_details::{self, Rank, ScoreDetails};
use crate::search::new::interner::{DedupInterner, Interned};
use crate::search::new::query_term::LocatedQueryTermSubset;
use crate::search::new::resolve_query_graph::compute_query_term_subset_docids;
@ -75,4 +76,8 @@ impl RankingRuleGraphTrait for TypoGraph {
}
Ok(edges)
}
fn rank_to_score(rank: Rank) -> ScoreDetails {
ScoreDetails::Typo(score_details::Typo::from_rank(rank))
}
}

View File

@ -1,6 +1,7 @@
use roaring::RoaringBitmap;
use super::{ComputedCondition, RankingRuleGraphTrait};
use crate::score_details::{self, Rank, ScoreDetails};
use crate::search::new::interner::{DedupInterner, Interned};
use crate::search::new::query_term::LocatedQueryTermSubset;
use crate::search::new::resolve_query_graph::compute_query_term_subset_docids;
@ -41,9 +42,10 @@ impl RankingRuleGraphTrait for WordsGraph {
_from: Option<&LocatedQueryTermSubset>,
to_term: &LocatedQueryTermSubset,
) -> Result<Vec<(u32, Interned<Self::Condition>)>> {
Ok(vec![(
to_term.term_ids.len() as u32,
conditions_interner.insert(WordsCondition { term: to_term.clone() }),
)])
Ok(vec![(0, conditions_interner.insert(WordsCondition { term: to_term.clone() }))])
}
fn rank_to_score(rank: Rank) -> ScoreDetails {
ScoreDetails::Words(score_details::Words::from_rank(rank))
}
}

View File

@ -2,6 +2,7 @@ use roaring::RoaringBitmap;
use super::logger::SearchLogger;
use super::{QueryGraph, SearchContext};
use crate::score_details::ScoreDetails;
use crate::Result;
/// An internal trait implemented by only [`PlaceholderQuery`] and [`QueryGraph`]
@ -66,4 +67,6 @@ pub struct RankingRuleOutput<Q> {
pub query: Q,
/// The allowed candidates for the child ranking rule
pub candidates: RoaringBitmap,
/// The score for the candidates of the current bucket
pub score: ScoreDetails,
}

View File

@ -1,9 +1,11 @@
use heed::BytesDecode;
use roaring::RoaringBitmap;
use super::logger::SearchLogger;
use super::{RankingRule, RankingRuleOutput, RankingRuleQueryTrait, SearchContext};
use crate::heed_codec::facet::FacetGroupKeyCodec;
use crate::heed_codec::ByteSliceRefCodec;
use crate::heed_codec::facet::{FacetGroupKeyCodec, OrderedF64Codec};
use crate::heed_codec::{ByteSliceRefCodec, StrRefCodec};
use crate::score_details::{self, ScoreDetails};
use crate::search::facet::{ascending_facet_sort, descending_facet_sort};
use crate::{FieldId, Index, Result};
@ -49,6 +51,7 @@ pub struct Sort<'ctx, Query> {
is_ascending: bool,
original_query: Option<Query>,
iter: Option<RankingRuleOutputIterWrapper<'ctx, Query>>,
must_redact: bool,
}
impl<'ctx, Query> Sort<'ctx, Query> {
pub fn new(
@ -59,15 +62,30 @@ impl<'ctx, Query> Sort<'ctx, Query> {
) -> Result<Self> {
let fields_ids_map = index.fields_ids_map(rtxn)?;
let field_id = fields_ids_map.id(&field_name);
let must_redact = Self::must_redact(index, rtxn, &field_name)?;
Ok(Self { field_name, field_id, is_ascending, original_query: None, iter: None })
Ok(Self {
field_name,
field_id,
is_ascending,
original_query: None,
iter: None,
must_redact,
})
}
fn must_redact(index: &Index, rtxn: &'ctx heed::RoTxn, field_name: &str) -> Result<bool> {
let Some(displayed_fields) = index.displayed_fields(rtxn)?
else { return Ok(false); };
Ok(!displayed_fields.iter().any(|&field| field == field_name))
}
}
impl<'ctx, Query: RankingRuleQueryTrait> RankingRule<'ctx, Query> for Sort<'ctx, Query> {
fn id(&self) -> String {
let Self { field_name, is_ascending, .. } = self;
format!("{field_name}:{}", if *is_ascending { "asc" } else { "desc " })
format!("{field_name}:{}", if *is_ascending { "asc" } else { "desc" })
}
fn start_iteration(
&mut self,
@ -118,12 +136,45 @@ impl<'ctx, Query: RankingRuleQueryTrait> RankingRule<'ctx, Query> for Sort<'ctx,
(itertools::Either::Right(number_iter), itertools::Either::Right(string_iter))
};
let number_iter = number_iter.map(|r| -> Result<_> {
let (docids, bytes) = r?;
Ok((
docids,
serde_json::Value::Number(
serde_json::Number::from_f64(
OrderedF64Codec::bytes_decode(bytes).expect("some number"),
)
.expect("too big float"),
),
))
});
let string_iter = string_iter.map(|r| -> Result<_> {
let (docids, bytes) = r?;
Ok((
docids,
serde_json::Value::String(
StrRefCodec::bytes_decode(bytes).expect("some string").to_owned(),
),
))
});
let query_graph = parent_query.clone();
let ascending = self.is_ascending;
let field_name = self.field_name.clone();
let must_redact = self.must_redact;
RankingRuleOutputIterWrapper::new(Box::new(number_iter.chain(string_iter).map(
move |r| {
let (docids, _) = r?;
Ok(RankingRuleOutput { query: query_graph.clone(), candidates: docids })
let (docids, value) = r?;
Ok(RankingRuleOutput {
query: query_graph.clone(),
candidates: docids,
score: ScoreDetails::Sort(score_details::Sort {
field_name: field_name.clone(),
ascending,
redacted: must_redact,
value,
}),
})
},
)))
}
@ -150,7 +201,16 @@ impl<'ctx, Query: RankingRuleQueryTrait> RankingRule<'ctx, Query> for Sort<'ctx,
Ok(Some(bucket))
} else {
let query = self.original_query.as_ref().unwrap().clone();
Ok(Some(RankingRuleOutput { query, candidates: universe.clone() }))
Ok(Some(RankingRuleOutput {
query,
candidates: universe.clone(),
score: ScoreDetails::Sort(score_details::Sort {
field_name: self.field_name.clone(),
ascending: self.is_ascending,
redacted: self.must_redact,
value: serde_json::Value::Null,
}),
}))
}
}

View File

@ -122,8 +122,11 @@ fn test_attribute_fid_simple() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[2, 6, 5, 4, 3, 9, 7, 8, 11, 10, 12, 13, 14, 0]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
}
#[test]
@ -135,6 +138,11 @@ fn test_attribute_fid_ngrams() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[2, 6, 5, 4, 3, 9, 7, 8, 11, 10, 12, 13, 14, 0]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
}

View File

@ -40,68 +40,68 @@ fn create_index() -> TempIndex {
},
{
"id": 5,
"text": "a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
"text": "a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
the quick brown fox",
},
{
"id": 6,
"text": "quick a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
"text": "quick a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
brown",
},
{
"id": 7,
"text": "a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
"text": "a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
quickbrown",
},
{
"id": 8,
"text": "a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
"text": "a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
quick brown",
},
{
"id": 9,
"text": "a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
"text": "a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a
quickbrown",
},
{
@ -137,8 +137,13 @@ fn test_attribute_position_simple() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("quick brown");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[10, 11, 12, 13, 2, 3, 4, 1, 0, 6, 8, 7, 9, 5]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
}
#[test]
fn test_attribute_position_repeated() {
@ -149,8 +154,13 @@ fn test_attribute_position_repeated() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("a a a a a");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[5, 7, 8, 9, 6]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
}
#[test]
@ -162,8 +172,13 @@ fn test_attribute_position_different_fields() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("quick brown");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[10, 11, 12, 13, 2, 3, 4, 1, 0, 6, 8, 7, 9, 5]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
}
#[test]
@ -175,6 +190,11 @@ fn test_attribute_position_ngrams() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("quick brown");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[10, 11, 12, 13, 2, 3, 4, 1, 0, 6, 8, 7, 9, 5]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
}

View File

@ -474,8 +474,14 @@ fn test_exactness_simple_ordered() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 8, 7, 6, 5, 4, 3, 2, 1]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@ -501,8 +507,14 @@ fn test_exactness_simple_reversed() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 8, 3, 4, 5, 6, 7]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@ -519,8 +531,14 @@ fn test_exactness_simple_reversed() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 8, 3, 4, 5, 6, 7]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@ -544,8 +562,14 @@ fn test_exactness_simple_random() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[8, 7, 4, 6, 3, 5]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@ -568,8 +592,14 @@ fn test_exactness_attribute_starts_with_simple() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.query("this balcony");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[2, 1, 0]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@ -589,8 +619,14 @@ fn test_exactness_attribute_starts_with_phrase() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.query("\"overlooking the sea\" is a beautiful balcony");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[6, 5, 4, 1]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@ -604,8 +640,14 @@ fn test_exactness_attribute_starts_with_phrase() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.query("overlooking the sea is a beautiful balcony");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[6, 5, 4, 3, 1, 7]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@ -628,8 +670,14 @@ fn test_exactness_all_candidates_with_typo() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.query("overlocking the sea is a beautiful balcony");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[4, 5, 6, 1, 7]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
// "overlooking" is returned here because the term matching strategy allows it
// but it has the worst exactness score (0 exact words)
@ -659,8 +707,14 @@ fn test_exactness_after_words() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[19, 9, 18, 8, 17, 16, 6, 7, 15, 5, 14, 4, 13, 3, 12, 2, 1, 11]");
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
@ -702,7 +756,13 @@ fn test_words_after_exactness() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[19, 9, 18, 8, 17, 16, 6, 7, 15, 5, 14, 4, 13, 3, 12, 2, 1, 11]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
@ -745,7 +805,14 @@ fn test_proximity_after_exactness() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[2, 1, 0, 4, 5, 8, 7, 3, 6]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
@ -776,7 +843,13 @@ fn test_proximity_after_exactness() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[0, 1, 2]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
@ -804,7 +877,13 @@ fn test_exactness_followed_by_typo_prefer_no_typo_prefix() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.query("quick brown fox extra");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[2, 1, 0, 4, 3]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
@ -834,7 +913,13 @@ fn test_typo_followed_by_exactness() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.query("extraordinarily quick brown fox");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_ids_scores: Vec<_> =
documents_ids.iter().zip(document_scores.into_iter()).collect();
insta::assert_snapshot!(format!("{document_ids_scores:#?}"));
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[1, 0, 4, 3]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);

View File

@ -7,6 +7,7 @@ use heed::RoTxn;
use maplit::hashset;
use crate::index::tests::TempIndex;
use crate::score_details::ScoreDetails;
use crate::search::new::tests::collect_field_values;
use crate::{AscDesc, Criterion, GeoSortStrategy, Member, Search, SearchResult};
@ -28,30 +29,37 @@ fn execute_iterative_and_rtree_returns_the_same<'a>(
rtxn: &RoTxn<'a>,
index: &TempIndex,
search: &mut Search<'a>,
) -> Vec<usize> {
) -> (Vec<usize>, Vec<Vec<ScoreDetails>>) {
search.geo_sort_strategy(GeoSortStrategy::AlwaysIterative(2));
let SearchResult { documents_ids, .. } = search.execute().unwrap();
let SearchResult { documents_ids, document_scores: iterative_scores_bucketed, .. } =
search.execute().unwrap();
let iterative_ids_bucketed = collect_field_values(index, rtxn, "id", &documents_ids);
search.geo_sort_strategy(GeoSortStrategy::AlwaysIterative(1000));
let SearchResult { documents_ids, .. } = search.execute().unwrap();
let SearchResult { documents_ids, document_scores: iterative_scores, .. } =
search.execute().unwrap();
let iterative_ids = collect_field_values(index, rtxn, "id", &documents_ids);
assert_eq!(iterative_ids_bucketed, iterative_ids, "iterative bucket");
assert_eq!(iterative_scores_bucketed, iterative_scores, "iterative bucket score");
search.geo_sort_strategy(GeoSortStrategy::AlwaysRtree(2));
let SearchResult { documents_ids, .. } = search.execute().unwrap();
let SearchResult { documents_ids, document_scores: rtree_scores_bucketed, .. } =
search.execute().unwrap();
let rtree_ids_bucketed = collect_field_values(index, rtxn, "id", &documents_ids);
search.geo_sort_strategy(GeoSortStrategy::AlwaysRtree(1000));
let SearchResult { documents_ids, .. } = search.execute().unwrap();
let SearchResult { documents_ids, document_scores: rtree_scores, .. } =
search.execute().unwrap();
let rtree_ids = collect_field_values(index, rtxn, "id", &documents_ids);
assert_eq!(rtree_ids_bucketed, rtree_ids, "rtree bucket");
assert_eq!(rtree_scores_bucketed, rtree_scores, "rtree bucket score");
assert_eq!(iterative_ids, rtree_ids, "iterative vs rtree");
assert_eq!(iterative_scores, rtree_scores, "iterative vs rtree scores");
iterative_ids.into_iter().map(|id| id.parse().unwrap()).collect()
(iterative_ids.into_iter().map(|id| id.parse().unwrap()).collect(), iterative_scores)
}
#[test]
@ -73,14 +81,17 @@ fn test_geo_sort() {
let rtxn = index.read_txn().unwrap();
let mut s = Search::new(&rtxn, &index);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.sort_criteria(vec![AscDesc::Asc(Member::Geo([0., 0.]))]);
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[0, 1, 2, 3, 4, 5, 6, 8, 7, 10, 9]");
insta::assert_snapshot!(format!("{scores:#?}"));
s.sort_criteria(vec![AscDesc::Desc(Member::Geo([0., 0.]))]);
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[5, 4, 3, 2, 1, 0, 6, 8, 7, 10, 9]");
insta::assert_snapshot!(format!("{scores:#?}"));
}
#[test]
@ -101,52 +112,63 @@ fn test_geo_sort_around_the_edge_of_the_flat_earth() {
let rtxn = index.read_txn().unwrap();
let mut s = Search::new(&rtxn, &index);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
// --- asc
s.sort_criteria(vec![AscDesc::Asc(Member::Geo([0., 0.]))]);
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[0, 1, 2, 3, 4]");
insta::assert_snapshot!(format!("{scores:#?}"));
// ensuring the lat doesn't wrap around
s.sort_criteria(vec![AscDesc::Asc(Member::Geo([85., 0.]))]);
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[1, 0, 3, 4, 2]");
insta::assert_snapshot!(format!("{scores:#?}"));
s.sort_criteria(vec![AscDesc::Asc(Member::Geo([-85., 0.]))]);
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[2, 0, 3, 4, 1]");
insta::assert_snapshot!(format!("{scores:#?}"));
// ensuring the lng does wrap around
s.sort_criteria(vec![AscDesc::Asc(Member::Geo([0., 175.]))]);
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[3, 4, 2, 1, 0]");
insta::assert_snapshot!(format!("{scores:#?}"));
s.sort_criteria(vec![AscDesc::Asc(Member::Geo([0., -175.]))]);
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[4, 3, 2, 1, 0]");
insta::assert_snapshot!(format!("{scores:#?}"));
// --- desc
s.sort_criteria(vec![AscDesc::Desc(Member::Geo([0., 0.]))]);
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[4, 3, 2, 1, 0]");
insta::assert_snapshot!(format!("{scores:#?}"));
// ensuring the lat doesn't wrap around
s.sort_criteria(vec![AscDesc::Desc(Member::Geo([85., 0.]))]);
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[2, 4, 3, 0, 1]");
insta::assert_snapshot!(format!("{scores:#?}"));
s.sort_criteria(vec![AscDesc::Desc(Member::Geo([-85., 0.]))]);
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[1, 4, 3, 0, 2]");
insta::assert_snapshot!(format!("{scores:#?}"));
// ensuring the lng does wrap around
s.sort_criteria(vec![AscDesc::Desc(Member::Geo([0., 175.]))]);
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[0, 1, 2, 4, 3]");
insta::assert_snapshot!(format!("{scores:#?}"));
s.sort_criteria(vec![AscDesc::Desc(Member::Geo([0., -175.]))]);
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[0, 1, 2, 3, 4]");
insta::assert_snapshot!(format!("{scores:#?}"));
}
#[test]
@ -166,19 +188,98 @@ fn geo_sort_mixed_with_words() {
let rtxn = index.read_txn().unwrap();
let mut s = Search::new(&rtxn, &index);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.sort_criteria(vec![AscDesc::Asc(Member::Geo([0., 0.]))]);
s.query("jean");
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[0, 2, 3]");
insta::assert_snapshot!(format!("{scores:#?}"));
s.query("bob");
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[2, 4]");
insta::assert_snapshot!(format!("{scores:#?}"), @r###"
[
[
Words(
Words {
matching_words: 1,
max_matching_words: 1,
},
),
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
-89.0,
0.0,
],
),
},
),
],
[
Words(
Words {
matching_words: 1,
max_matching_words: 1,
},
),
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
0.0,
-179.0,
],
),
},
),
],
]
"###);
s.query("intel");
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[1]");
insta::assert_snapshot!(format!("{scores:#?}"), @r###"
[
[
Words(
Words {
matching_words: 1,
max_matching_words: 1,
},
),
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
88.0,
0.0,
],
),
},
),
],
]
"###);
}
#[test]
@ -198,9 +299,11 @@ fn geo_sort_without_any_geo_faceted_documents() {
let rtxn = index.read_txn().unwrap();
let mut s = Search::new(&rtxn, &index);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.sort_criteria(vec![AscDesc::Asc(Member::Geo([0., 0.]))]);
s.query("jean");
let ids = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
let (ids, scores) = execute_iterative_and_rtree_returns_the_same(&rtxn, &index, &mut s);
insta::assert_snapshot!(format!("{ids:?}"), @"[0, 2, 3]");
insta::assert_snapshot!(format!("{scores:#?}"));
}

View File

@ -80,10 +80,13 @@ fn test_2gram_simple() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("sun flower");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
// will also match documents with "sunflower" + prefix tolerance
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[0, 1, 2, 3, 5]");
// scores are empty because the only rule is Words with All matching strategy
insta::assert_snapshot!(format!("{document_scores:?}"), @"[[], [], [], [], []]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[

View File

@ -122,11 +122,11 @@ fn create_edge_cases_index() -> TempIndex {
sta stb stc ste stf stg sth sti stj stk stl stm stn sto stp stq str stst stt stu stv stw stx sty stz
"
},
// The next 5 documents lay out a trap with the split word, phrase search, or synonym `sun flower`.
// If the search query is "sunflower", the split word "Sun Flower" will match some documents.
// The next 5 documents lay out a trap with the split word, phrase search, or synonym `sun flower`.
// If the search query is "sunflower", the split word "Sun Flower" will match some documents.
// If the query is `sunflower wilting`, then we should make sure that
// the sprximity condition `flower wilting: sprx N` also comes with the condition
// `sun wilting: sprx N+1`. TODO: this is not the exact condition we use for now.
// `sun wilting: sprx N+1`. TODO: this is not the exact condition we use for now.
// We only check that the phrase `sun flower` exists and `flower wilting: sprx N`, which
// is better than nothing but not the best.
{
@ -139,7 +139,7 @@ fn create_edge_cases_index() -> TempIndex {
},
{
"id": 3,
// This document matches the query `sunflower wilting`, but the sprximity condition
// This document matches the query `sunflower wilting`, but the sprximity condition
// between `sunflower` and `wilting` cannot be through the split-word `Sun Flower`
// which would reduce to only `flower` and `wilting` being in sprximity.
"text": "A flower wilting under the sun, unlike a sunflower"
@ -270,13 +270,13 @@ fn test_proximity_simple() {
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[4, 9, 10, 7, 6, 5, 2, 3, 0, 1]");
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 10, 4, 7, 6, 5, 2, 3, 0, 1]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
"\"the quickbrown fox jumps over the lazy dog\"",
"\"the quack brown fox jumps over the lazy dog\"",
"\"the quick brown fox jumps over the lazy dog\"",
"\"the quickbrown fox jumps over the lazy dog\"",
"\"the really quick brown fox jumps over the lazy dog\"",
"\"the really quick brown fox jumps over the very lazy dog\"",
"\"brown quick fox jumps over the lazy dog\"",
@ -295,9 +295,12 @@ fn test_proximity_split_word() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("sunflower wilting");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[2, 4, 5, 1, 3]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
// TODO: "2" and "4" should be swapped ideally
insta::assert_debug_snapshot!(texts, @r###"
@ -312,9 +315,11 @@ fn test_proximity_split_word() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("\"sun flower\" wilting");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[2, 4, 1]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
// TODO: "2" and "4" should be swapped ideally
insta::assert_debug_snapshot!(texts, @r###"
@ -337,9 +342,11 @@ fn test_proximity_split_word() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("xyz wilting");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[2, 4, 1]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
// TODO: "2" and "4" should be swapped ideally
insta::assert_debug_snapshot!(texts, @r###"
@ -358,9 +365,11 @@ fn test_proximity_prefix_db() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("best s");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[10, 13, 9, 12, 8, 6, 7, 11, 15]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
// This test illustrates the loss of precision from using the prefix DB
@ -381,9 +390,11 @@ fn test_proximity_prefix_db() {
// Difference when using the `su` prefix, which is not in the prefix DB
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("best su");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[10, 13, 9, 12, 8, 11, 7, 6, 15]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
@ -406,9 +417,11 @@ fn test_proximity_prefix_db() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("best win");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[15, 16, 17, 18, 19, 20, 21, 22]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
@ -428,9 +441,11 @@ fn test_proximity_prefix_db() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("best wint");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[19, 22, 18, 21, 17, 20, 16, 15]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
@ -450,9 +465,11 @@ fn test_proximity_prefix_db() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("best wi");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[19, 22, 18, 21, 17, 15, 16, 20]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"

View File

@ -61,8 +61,41 @@ fn test_trap_basic() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("summer holiday");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[0, 1]");
insta::assert_snapshot!(format!("{document_scores:#?}"), @r###"
[
[
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 2,
},
),
],
[
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 2,
},
),
],
]
"###);
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
// TODO: this is incorrect, 1 should come before 0
insta::assert_debug_snapshot!(texts, @r###"

View File

@ -0,0 +1,244 @@
---
source: milli/src/search/new/tests/attribute_fid.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
2,
[
Fid(
Rank {
rank: 19,
max_rank: 19,
},
),
Position(
Rank {
rank: 91,
max_rank: 91,
},
),
],
),
(
6,
[
Fid(
Rank {
rank: 15,
max_rank: 19,
},
),
Position(
Rank {
rank: 81,
max_rank: 91,
},
),
],
),
(
5,
[
Fid(
Rank {
rank: 14,
max_rank: 19,
},
),
Position(
Rank {
rank: 79,
max_rank: 91,
},
),
],
),
(
4,
[
Fid(
Rank {
rank: 13,
max_rank: 19,
},
),
Position(
Rank {
rank: 77,
max_rank: 91,
},
),
],
),
(
3,
[
Fid(
Rank {
rank: 12,
max_rank: 19,
},
),
Position(
Rank {
rank: 83,
max_rank: 91,
},
),
],
),
(
9,
[
Fid(
Rank {
rank: 11,
max_rank: 19,
},
),
Position(
Rank {
rank: 75,
max_rank: 91,
},
),
],
),
(
8,
[
Fid(
Rank {
rank: 10,
max_rank: 19,
},
),
Position(
Rank {
rank: 79,
max_rank: 91,
},
),
],
),
(
7,
[
Fid(
Rank {
rank: 10,
max_rank: 19,
},
),
Position(
Rank {
rank: 73,
max_rank: 91,
},
),
],
),
(
11,
[
Fid(
Rank {
rank: 7,
max_rank: 19,
},
),
Position(
Rank {
rank: 77,
max_rank: 91,
},
),
],
),
(
10,
[
Fid(
Rank {
rank: 6,
max_rank: 19,
},
),
Position(
Rank {
rank: 81,
max_rank: 91,
},
),
],
),
(
13,
[
Fid(
Rank {
rank: 6,
max_rank: 19,
},
),
Position(
Rank {
rank: 81,
max_rank: 91,
},
),
],
),
(
12,
[
Fid(
Rank {
rank: 6,
max_rank: 19,
},
),
Position(
Rank {
rank: 78,
max_rank: 91,
},
),
],
),
(
14,
[
Fid(
Rank {
rank: 5,
max_rank: 19,
},
),
Position(
Rank {
rank: 75,
max_rank: 91,
},
),
],
),
(
0,
[
Fid(
Rank {
rank: 1,
max_rank: 19,
},
),
Position(
Rank {
rank: 91,
max_rank: 91,
},
),
],
),
]

View File

@ -0,0 +1,244 @@
---
source: milli/src/search/new/tests/attribute_fid.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
2,
[
Fid(
Rank {
rank: 19,
max_rank: 19,
},
),
Position(
Rank {
rank: 91,
max_rank: 91,
},
),
],
),
(
6,
[
Fid(
Rank {
rank: 15,
max_rank: 19,
},
),
Position(
Rank {
rank: 81,
max_rank: 91,
},
),
],
),
(
5,
[
Fid(
Rank {
rank: 14,
max_rank: 19,
},
),
Position(
Rank {
rank: 79,
max_rank: 91,
},
),
],
),
(
4,
[
Fid(
Rank {
rank: 13,
max_rank: 19,
},
),
Position(
Rank {
rank: 77,
max_rank: 91,
},
),
],
),
(
3,
[
Fid(
Rank {
rank: 12,
max_rank: 19,
},
),
Position(
Rank {
rank: 83,
max_rank: 91,
},
),
],
),
(
9,
[
Fid(
Rank {
rank: 11,
max_rank: 19,
},
),
Position(
Rank {
rank: 75,
max_rank: 91,
},
),
],
),
(
8,
[
Fid(
Rank {
rank: 10,
max_rank: 19,
},
),
Position(
Rank {
rank: 79,
max_rank: 91,
},
),
],
),
(
7,
[
Fid(
Rank {
rank: 10,
max_rank: 19,
},
),
Position(
Rank {
rank: 73,
max_rank: 91,
},
),
],
),
(
11,
[
Fid(
Rank {
rank: 7,
max_rank: 19,
},
),
Position(
Rank {
rank: 77,
max_rank: 91,
},
),
],
),
(
10,
[
Fid(
Rank {
rank: 6,
max_rank: 19,
},
),
Position(
Rank {
rank: 81,
max_rank: 91,
},
),
],
),
(
13,
[
Fid(
Rank {
rank: 6,
max_rank: 19,
},
),
Position(
Rank {
rank: 81,
max_rank: 91,
},
),
],
),
(
12,
[
Fid(
Rank {
rank: 6,
max_rank: 19,
},
),
Position(
Rank {
rank: 78,
max_rank: 91,
},
),
],
),
(
14,
[
Fid(
Rank {
rank: 5,
max_rank: 19,
},
),
Position(
Rank {
rank: 75,
max_rank: 91,
},
),
],
),
(
0,
[
Fid(
Rank {
rank: 1,
max_rank: 19,
},
),
Position(
Rank {
rank: 91,
max_rank: 91,
},
),
],
),
]

View File

@ -0,0 +1,244 @@
---
source: milli/src/search/new/tests/attribute_position.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
10,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 21,
max_rank: 21,
},
),
],
),
(
12,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 21,
max_rank: 21,
},
),
],
),
(
11,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 20,
max_rank: 21,
},
),
],
),
(
13,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 20,
max_rank: 21,
},
),
],
),
(
3,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 19,
max_rank: 21,
},
),
],
),
(
4,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 19,
max_rank: 21,
},
),
],
),
(
2,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 18,
max_rank: 21,
},
),
],
),
(
0,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 15,
max_rank: 21,
},
),
],
),
(
1,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 15,
max_rank: 21,
},
),
],
),
(
6,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 13,
max_rank: 21,
},
),
],
),
(
8,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 5,
max_rank: 21,
},
),
],
),
(
7,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 4,
max_rank: 21,
},
),
],
),
(
9,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 4,
max_rank: 21,
},
),
],
),
(
5,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 1,
max_rank: 21,
},
),
],
),
]

View File

@ -0,0 +1,244 @@
---
source: milli/src/search/new/tests/attribute_position.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
10,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 21,
max_rank: 21,
},
),
],
),
(
12,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 21,
max_rank: 21,
},
),
],
),
(
11,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 20,
max_rank: 21,
},
),
],
),
(
13,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 20,
max_rank: 21,
},
),
],
),
(
3,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 19,
max_rank: 21,
},
),
],
),
(
4,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 19,
max_rank: 21,
},
),
],
),
(
2,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 18,
max_rank: 21,
},
),
],
),
(
0,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 15,
max_rank: 21,
},
),
],
),
(
1,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 15,
max_rank: 21,
},
),
],
),
(
6,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 13,
max_rank: 21,
},
),
],
),
(
8,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 5,
max_rank: 21,
},
),
],
),
(
7,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 4,
max_rank: 21,
},
),
],
),
(
9,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 4,
max_rank: 21,
},
),
],
),
(
5,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 1,
max_rank: 21,
},
),
],
),
]

View File

@ -0,0 +1,91 @@
---
source: milli/src/search/new/tests/attribute_position.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
5,
[
Fid(
Rank {
rank: 11,
max_rank: 11,
},
),
Position(
Rank {
rank: 51,
max_rank: 51,
},
),
],
),
(
7,
[
Fid(
Rank {
rank: 11,
max_rank: 11,
},
),
Position(
Rank {
rank: 51,
max_rank: 51,
},
),
],
),
(
8,
[
Fid(
Rank {
rank: 11,
max_rank: 11,
},
),
Position(
Rank {
rank: 51,
max_rank: 51,
},
),
],
),
(
9,
[
Fid(
Rank {
rank: 11,
max_rank: 11,
},
),
Position(
Rank {
rank: 51,
max_rank: 51,
},
),
],
),
(
6,
[
Fid(
Rank {
rank: 11,
max_rank: 11,
},
),
Position(
Rank {
rank: 50,
max_rank: 51,
},
),
],
),
]

View File

@ -0,0 +1,244 @@
---
source: milli/src/search/new/tests/attribute_position.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
10,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 21,
max_rank: 21,
},
),
],
),
(
12,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 21,
max_rank: 21,
},
),
],
),
(
11,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 20,
max_rank: 21,
},
),
],
),
(
13,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 20,
max_rank: 21,
},
),
],
),
(
3,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 19,
max_rank: 21,
},
),
],
),
(
4,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 19,
max_rank: 21,
},
),
],
),
(
2,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 18,
max_rank: 21,
},
),
],
),
(
0,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 15,
max_rank: 21,
},
),
],
),
(
1,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 15,
max_rank: 21,
},
),
],
),
(
6,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 13,
max_rank: 21,
},
),
],
),
(
8,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 5,
max_rank: 21,
},
),
],
),
(
7,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 4,
max_rank: 21,
},
),
],
),
(
9,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 4,
max_rank: 21,
},
),
],
),
(
5,
[
Fid(
Rank {
rank: 5,
max_rank: 5,
},
),
Position(
Rank {
rank: 1,
max_rank: 21,
},
),
],
),
]

View File

@ -0,0 +1,366 @@
---
source: milli/src/search/new/tests/exactness.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
19,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 10,
max_rank: 10,
},
),
],
),
(
9,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 7,
max_rank: 10,
},
),
],
),
(
18,
[
Words(
Words {
matching_words: 8,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 9,
max_rank: 9,
},
),
],
),
(
8,
[
Words(
Words {
matching_words: 8,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 6,
max_rank: 9,
},
),
],
),
(
17,
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 8,
max_rank: 8,
},
),
],
),
(
16,
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 8,
max_rank: 8,
},
),
],
),
(
6,
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 5,
max_rank: 8,
},
),
],
),
(
7,
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 5,
max_rank: 8,
},
),
],
),
(
15,
[
Words(
Words {
matching_words: 5,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 6,
max_rank: 6,
},
),
],
),
(
5,
[
Words(
Words {
matching_words: 5,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 6,
},
),
],
),
(
14,
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 5,
max_rank: 5,
},
),
],
),
(
4,
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 5,
},
),
],
),
(
13,
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 4,
max_rank: 4,
},
),
],
),
(
3,
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 4,
},
),
],
),
(
12,
[
Words(
Words {
matching_words: 2,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 3,
},
),
],
),
(
2,
[
Words(
Words {
matching_words: 2,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 3,
},
),
],
),
(
1,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
(
11,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
]

View File

@ -0,0 +1,106 @@
---
source: milli/src/search/new/tests/exactness.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
4,
[
Words(
Words {
matching_words: 7,
max_matching_words: 7,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 7,
max_rank: 8,
},
),
],
),
(
5,
[
Words(
Words {
matching_words: 7,
max_matching_words: 7,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 7,
max_rank: 8,
},
),
],
),
(
6,
[
Words(
Words {
matching_words: 7,
max_matching_words: 7,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 7,
max_rank: 8,
},
),
],
),
(
1,
[
Words(
Words {
matching_words: 4,
max_matching_words: 7,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 4,
max_rank: 5,
},
),
],
),
(
7,
[
Words(
Words {
matching_words: 1,
max_matching_words: 7,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 1,
max_rank: 2,
},
),
],
),
]

View File

@ -0,0 +1,126 @@
---
source: milli/src/search/new/tests/exactness.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
6,
[
Words(
Words {
matching_words: 7,
max_matching_words: 7,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 8,
max_rank: 8,
},
),
],
),
(
5,
[
Words(
Words {
matching_words: 7,
max_matching_words: 7,
},
),
ExactAttribute(
MatchesStart,
),
Exactness(
Rank {
rank: 8,
max_rank: 8,
},
),
],
),
(
4,
[
Words(
Words {
matching_words: 7,
max_matching_words: 7,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 8,
max_rank: 8,
},
),
],
),
(
3,
[
Words(
Words {
matching_words: 7,
max_matching_words: 7,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 7,
max_rank: 8,
},
),
],
),
(
1,
[
Words(
Words {
matching_words: 4,
max_matching_words: 7,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 5,
max_rank: 5,
},
),
],
),
(
7,
[
Words(
Words {
matching_words: 1,
max_matching_words: 7,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
]

View File

@ -0,0 +1,86 @@
---
source: milli/src/search/new/tests/exactness.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
6,
[
Words(
Words {
matching_words: 7,
max_matching_words: 7,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 6,
max_rank: 6,
},
),
],
),
(
5,
[
Words(
Words {
matching_words: 7,
max_matching_words: 7,
},
),
ExactAttribute(
MatchesStart,
),
Exactness(
Rank {
rank: 6,
max_rank: 6,
},
),
],
),
(
4,
[
Words(
Words {
matching_words: 7,
max_matching_words: 7,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 6,
max_rank: 6,
},
),
],
),
(
1,
[
Words(
Words {
matching_words: 4,
max_matching_words: 7,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 3,
},
),
],
),
]

View File

@ -0,0 +1,66 @@
---
source: milli/src/search/new/tests/exactness.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
2,
[
Words(
Words {
matching_words: 2,
max_matching_words: 2,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 3,
},
),
],
),
(
1,
[
Words(
Words {
matching_words: 2,
max_matching_words: 2,
},
),
ExactAttribute(
MatchesStart,
),
Exactness(
Rank {
rank: 3,
max_rank: 3,
},
),
],
),
(
0,
[
Words(
Words {
matching_words: 2,
max_matching_words: 2,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 3,
},
),
],
),
]

View File

@ -0,0 +1,136 @@
---
source: milli/src/search/new/tests/exactness.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
2,
[
Words(
Words {
matching_words: 4,
max_matching_words: 4,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 5,
max_rank: 5,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 1,
},
),
],
),
(
1,
[
Words(
Words {
matching_words: 4,
max_matching_words: 4,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 4,
max_rank: 5,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 2,
},
),
],
),
(
0,
[
Words(
Words {
matching_words: 4,
max_matching_words: 4,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 4,
max_rank: 5,
},
),
Typo(
Typo {
typo_count: 1,
max_typo_count: 2,
},
),
],
),
(
4,
[
Words(
Words {
matching_words: 4,
max_matching_words: 4,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 4,
max_rank: 5,
},
),
Typo(
Typo {
typo_count: 1,
max_typo_count: 2,
},
),
],
),
(
3,
[
Words(
Words {
matching_words: 4,
max_matching_words: 4,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 5,
},
),
Typo(
Typo {
typo_count: 2,
max_typo_count: 3,
},
),
],
),
]

View File

@ -0,0 +1,186 @@
---
source: milli/src/search/new/tests/exactness.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
9,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 10,
max_rank: 10,
},
),
],
),
(
8,
[
Words(
Words {
matching_words: 8,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 9,
max_rank: 9,
},
),
],
),
(
7,
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 8,
max_rank: 8,
},
),
],
),
(
6,
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 8,
max_rank: 8,
},
),
],
),
(
5,
[
Words(
Words {
matching_words: 5,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 6,
max_rank: 6,
},
),
],
),
(
4,
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 5,
max_rank: 5,
},
),
],
),
(
3,
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 4,
max_rank: 4,
},
),
],
),
(
2,
[
Words(
Words {
matching_words: 2,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 3,
},
),
],
),
(
1,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
]

View File

@ -0,0 +1,126 @@
---
source: milli/src/search/new/tests/exactness.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
8,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 10,
max_rank: 10,
},
),
],
),
(
7,
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 4,
max_rank: 4,
},
),
],
),
(
4,
[
Words(
Words {
matching_words: 2,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 3,
},
),
],
),
(
6,
[
Words(
Words {
matching_words: 2,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 3,
},
),
],
),
(
3,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
(
5,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
]

View File

@ -0,0 +1,146 @@
---
source: milli/src/search/new/tests/exactness.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
9,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 10,
max_rank: 10,
},
),
],
),
(
8,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 10,
max_rank: 10,
},
),
],
),
(
3,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
MatchesStart,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
(
4,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
(
5,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
(
6,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
(
7,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
]

View File

@ -0,0 +1,146 @@
---
source: milli/src/search/new/tests/exactness.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
9,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 10,
max_rank: 10,
},
),
],
),
(
8,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 10,
max_rank: 10,
},
),
],
),
(
3,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
MatchesStart,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
(
4,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
(
5,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
(
6,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
(
7,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
]

View File

@ -0,0 +1,84 @@
---
source: milli/src/search/new/tests/exactness.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
0,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 10,
max_rank: 10,
},
),
Proximity(
Rank {
rank: 35,
max_rank: 57,
},
),
],
),
(
1,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 10,
max_rank: 10,
},
),
Proximity(
Rank {
rank: 35,
max_rank: 57,
},
),
],
),
(
2,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 10,
max_rank: 10,
},
),
Proximity(
Rank {
rank: 35,
max_rank: 57,
},
),
],
),
]

View File

@ -0,0 +1,240 @@
---
source: milli/src/search/new/tests/exactness.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
2,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 10,
max_rank: 10,
},
),
Proximity(
Rank {
rank: 57,
max_rank: 57,
},
),
],
),
(
1,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 10,
max_rank: 10,
},
),
Proximity(
Rank {
rank: 56,
max_rank: 57,
},
),
],
),
(
0,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 10,
max_rank: 10,
},
),
Proximity(
Rank {
rank: 35,
max_rank: 57,
},
),
],
),
(
4,
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
ExactAttribute(
MatchesStart,
),
Exactness(
Rank {
rank: 5,
max_rank: 5,
},
),
Proximity(
Rank {
rank: 22,
max_rank: 22,
},
),
],
),
(
5,
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
ExactAttribute(
MatchesStart,
),
Exactness(
Rank {
rank: 5,
max_rank: 5,
},
),
Proximity(
Rank {
rank: 22,
max_rank: 22,
},
),
],
),
(
8,
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
ExactAttribute(
MatchesStart,
),
Exactness(
Rank {
rank: 5,
max_rank: 5,
},
),
Proximity(
Rank {
rank: 22,
max_rank: 22,
},
),
],
),
(
7,
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 5,
max_rank: 5,
},
),
Proximity(
Rank {
rank: 21,
max_rank: 22,
},
),
],
),
(
3,
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 5,
max_rank: 5,
},
),
Proximity(
Rank {
rank: 17,
max_rank: 22,
},
),
],
),
(
6,
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 5,
max_rank: 5,
},
),
Proximity(
Rank {
rank: 17,
max_rank: 22,
},
),
],
),
]

View File

@ -0,0 +1,110 @@
---
source: milli/src/search/new/tests/exactness.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
1,
[
Words(
Words {
matching_words: 4,
max_matching_words: 4,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 5,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 5,
max_rank: 5,
},
),
],
),
(
0,
[
Words(
Words {
matching_words: 4,
max_matching_words: 4,
},
),
Typo(
Typo {
typo_count: 1,
max_typo_count: 5,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 4,
max_rank: 5,
},
),
],
),
(
4,
[
Words(
Words {
matching_words: 4,
max_matching_words: 4,
},
),
Typo(
Typo {
typo_count: 2,
max_typo_count: 5,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 4,
max_rank: 5,
},
),
],
),
(
3,
[
Words(
Words {
matching_words: 4,
max_matching_words: 4,
},
),
Typo(
Typo {
typo_count: 2,
max_typo_count: 5,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 5,
},
),
],
),
]

View File

@ -0,0 +1,366 @@
---
source: milli/src/search/new/tests/exactness.rs
expression: "format!(\"{document_ids_scores:#?}\")"
---
[
(
19,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 10,
max_rank: 10,
},
),
],
),
(
9,
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 7,
max_rank: 10,
},
),
],
),
(
18,
[
Words(
Words {
matching_words: 8,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 9,
max_rank: 9,
},
),
],
),
(
8,
[
Words(
Words {
matching_words: 8,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 6,
max_rank: 9,
},
),
],
),
(
17,
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 8,
max_rank: 8,
},
),
],
),
(
16,
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 8,
max_rank: 8,
},
),
],
),
(
6,
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 5,
max_rank: 8,
},
),
],
),
(
7,
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 5,
max_rank: 8,
},
),
],
),
(
15,
[
Words(
Words {
matching_words: 5,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 6,
max_rank: 6,
},
),
],
),
(
5,
[
Words(
Words {
matching_words: 5,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 6,
},
),
],
),
(
14,
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 5,
max_rank: 5,
},
),
],
),
(
4,
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 5,
},
),
],
),
(
13,
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 4,
max_rank: 4,
},
),
],
),
(
3,
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 4,
},
),
],
),
(
12,
[
Words(
Words {
matching_words: 2,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 3,
},
),
],
),
(
2,
[
Words(
Words {
matching_words: 2,
max_matching_words: 9,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 3,
},
),
],
),
(
1,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
(
11,
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
ExactAttribute(
ExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
),
]

View File

@ -0,0 +1,168 @@
---
source: milli/src/search/new/tests/geo_sort.rs
expression: "format!(\"{scores:#?}\")"
---
[
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
0.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
1.0,
1.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
2.0,
-1.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
-2.0,
-2.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
3.0,
5.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
6.0,
-5.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: None,
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: None,
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: None,
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: None,
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: None,
},
),
],
]

View File

@ -0,0 +1,168 @@
---
source: milli/src/search/new/tests/geo_sort.rs
expression: "format!(\"{scores:#?}\")"
---
[
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: Some(
[
6.0,
-5.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: Some(
[
3.0,
5.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: Some(
[
-2.0,
-2.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: Some(
[
2.0,
-1.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: Some(
[
1.0,
1.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: Some(
[
0.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: None,
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: None,
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: None,
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: None,
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: None,
},
),
],
]

View File

@ -0,0 +1,91 @@
---
source: milli/src/search/new/tests/geo_sort.rs
expression: "format!(\"{scores:#?}\")"
---
[
[
GeoSort(
GeoSort {
target_point: [
0.0,
-175.0,
],
ascending: true,
value: Some(
[
0.0,
-179.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
-175.0,
],
ascending: true,
value: Some(
[
0.0,
178.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
-175.0,
],
ascending: true,
value: Some(
[
-89.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
-175.0,
],
ascending: true,
value: Some(
[
88.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
-175.0,
],
ascending: true,
value: Some(
[
0.0,
0.0,
],
),
},
),
],
]

View File

@ -0,0 +1,91 @@
---
source: milli/src/search/new/tests/geo_sort.rs
expression: "format!(\"{scores:#?}\")"
---
[
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: Some(
[
0.0,
-179.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: Some(
[
0.0,
178.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: Some(
[
-89.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: Some(
[
88.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: false,
value: Some(
[
0.0,
0.0,
],
),
},
),
],
]

View File

@ -0,0 +1,91 @@
---
source: milli/src/search/new/tests/geo_sort.rs
expression: "format!(\"{scores:#?}\")"
---
[
[
GeoSort(
GeoSort {
target_point: [
85.0,
0.0,
],
ascending: false,
value: Some(
[
-89.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
85.0,
0.0,
],
ascending: false,
value: Some(
[
0.0,
-179.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
85.0,
0.0,
],
ascending: false,
value: Some(
[
0.0,
178.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
85.0,
0.0,
],
ascending: false,
value: Some(
[
0.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
85.0,
0.0,
],
ascending: false,
value: Some(
[
88.0,
0.0,
],
),
},
),
],
]

View File

@ -0,0 +1,91 @@
---
source: milli/src/search/new/tests/geo_sort.rs
expression: "format!(\"{scores:#?}\")"
---
[
[
GeoSort(
GeoSort {
target_point: [
-85.0,
0.0,
],
ascending: false,
value: Some(
[
88.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
-85.0,
0.0,
],
ascending: false,
value: Some(
[
0.0,
-179.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
-85.0,
0.0,
],
ascending: false,
value: Some(
[
0.0,
178.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
-85.0,
0.0,
],
ascending: false,
value: Some(
[
0.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
-85.0,
0.0,
],
ascending: false,
value: Some(
[
-89.0,
0.0,
],
),
},
),
],
]

View File

@ -0,0 +1,91 @@
---
source: milli/src/search/new/tests/geo_sort.rs
expression: "format!(\"{scores:#?}\")"
---
[
[
GeoSort(
GeoSort {
target_point: [
0.0,
175.0,
],
ascending: false,
value: Some(
[
0.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
175.0,
],
ascending: false,
value: Some(
[
88.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
175.0,
],
ascending: false,
value: Some(
[
-89.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
175.0,
],
ascending: false,
value: Some(
[
0.0,
-179.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
175.0,
],
ascending: false,
value: Some(
[
0.0,
178.0,
],
),
},
),
],
]

View File

@ -0,0 +1,91 @@
---
source: milli/src/search/new/tests/geo_sort.rs
expression: "format!(\"{scores:#?}\")"
---
[
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
0.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
88.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
-89.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
0.0,
178.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
0.0,
-179.0,
],
),
},
),
],
]

View File

@ -0,0 +1,91 @@
---
source: milli/src/search/new/tests/geo_sort.rs
expression: "format!(\"{scores:#?}\")"
---
[
[
GeoSort(
GeoSort {
target_point: [
0.0,
-175.0,
],
ascending: false,
value: Some(
[
0.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
-175.0,
],
ascending: false,
value: Some(
[
88.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
-175.0,
],
ascending: false,
value: Some(
[
-89.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
-175.0,
],
ascending: false,
value: Some(
[
0.0,
178.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
-175.0,
],
ascending: false,
value: Some(
[
0.0,
-179.0,
],
),
},
),
],
]

View File

@ -0,0 +1,91 @@
---
source: milli/src/search/new/tests/geo_sort.rs
expression: "format!(\"{scores:#?}\")"
---
[
[
GeoSort(
GeoSort {
target_point: [
85.0,
0.0,
],
ascending: true,
value: Some(
[
88.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
85.0,
0.0,
],
ascending: true,
value: Some(
[
0.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
85.0,
0.0,
],
ascending: true,
value: Some(
[
0.0,
178.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
85.0,
0.0,
],
ascending: true,
value: Some(
[
0.0,
-179.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
85.0,
0.0,
],
ascending: true,
value: Some(
[
-89.0,
0.0,
],
),
},
),
],
]

View File

@ -0,0 +1,91 @@
---
source: milli/src/search/new/tests/geo_sort.rs
expression: "format!(\"{scores:#?}\")"
---
[
[
GeoSort(
GeoSort {
target_point: [
-85.0,
0.0,
],
ascending: true,
value: Some(
[
-89.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
-85.0,
0.0,
],
ascending: true,
value: Some(
[
0.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
-85.0,
0.0,
],
ascending: true,
value: Some(
[
0.0,
178.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
-85.0,
0.0,
],
ascending: true,
value: Some(
[
0.0,
-179.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
-85.0,
0.0,
],
ascending: true,
value: Some(
[
88.0,
0.0,
],
),
},
),
],
]

View File

@ -0,0 +1,91 @@
---
source: milli/src/search/new/tests/geo_sort.rs
expression: "format!(\"{scores:#?}\")"
---
[
[
GeoSort(
GeoSort {
target_point: [
0.0,
175.0,
],
ascending: true,
value: Some(
[
0.0,
178.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
175.0,
],
ascending: true,
value: Some(
[
0.0,
-179.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
175.0,
],
ascending: true,
value: Some(
[
-89.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
175.0,
],
ascending: true,
value: Some(
[
88.0,
0.0,
],
),
},
),
],
[
GeoSort(
GeoSort {
target_point: [
0.0,
175.0,
],
ascending: true,
value: Some(
[
0.0,
0.0,
],
),
},
),
],
]

View File

@ -0,0 +1,75 @@
---
source: milli/src/search/new/tests/geo_sort.rs
expression: "format!(\"{scores:#?}\")"
---
[
[
Words(
Words {
matching_words: 1,
max_matching_words: 1,
},
),
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
0.0,
0.0,
],
),
},
),
],
[
Words(
Words {
matching_words: 1,
max_matching_words: 1,
},
),
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
-89.0,
0.0,
],
),
},
),
],
[
Words(
Words {
matching_words: 1,
max_matching_words: 1,
},
),
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: Some(
[
0.0,
178.0,
],
),
},
),
],
]

View File

@ -0,0 +1,60 @@
---
source: milli/src/search/new/tests/geo_sort.rs
expression: "format!(\"{scores:#?}\")"
---
[
[
Words(
Words {
matching_words: 1,
max_matching_words: 1,
},
),
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: None,
},
),
],
[
Words(
Words {
matching_words: 1,
max_matching_words: 1,
},
),
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: None,
},
),
],
[
Words(
Words {
matching_words: 1,
max_matching_words: 1,
},
),
GeoSort(
GeoSort {
target_point: [
0.0,
0.0,
],
ascending: true,
value: None,
},
),
],
]

View File

@ -0,0 +1,70 @@
---
source: milli/src/search/new/tests/proximity.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 7,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 6,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 6,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 5,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 5,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 4,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
]

View File

@ -0,0 +1,70 @@
---
source: milli/src/search/new/tests/proximity.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 7,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 6,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 6,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 5,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
]

View File

@ -0,0 +1,78 @@
---
source: milli/src/search/new/tests/proximity.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 7,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 6,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 6,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 5,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
]

View File

@ -0,0 +1,78 @@
---
source: milli/src/search/new/tests/proximity.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 7,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 6,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 6,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 5,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 5,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 4,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
]

View File

@ -0,0 +1,70 @@
---
source: milli/src/search/new/tests/proximity.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
]

View File

@ -0,0 +1,46 @@
---
source: milli/src/search/new/tests/proximity.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
]

View File

@ -0,0 +1,30 @@
---
source: milli/src/search/new/tests/proximity.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
]

View File

@ -0,0 +1,30 @@
---
source: milli/src/search/new/tests/proximity.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 8,
},
),
],
]

View File

@ -0,0 +1,206 @@
---
source: milli/src/search/new/tests/sort.rs
expression: document_scores_json
---
[
{
"vague:asc": {
"order": 0,
"value": 0.0
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": 1.0
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": 1.0
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": 1.0
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": 1.1367
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": 1.2367
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": 1.5673
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": "0"
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": "1"
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": "false"
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": "false"
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": "true"
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": "true"
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": null
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": null
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": null
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": null
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": null
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": null
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
},
{
"vague:asc": {
"order": 0,
"value": null
},
"<hidden-rule-1>": {
"order": 1,
"value": "<hidden>"
}
}
]

View File

@ -0,0 +1,206 @@
---
source: milli/src/search/new/tests/sort.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: Number(2.0),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: Number(1.5673),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: Number(1.2367),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: Number(1.1367),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: Number(1.0),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: Number(1.0),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: Number(0.0),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: String("true"),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: String("true"),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: String("false"),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: String("false"),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: String("1"),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: String("0"),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: Null,
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: Null,
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: Null,
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: Null,
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: Null,
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: Null,
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: false,
redacted: false,
value: Null,
},
),
],
]

View File

@ -0,0 +1,206 @@
---
source: milli/src/search/new/tests/sort.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("i"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("i"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("i"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("h"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("g"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("g"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("f"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("f"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("f"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("e"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("e"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("e"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("e"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("e"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("e"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("d"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("c"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("c"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("c"),
},
),
],
[
Sort(
Sort {
field_name: "letter",
ascending: false,
redacted: false,
value: String("b"),
},
),
],
]

View File

@ -0,0 +1,206 @@
---
source: milli/src/search/new/tests/sort.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(5.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(4.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(3.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(2.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(2.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(2.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(2.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(2.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(1.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(1.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(1.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(1.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(1.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(1.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(1.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(0.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(0.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(0.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(0.0),
},
),
],
[
Sort(
Sort {
field_name: "rank",
ascending: false,
redacted: false,
value: Number(0.0),
},
),
],
]

View File

@ -0,0 +1,206 @@
---
source: milli/src/search/new/tests/sort.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: Number(0.0),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: Number(1.0),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: Number(1.0),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: Number(1.0),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: Number(1.1367),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: Number(1.2367),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: Number(1.5673),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: String("0"),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: String("1"),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: String("false"),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: String("false"),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: String("true"),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: String("true"),
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: Null,
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: Null,
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: Null,
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: Null,
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: Null,
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: Null,
},
),
],
[
Sort(
Sort {
field_name: "vague",
ascending: true,
redacted: false,
value: Null,
},
),
],
]

View File

@ -0,0 +1,129 @@
---
source: milli/src/search/new/tests/stop_words.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Words(
Words {
matching_words: 3,
max_matching_words: 3,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 2,
},
),
Proximity(
Rank {
rank: 1,
max_rank: 1,
},
),
Fid(
Rank {
rank: 1,
max_rank: 1,
},
),
Position(
Rank {
rank: 31,
max_rank: 31,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 4,
max_rank: 4,
},
),
],
[
Words(
Words {
matching_words: 3,
max_matching_words: 3,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 2,
},
),
Proximity(
Rank {
rank: 1,
max_rank: 1,
},
),
Fid(
Rank {
rank: 1,
max_rank: 1,
},
),
Position(
Rank {
rank: 31,
max_rank: 31,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 4,
max_rank: 4,
},
),
],
[
Words(
Words {
matching_words: 3,
max_matching_words: 3,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 2,
},
),
Proximity(
Rank {
rank: 1,
max_rank: 1,
},
),
Fid(
Rank {
rank: 1,
max_rank: 1,
},
),
Position(
Rank {
rank: 27,
max_rank: 31,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 4,
max_rank: 4,
},
),
],
]

View File

@ -0,0 +1,13 @@
---
source: milli/src/search/new/tests/stop_words.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[],
[],
[],
[],
[],
[],
[],
]

View File

@ -0,0 +1,12 @@
---
source: milli/src/search/new/tests/typo.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[],
[],
[],
[],
[],
[],
]

View File

@ -0,0 +1,54 @@
---
source: milli/src/search/new/tests/typo.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Typo(
Typo {
typo_count: 0,
max_typo_count: 5,
},
),
],
[
Typo(
Typo {
typo_count: 0,
max_typo_count: 5,
},
),
],
[
Typo(
Typo {
typo_count: 1,
max_typo_count: 5,
},
),
],
[
Typo(
Typo {
typo_count: 1,
max_typo_count: 5,
},
),
],
[
Typo(
Typo {
typo_count: 2,
max_typo_count: 5,
},
),
],
[
Typo(
Typo {
typo_count: 5,
max_typo_count: 5,
},
),
],
]

View File

@ -0,0 +1,54 @@
---
source: milli/src/search/new/tests/typo.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Typo(
Typo {
typo_count: 0,
max_typo_count: 6,
},
),
],
[
Typo(
Typo {
typo_count: 0,
max_typo_count: 6,
},
),
],
[
Typo(
Typo {
typo_count: 2,
max_typo_count: 6,
},
),
],
[
Typo(
Typo {
typo_count: 2,
max_typo_count: 6,
},
),
],
[
Typo(
Typo {
typo_count: 3,
max_typo_count: 6,
},
),
],
[
Typo(
Typo {
typo_count: 4,
max_typo_count: 6,
},
),
],
]

View File

@ -0,0 +1,9 @@
---
source: milli/src/search/new/tests/typo.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[],
[],
[],
]

View File

@ -0,0 +1,9 @@
---
source: milli/src/search/new/tests/typo.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[],
[],
[],
]

View File

@ -0,0 +1,244 @@
---
source: milli/src/search/new/tests/typo.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 9,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 1,
max_typo_count: 9,
},
),
],
[
Words(
Words {
matching_words: 8,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 8,
},
),
],
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 7,
},
),
],
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 7,
},
),
],
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 7,
},
),
],
[
Words(
Words {
matching_words: 5,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 5,
},
),
],
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 4,
},
),
],
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 3,
},
),
],
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 3,
},
),
],
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 3,
},
),
],
[
Words(
Words {
matching_words: 2,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 2,
},
),
],
[
Words(
Words {
matching_words: 2,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 1,
max_typo_count: 2,
},
),
],
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 1,
},
),
],
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 1,
},
),
],
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 1,
},
),
],
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 1,
},
),
],
]

View File

@ -0,0 +1,244 @@
---
source: milli/src/search/new/tests/typo.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 9,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 1,
max_typo_count: 9,
},
),
],
[
Words(
Words {
matching_words: 8,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 8,
},
),
],
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 7,
},
),
],
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 7,
},
),
],
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 7,
},
),
],
[
Words(
Words {
matching_words: 5,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 5,
},
),
],
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 4,
},
),
],
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 3,
},
),
],
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 3,
},
),
],
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 3,
},
),
],
[
Words(
Words {
matching_words: 2,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 2,
},
),
],
[
Words(
Words {
matching_words: 2,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 1,
max_typo_count: 2,
},
),
],
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 1,
},
),
],
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 1,
},
),
],
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 1,
},
),
],
[
Words(
Words {
matching_words: 1,
max_matching_words: 9,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 1,
},
),
],
]

View File

@ -0,0 +1,30 @@
---
source: milli/src/search/new/tests/typo.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Typo(
Typo {
typo_count: 0,
max_typo_count: 13,
},
),
],
[
Typo(
Typo {
typo_count: 0,
max_typo_count: 13,
},
),
],
[
Typo(
Typo {
typo_count: 1,
max_typo_count: 13,
},
),
],
]

View File

@ -0,0 +1,30 @@
---
source: milli/src/search/new/tests/typo.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Typo(
Typo {
typo_count: 0,
max_typo_count: 13,
},
),
],
[
Typo(
Typo {
typo_count: 2,
max_typo_count: 13,
},
),
],
[
Typo(
Typo {
typo_count: 2,
max_typo_count: 13,
},
),
],
]

View File

@ -0,0 +1,62 @@
---
source: milli/src/search/new/tests/typo_proximity.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Typo(
Typo {
typo_count: 0,
max_typo_count: 3,
},
),
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
],
[
Typo(
Typo {
typo_count: 0,
max_typo_count: 3,
},
),
Proximity(
Rank {
rank: 5,
max_rank: 8,
},
),
],
[
Typo(
Typo {
typo_count: 1,
max_typo_count: 3,
},
),
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
],
[
Typo(
Typo {
typo_count: 1,
max_typo_count: 3,
},
),
Proximity(
Rank {
rank: 7,
max_rank: 8,
},
),
],
]

View File

@ -0,0 +1,34 @@
---
source: milli/src/search/new/tests/typo_proximity.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Typo(
Typo {
typo_count: 1,
max_typo_count: 5,
},
),
Proximity(
Rank {
rank: 15,
max_rank: 15,
},
),
],
[
Typo(
Typo {
typo_count: 1,
max_typo_count: 5,
},
),
Proximity(
Rank {
rank: 8,
max_rank: 15,
},
),
],
]

View File

@ -0,0 +1,216 @@
---
source: milli/src/search/new/tests/words_tms.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 50,
max_rank: 50,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 50,
max_rank: 50,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 49,
max_rank: 50,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 49,
max_rank: 50,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 48,
max_rank: 50,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 41,
max_rank: 50,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 40,
max_rank: 50,
},
),
],
[
Words(
Words {
matching_words: 8,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 43,
max_rank: 43,
},
),
],
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 36,
max_rank: 36,
},
),
],
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 31,
max_rank: 36,
},
),
],
[
Words(
Words {
matching_words: 5,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 22,
max_rank: 22,
},
),
],
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 15,
max_rank: 15,
},
),
],
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 15,
max_rank: 15,
},
),
],
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 15,
max_rank: 15,
},
),
],
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 8,
max_rank: 8,
},
),
],
]

View File

@ -0,0 +1,160 @@
---
source: milli/src/search/new/tests/words_tms.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 43,
max_rank: 43,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 43,
max_rank: 43,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 42,
max_rank: 43,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 42,
max_rank: 43,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 41,
max_rank: 43,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 34,
max_rank: 43,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 33,
max_rank: 43,
},
),
],
[
Words(
Words {
matching_words: 8,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 36,
max_rank: 36,
},
),
],
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 29,
max_rank: 29,
},
),
],
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 24,
max_rank: 29,
},
),
],
[
Words(
Words {
matching_words: 5,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 15,
max_rank: 15,
},
),
],
]

View File

@ -0,0 +1,286 @@
---
source: milli/src/search/new/tests/words_tms.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 57,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 57,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 56,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 56,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 55,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 54,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 53,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 52,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 51,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 48,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 47,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 1,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 8,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 50,
max_rank: 50,
},
),
],
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 43,
max_rank: 43,
},
),
],
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 38,
max_rank: 43,
},
),
],
[
Words(
Words {
matching_words: 5,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 29,
max_rank: 29,
},
),
],
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 22,
max_rank: 22,
},
),
],
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 22,
max_rank: 22,
},
),
],
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 22,
max_rank: 22,
},
),
],
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 15,
max_rank: 15,
},
),
],
]

View File

@ -0,0 +1,286 @@
---
source: milli/src/search/new/tests/words_tms.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 57,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 56,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 55,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 54,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 54,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 54,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 53,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 53,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 52,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 47,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 45,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 1,
max_rank: 57,
},
),
],
[
Words(
Words {
matching_words: 8,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 47,
max_rank: 50,
},
),
],
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 40,
max_rank: 43,
},
),
],
[
Words(
Words {
matching_words: 7,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 35,
max_rank: 43,
},
),
],
[
Words(
Words {
matching_words: 5,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 26,
max_rank: 29,
},
),
],
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 19,
max_rank: 22,
},
),
],
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 19,
max_rank: 22,
},
),
],
[
Words(
Words {
matching_words: 4,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 19,
max_rank: 22,
},
),
],
[
Words(
Words {
matching_words: 3,
max_matching_words: 9,
},
),
Proximity(
Rank {
rank: 13,
max_rank: 15,
},
),
],
]

View File

@ -0,0 +1,102 @@
---
source: milli/src/search/new/tests/words_tms.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Proximity(
Rank {
rank: 57,
max_rank: 57,
},
),
],
[
Proximity(
Rank {
rank: 57,
max_rank: 57,
},
),
],
[
Proximity(
Rank {
rank: 56,
max_rank: 57,
},
),
],
[
Proximity(
Rank {
rank: 56,
max_rank: 57,
},
),
],
[
Proximity(
Rank {
rank: 55,
max_rank: 57,
},
),
],
[
Proximity(
Rank {
rank: 54,
max_rank: 57,
},
),
],
[
Proximity(
Rank {
rank: 53,
max_rank: 57,
},
),
],
[
Proximity(
Rank {
rank: 52,
max_rank: 57,
},
),
],
[
Proximity(
Rank {
rank: 51,
max_rank: 57,
},
),
],
[
Proximity(
Rank {
rank: 48,
max_rank: 57,
},
),
],
[
Proximity(
Rank {
rank: 47,
max_rank: 57,
},
),
],
[
Proximity(
Rank {
rank: 1,
max_rank: 57,
},
),
],
]

Some files were not shown because too many files have changed in this diff Show More