mirror of
https://github.com/meilisearch/meilisearch.git
synced 2024-11-30 00:55:00 +08:00
Merge #3821
3821: Add normalized and detailed scores to documents returned by a query r=dureuill a=dureuill # Pull Request ## Related issue Fixes #3771 ## What does this PR do? ### User standpoint <details> <summary>Request ranking score</summary> ``` echo '{ "q": "Badman dark knight returns", "showRankingScore": true, "limit": 10, "attributesToRetrieve": ["title"] }' | mieli search -i index-word-count-10-count ``` </details> <details> <summary>Response</summary> ```json { "hits": [ { "title": "Batman: The Dark Knight Returns, Part 1", "_rankingScore": 0.947520325203252 }, { "title": "Batman: The Dark Knight Returns, Part 2", "_rankingScore": 0.947520325203252 }, { "title": "Batman Unmasked: The Psychology of the Dark Knight", "_rankingScore": 0.6657594086021505 }, { "title": "Legends of the Dark Knight: The History of Batman", "_rankingScore": 0.6654905913978495 }, { "title": "Angel and the Badman", "_rankingScore": 0.2196969696969697 }, { "title": "Angel and the Badman", "_rankingScore": 0.2196969696969697 }, { "title": "Batman", "_rankingScore": 0.11553030303030302 }, { "title": "Batman Begins", "_rankingScore": 0.11553030303030302 }, { "title": "Batman Returns", "_rankingScore": 0.11553030303030302 }, { "title": "Batman Forever", "_rankingScore": 0.11553030303030302 } ], "query": "Badman dark knight returns", "processingTimeMs": 12, "limit": 10, "offset": 0, "estimatedTotalHits": 46 } ``` </details> - If adding a `showRankingScore` parameter to the search query, then documents returned by a search now contain an additional field `_rankingScore` that is a float bigger than 0 and lower or equal to 1.0. This field represents the relevancy of the document, relatively to the search query and the settings of the index, with 1.0 meaning "perfect match" and 0 meaning "not matching the query" (Meilisearch should never return documents not matching the query at all). - The `sort` and `geosort` ranking rules do not influence the `_rankingScore`. <details> <summary>Request detailed ranking scores</summary> ``` echo '{ "q": "Badman dark knight returns", "showRankingScoreDetails": true, "limit": 5, "attributesToRetrieve": ["title"] }' | mieli search -i index-word-count-10-count ``` </details> <details> <summary>Response</summary> ```json { "hits": [ { "title": "Batman: The Dark Knight Returns, Part 1", "_rankingScoreDetails": { "words": { "order": 0, "matchingWords": 4, "maxMatchingWords": 4, "score": 1.0 }, "typo": { "order": 1, "typoCount": 1, "maxTypoCount": 4, "score": 0.8 }, "proximity": { "order": 2, "score": 0.9545454545454546 }, "attribute": { "order": 3, "attributes_ranking_order": 1.0, "attributes_query_word_order": 0.926829268292683, "score": 0.926829268292683 }, "exactness": { "order": 4, "matchType": "noExactMatch", "score": 0.26666666666666666 } } }, { "title": "Batman: The Dark Knight Returns, Part 2", "_rankingScoreDetails": { "words": { "order": 0, "matchingWords": 4, "maxMatchingWords": 4, "score": 1.0 }, "typo": { "order": 1, "typoCount": 1, "maxTypoCount": 4, "score": 0.8 }, "proximity": { "order": 2, "score": 0.9545454545454546 }, "attribute": { "order": 3, "attributes_ranking_order": 1.0, "attributes_query_word_order": 0.926829268292683, "score": 0.926829268292683 }, "exactness": { "order": 4, "matchType": "noExactMatch", "score": 0.26666666666666666 } } }, { "title": "Batman Unmasked: The Psychology of the Dark Knight", "_rankingScoreDetails": { "words": { "order": 0, "matchingWords": 3, "maxMatchingWords": 4, "score": 0.75 }, "typo": { "order": 1, "typoCount": 1, "maxTypoCount": 3, "score": 0.75 }, "proximity": { "order": 2, "score": 0.6666666666666666 }, "attribute": { "order": 3, "attributes_ranking_order": 1.0, "attributes_query_word_order": 0.8064516129032258, "score": 0.8064516129032258 }, "exactness": { "order": 4, "matchType": "noExactMatch", "score": 0.25 } } }, { "title": "Legends of the Dark Knight: The History of Batman", "_rankingScoreDetails": { "words": { "order": 0, "matchingWords": 3, "maxMatchingWords": 4, "score": 0.75 }, "typo": { "order": 1, "typoCount": 1, "maxTypoCount": 3, "score": 0.75 }, "proximity": { "order": 2, "score": 0.6666666666666666 }, "attribute": { "order": 3, "attributes_ranking_order": 1.0, "attributes_query_word_order": 0.7419354838709677, "score": 0.7419354838709677 }, "exactness": { "order": 4, "matchType": "noExactMatch", "score": 0.25 } } }, { "title": "Angel and the Badman", "_rankingScoreDetails": { "words": { "order": 0, "matchingWords": 1, "maxMatchingWords": 4, "score": 0.25 }, "typo": { "order": 1, "typoCount": 0, "maxTypoCount": 1, "score": 1.0 }, "proximity": { "order": 2, "score": 1.0 }, "attribute": { "order": 3, "attributes_ranking_order": 1.0, "attributes_query_word_order": 0.8181818181818182, "score": 0.8181818181818182 }, "exactness": { "order": 4, "matchType": "noExactMatch", "score": 0.3333333333333333 } } } ], "query": "Badman dark knight returns", "processingTimeMs": 9, "limit": 5, "offset": 0, "estimatedTotalHits": 46 } ``` </details> - If adding a `showRankingScoreDetails` parameter to the search query, then the returned documents will now contain an additional `_rankingScoreDetails` field that is a JSON object containing one field per ranking rule that was applied, whose value is a JSON object with the following fields: - `order`: a number indicating the order this rule was applied (0 is the first applied ranking rule) - `score` (except for `sort` and `geosort`): a float indicating how the document matched this particular rule. - other fields that are specific to the rule, indicating for example how many words matched for a document and how many typos were counted in a matching document. - If the `displayableAttributes` list is defined in the settings of the index, any ranking rule using an attribute **not** part of that list will be marked as `<hidden-rule>` in the `_rankingScoreDetails`. - Search queries that are part of a `multi-search` requests are modified in the same way and each of the queries can take the `showRankingScore` and `showRankingScoreDetails` parameters independently. The results are still returned in separate lists and providing a unified list of results between multiple queries is not in the scope of this PR (but is unblocked by this PR and can be done manually by using the scores of the various documents). ### Implementation standpoint - Fix difference in how the position of terms were computed at indexing time and query time: this difference meant that a query containing a hard separator would fail the exactness check. - Fix the id reported by the sort ranking rule (very minor) - Change how the cost of removing words is computed. After this change the cost no longer works for any other ranking rule than `words`. Also made `words` have a cost of 0 such that the entire cost of `words` is given by the termRemovalStrategy. The new cost computation makes it so the score is computed in a way consistent with the number of words in the query. Additionally, the words that appear in phrases in the query are also counted as matching words. - When any score computation is requested through `showRankingScore` or `showRankingScoreDetails`, remove optimization where ranking rules are not executed on buckets of a single document: this is important to allow the computation of an accurate score. - add virtual conditions to fid and position to always have the max cost: this ensures that the score is independent from the dataset - the Position ranking rule now takes into account the distance to the position of the word in the query instead of the distance to the position 0. - modified proximity ranking rule cost calculation so that the cost is 0 for documents that are perfectly matching the query - Add a new `milli::score_details` module containing all the types that are involved in score computation. - Make it so a bucket of result now contains a `ScoreDetails` and changed the ranking rules to produce their `ScoreDetails`. - Expose the scores in the REST API. - Add very light analytics for scoring. - Update the search tests to add the expected scores. Co-authored-by: Louis Dureuil <louis@meilisearch.com>
This commit is contained in:
commit
2d34005965
@ -240,6 +240,8 @@ InvalidSearchOffset , InvalidRequest , BAD_REQUEST ;
|
|||||||
InvalidSearchPage , InvalidRequest , BAD_REQUEST ;
|
InvalidSearchPage , InvalidRequest , BAD_REQUEST ;
|
||||||
InvalidSearchQ , InvalidRequest , BAD_REQUEST ;
|
InvalidSearchQ , InvalidRequest , BAD_REQUEST ;
|
||||||
InvalidSearchShowMatchesPosition , InvalidRequest , BAD_REQUEST ;
|
InvalidSearchShowMatchesPosition , InvalidRequest , BAD_REQUEST ;
|
||||||
|
InvalidSearchShowRankingScore , InvalidRequest , BAD_REQUEST ;
|
||||||
|
InvalidSearchShowRankingScoreDetails , InvalidRequest , BAD_REQUEST ;
|
||||||
InvalidSearchSort , InvalidRequest , BAD_REQUEST ;
|
InvalidSearchSort , InvalidRequest , BAD_REQUEST ;
|
||||||
InvalidSettingsDisplayedAttributes , InvalidRequest , BAD_REQUEST ;
|
InvalidSettingsDisplayedAttributes , InvalidRequest , BAD_REQUEST ;
|
||||||
InvalidSettingsDistinctAttribute , InvalidRequest , BAD_REQUEST ;
|
InvalidSettingsDistinctAttribute , InvalidRequest , BAD_REQUEST ;
|
||||||
|
@ -569,6 +569,10 @@ pub struct SearchAggregator {
|
|||||||
// facets
|
// facets
|
||||||
facets_sum_of_terms: usize,
|
facets_sum_of_terms: usize,
|
||||||
facets_total_number_of_facets: usize,
|
facets_total_number_of_facets: usize,
|
||||||
|
|
||||||
|
// scoring
|
||||||
|
show_ranking_score: bool,
|
||||||
|
show_ranking_score_details: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SearchAggregator {
|
impl SearchAggregator {
|
||||||
@ -632,6 +636,9 @@ impl SearchAggregator {
|
|||||||
ret.crop_length = query.crop_length != DEFAULT_CROP_LENGTH();
|
ret.crop_length = query.crop_length != DEFAULT_CROP_LENGTH();
|
||||||
ret.show_matches_position = query.show_matches_position;
|
ret.show_matches_position = query.show_matches_position;
|
||||||
|
|
||||||
|
ret.show_ranking_score = query.show_ranking_score;
|
||||||
|
ret.show_ranking_score_details = query.show_ranking_score_details;
|
||||||
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -706,6 +713,10 @@ impl SearchAggregator {
|
|||||||
let matching_strategy = self.matching_strategy.entry(key).or_insert(0);
|
let matching_strategy = self.matching_strategy.entry(key).or_insert(0);
|
||||||
*matching_strategy = matching_strategy.saturating_add(value);
|
*matching_strategy = matching_strategy.saturating_add(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// scoring
|
||||||
|
self.show_ranking_score |= other.show_ranking_score;
|
||||||
|
self.show_ranking_score_details |= other.show_ranking_score_details;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_event(self, user: &User, event_name: &str) -> Option<Track> {
|
pub fn into_event(self, user: &User, event_name: &str) -> Option<Track> {
|
||||||
@ -760,7 +771,11 @@ impl SearchAggregator {
|
|||||||
},
|
},
|
||||||
"matching_strategy": {
|
"matching_strategy": {
|
||||||
"most_used_strategy": self.matching_strategy.iter().max_by_key(|(_, v)| *v).map(|(k, _)| json!(k)).unwrap_or_else(|| json!(null)),
|
"most_used_strategy": self.matching_strategy.iter().max_by_key(|(_, v)| *v).map(|(k, _)| json!(k)).unwrap_or_else(|| json!(null)),
|
||||||
}
|
},
|
||||||
|
"scoring": {
|
||||||
|
"show_ranking_score": self.show_ranking_score,
|
||||||
|
"show_ranking_score_details": self.show_ranking_score_details,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(Track {
|
Some(Track {
|
||||||
|
@ -56,6 +56,10 @@ pub struct SearchQueryGet {
|
|||||||
sort: Option<String>,
|
sort: Option<String>,
|
||||||
#[deserr(default, error = DeserrQueryParamError<InvalidSearchShowMatchesPosition>)]
|
#[deserr(default, error = DeserrQueryParamError<InvalidSearchShowMatchesPosition>)]
|
||||||
show_matches_position: Param<bool>,
|
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>)]
|
#[deserr(default, error = DeserrQueryParamError<InvalidSearchFacets>)]
|
||||||
facets: Option<CS<String>>,
|
facets: Option<CS<String>>,
|
||||||
#[deserr( default = DEFAULT_HIGHLIGHT_PRE_TAG(), error = DeserrQueryParamError<InvalidSearchHighlightPreTag>)]
|
#[deserr( default = DEFAULT_HIGHLIGHT_PRE_TAG(), error = DeserrQueryParamError<InvalidSearchHighlightPreTag>)]
|
||||||
@ -91,6 +95,8 @@ impl From<SearchQueryGet> for SearchQuery {
|
|||||||
filter,
|
filter,
|
||||||
sort: other.sort.map(|attr| fix_sort_query_parameters(&attr)),
|
sort: other.sort.map(|attr| fix_sort_query_parameters(&attr)),
|
||||||
show_matches_position: other.show_matches_position.0,
|
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()),
|
facets: other.facets.map(|o| o.into_iter().collect()),
|
||||||
highlight_pre_tag: other.highlight_pre_tag,
|
highlight_pre_tag: other.highlight_pre_tag,
|
||||||
highlight_post_tag: other.highlight_post_tag,
|
highlight_post_tag: other.highlight_post_tag,
|
||||||
|
@ -9,6 +9,7 @@ use meilisearch_auth::IndexSearchRules;
|
|||||||
use meilisearch_types::deserr::DeserrJsonError;
|
use meilisearch_types::deserr::DeserrJsonError;
|
||||||
use meilisearch_types::error::deserr_codes::*;
|
use meilisearch_types::error::deserr_codes::*;
|
||||||
use meilisearch_types::index_uid::IndexUid;
|
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::settings::DEFAULT_PAGINATION_MAX_TOTAL_HITS;
|
||||||
use meilisearch_types::{milli, Document};
|
use meilisearch_types::{milli, Document};
|
||||||
use milli::tokenizer::TokenizerBuilder;
|
use milli::tokenizer::TokenizerBuilder;
|
||||||
@ -54,6 +55,10 @@ pub struct SearchQuery {
|
|||||||
pub attributes_to_highlight: Option<HashSet<String>>,
|
pub attributes_to_highlight: Option<HashSet<String>>,
|
||||||
#[deserr(default, error = DeserrJsonError<InvalidSearchShowMatchesPosition>, default)]
|
#[deserr(default, error = DeserrJsonError<InvalidSearchShowMatchesPosition>, default)]
|
||||||
pub show_matches_position: bool,
|
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>)]
|
#[deserr(default, error = DeserrJsonError<InvalidSearchFilter>)]
|
||||||
pub filter: Option<Value>,
|
pub filter: Option<Value>,
|
||||||
#[deserr(default, error = DeserrJsonError<InvalidSearchSort>)]
|
#[deserr(default, error = DeserrJsonError<InvalidSearchSort>)]
|
||||||
@ -103,6 +108,10 @@ pub struct SearchQueryWithIndex {
|
|||||||
pub crop_length: usize,
|
pub crop_length: usize,
|
||||||
#[deserr(default, error = DeserrJsonError<InvalidSearchAttributesToHighlight>)]
|
#[deserr(default, error = DeserrJsonError<InvalidSearchAttributesToHighlight>)]
|
||||||
pub attributes_to_highlight: Option<HashSet<String>>,
|
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)]
|
#[deserr(default, error = DeserrJsonError<InvalidSearchShowMatchesPosition>, default)]
|
||||||
pub show_matches_position: bool,
|
pub show_matches_position: bool,
|
||||||
#[deserr(default, error = DeserrJsonError<InvalidSearchFilter>)]
|
#[deserr(default, error = DeserrJsonError<InvalidSearchFilter>)]
|
||||||
@ -134,6 +143,8 @@ impl SearchQueryWithIndex {
|
|||||||
attributes_to_crop,
|
attributes_to_crop,
|
||||||
crop_length,
|
crop_length,
|
||||||
attributes_to_highlight,
|
attributes_to_highlight,
|
||||||
|
show_ranking_score,
|
||||||
|
show_ranking_score_details,
|
||||||
show_matches_position,
|
show_matches_position,
|
||||||
filter,
|
filter,
|
||||||
sort,
|
sort,
|
||||||
@ -155,6 +166,8 @@ impl SearchQueryWithIndex {
|
|||||||
attributes_to_crop,
|
attributes_to_crop,
|
||||||
crop_length,
|
crop_length,
|
||||||
attributes_to_highlight,
|
attributes_to_highlight,
|
||||||
|
show_ranking_score,
|
||||||
|
show_ranking_score_details,
|
||||||
show_matches_position,
|
show_matches_position,
|
||||||
filter,
|
filter,
|
||||||
sort,
|
sort,
|
||||||
@ -194,7 +207,7 @@ impl From<MatchingStrategy> for TermsMatchingStrategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, PartialEq, Eq)]
|
#[derive(Debug, Clone, Serialize, PartialEq)]
|
||||||
pub struct SearchHit {
|
pub struct SearchHit {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub document: Document,
|
pub document: Document,
|
||||||
@ -202,6 +215,10 @@ pub struct SearchHit {
|
|||||||
pub formatted: Document,
|
pub formatted: Document,
|
||||||
#[serde(rename = "_matchesPosition", skip_serializing_if = "Option::is_none")]
|
#[serde(rename = "_matchesPosition", skip_serializing_if = "Option::is_none")]
|
||||||
pub matches_position: Option<MatchesPosition>,
|
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)]
|
#[derive(Serialize, Debug, Clone, PartialEq)]
|
||||||
@ -283,6 +300,11 @@ pub fn perform_search(
|
|||||||
.unwrap_or(DEFAULT_PAGINATION_MAX_TOTAL_HITS);
|
.unwrap_or(DEFAULT_PAGINATION_MAX_TOTAL_HITS);
|
||||||
|
|
||||||
search.exhaustive_number_hits(is_finite_pagination);
|
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.
|
// compute the offset on the limit depending on the pagination mode.
|
||||||
let (offset, limit) = if is_finite_pagination {
|
let (offset, limit) = if is_finite_pagination {
|
||||||
@ -320,7 +342,8 @@ pub fn perform_search(
|
|||||||
search.sort_criteria(sort);
|
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();
|
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)?;
|
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
|
// First generate a document with all the displayed fields
|
||||||
let displayed_document = make_document(&displayed_ids, &fields_ids_map, obkv)?;
|
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);
|
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);
|
documents.push(hit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use insta::{allow_duplicates, assert_json_snapshot};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -18,30 +19,43 @@ async fn formatted_contain_wildcard() {
|
|||||||
|response, code|
|
|response, code|
|
||||||
{
|
{
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"_formatted": {
|
@r###"
|
||||||
"id": "852",
|
{
|
||||||
"cattos": "<em>pésti</em>",
|
"_formatted": {
|
||||||
},
|
"id": "852",
|
||||||
"_matchesPosition": {"cattos": [{"start": 0, "length": 5}]},
|
"cattos": "<em>pésti</em>"
|
||||||
})
|
},
|
||||||
);
|
"_matchesPosition": {
|
||||||
}
|
"cattos": [
|
||||||
|
{
|
||||||
|
"start": 0,
|
||||||
|
"length": 5
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
index
|
index
|
||||||
.search(json!({ "q": "pésti", "attributesToRetrieve": ["*"] }), |response, code| {
|
.search(json!({ "q": "pésti", "attributesToRetrieve": ["*"] }), |response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"id": 852,
|
@r###"
|
||||||
"cattos": "pésti",
|
{
|
||||||
})
|
"id": 852,
|
||||||
);
|
"cattos": "pésti"
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@ -50,20 +64,29 @@ async fn formatted_contain_wildcard() {
|
|||||||
json!({ "q": "pésti", "attributesToRetrieve": ["*"], "attributesToHighlight": ["id"], "showMatchesPosition": true }),
|
json!({ "q": "pésti", "attributesToRetrieve": ["*"], "attributesToHighlight": ["id"], "showMatchesPosition": true }),
|
||||||
|response, code| {
|
|response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"id": 852,
|
@r###"
|
||||||
"cattos": "pésti",
|
{
|
||||||
"_formatted": {
|
"id": 852,
|
||||||
"id": "852",
|
"cattos": "pésti",
|
||||||
"cattos": "pésti",
|
"_formatted": {
|
||||||
},
|
"id": "852",
|
||||||
"_matchesPosition": {"cattos": [{"start": 0, "length": 5}]},
|
"cattos": "pésti"
|
||||||
})
|
},
|
||||||
);
|
"_matchesPosition": {
|
||||||
}
|
"cattos": [
|
||||||
)
|
{
|
||||||
|
"start": 0,
|
||||||
|
"length": 5
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
index
|
index
|
||||||
@ -71,17 +94,20 @@ async fn formatted_contain_wildcard() {
|
|||||||
json!({ "q": "pésti", "attributesToRetrieve": ["*"], "attributesToCrop": ["*"] }),
|
json!({ "q": "pésti", "attributesToRetrieve": ["*"], "attributesToCrop": ["*"] }),
|
||||||
|response, code| {
|
|response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"id": 852,
|
@r###"
|
||||||
"cattos": "pésti",
|
{
|
||||||
"_formatted": {
|
"id": 852,
|
||||||
"id": "852",
|
"cattos": "pésti",
|
||||||
"cattos": "pésti",
|
"_formatted": {
|
||||||
}
|
"id": "852",
|
||||||
})
|
"cattos": "pésti"
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
"###);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
@ -89,17 +115,20 @@ async fn formatted_contain_wildcard() {
|
|||||||
index
|
index
|
||||||
.search(json!({ "q": "pésti", "attributesToCrop": ["*"] }), |response, code| {
|
.search(json!({ "q": "pésti", "attributesToCrop": ["*"] }), |response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"id": 852,
|
@r###"
|
||||||
"cattos": "pésti",
|
{
|
||||||
"_formatted": {
|
"id": 852,
|
||||||
"id": "852",
|
"cattos": "pésti",
|
||||||
"cattos": "pésti",
|
"_formatted": {
|
||||||
}
|
"id": "852",
|
||||||
})
|
"cattos": "pésti"
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
@ -116,21 +145,24 @@ async fn format_nested() {
|
|||||||
index
|
index
|
||||||
.search(json!({ "q": "pésti", "attributesToRetrieve": ["doggos"] }), |response, code| {
|
.search(json!({ "q": "pésti", "attributesToRetrieve": ["doggos"] }), |response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"doggos": [
|
@r###"
|
||||||
{
|
{
|
||||||
"name": "bobby",
|
"doggos": [
|
||||||
"age": 2,
|
{
|
||||||
},
|
"name": "bobby",
|
||||||
{
|
"age": 2
|
||||||
"name": "buddy",
|
},
|
||||||
"age": 4,
|
{
|
||||||
},
|
"name": "buddy",
|
||||||
],
|
"age": 4
|
||||||
})
|
}
|
||||||
);
|
]
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@ -139,19 +171,22 @@ async fn format_nested() {
|
|||||||
json!({ "q": "pésti", "attributesToRetrieve": ["doggos.name"] }),
|
json!({ "q": "pésti", "attributesToRetrieve": ["doggos.name"] }),
|
||||||
|response, code| {
|
|response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"doggos": [
|
@r###"
|
||||||
{
|
{
|
||||||
"name": "bobby",
|
"doggos": [
|
||||||
},
|
{
|
||||||
{
|
"name": "bobby"
|
||||||
"name": "buddy",
|
},
|
||||||
},
|
{
|
||||||
],
|
"name": "buddy"
|
||||||
})
|
}
|
||||||
);
|
]
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
@ -161,20 +196,30 @@ async fn format_nested() {
|
|||||||
json!({ "q": "bobby", "attributesToRetrieve": ["doggos.name"], "showMatchesPosition": true }),
|
json!({ "q": "bobby", "attributesToRetrieve": ["doggos.name"], "showMatchesPosition": true }),
|
||||||
|response, code| {
|
|response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"doggos": [
|
@r###"
|
||||||
{
|
{
|
||||||
"name": "bobby",
|
"doggos": [
|
||||||
},
|
{
|
||||||
{
|
"name": "bobby"
|
||||||
"name": "buddy",
|
},
|
||||||
},
|
{
|
||||||
],
|
"name": "buddy"
|
||||||
"_matchesPosition": {"doggos.name": [{"start": 0, "length": 5}]},
|
}
|
||||||
})
|
],
|
||||||
);
|
"_matchesPosition": {
|
||||||
|
"doggos.name": [
|
||||||
|
{
|
||||||
|
"start": 0,
|
||||||
|
"length": 5
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
@ -183,21 +228,24 @@ async fn format_nested() {
|
|||||||
.search(json!({ "q": "pésti", "attributesToRetrieve": [], "attributesToHighlight": ["doggos.name"] }),
|
.search(json!({ "q": "pésti", "attributesToRetrieve": [], "attributesToHighlight": ["doggos.name"] }),
|
||||||
|response, code| {
|
|response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"_formatted": {
|
@r###"
|
||||||
"doggos": [
|
{
|
||||||
{
|
"_formatted": {
|
||||||
"name": "bobby",
|
"doggos": [
|
||||||
},
|
{
|
||||||
{
|
"name": "bobby"
|
||||||
"name": "buddy",
|
},
|
||||||
},
|
{
|
||||||
],
|
"name": "buddy"
|
||||||
},
|
}
|
||||||
})
|
]
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@ -205,21 +253,24 @@ async fn format_nested() {
|
|||||||
.search(json!({ "q": "pésti", "attributesToRetrieve": [], "attributesToCrop": ["doggos.name"] }),
|
.search(json!({ "q": "pésti", "attributesToRetrieve": [], "attributesToCrop": ["doggos.name"] }),
|
||||||
|response, code| {
|
|response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"_formatted": {
|
@r###"
|
||||||
"doggos": [
|
{
|
||||||
{
|
"_formatted": {
|
||||||
"name": "bobby",
|
"doggos": [
|
||||||
},
|
{
|
||||||
{
|
"name": "bobby"
|
||||||
"name": "buddy",
|
},
|
||||||
},
|
{
|
||||||
],
|
"name": "buddy"
|
||||||
},
|
}
|
||||||
})
|
]
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@ -227,55 +278,61 @@ async fn format_nested() {
|
|||||||
.search(json!({ "q": "pésti", "attributesToRetrieve": ["doggos.name"], "attributesToHighlight": ["doggos.age"] }),
|
.search(json!({ "q": "pésti", "attributesToRetrieve": ["doggos.name"], "attributesToHighlight": ["doggos.age"] }),
|
||||||
|response, code| {
|
|response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"doggos": [
|
@r###"
|
||||||
{
|
{
|
||||||
"name": "bobby",
|
"doggos": [
|
||||||
},
|
{
|
||||||
{
|
"name": "bobby"
|
||||||
"name": "buddy",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"_formatted": {
|
|
||||||
"doggos": [
|
|
||||||
{
|
|
||||||
"name": "bobby",
|
|
||||||
"age": "2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "buddy",
|
|
||||||
"age": "4",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
})
|
{
|
||||||
);
|
"name": "buddy"
|
||||||
})
|
}
|
||||||
|
],
|
||||||
|
"_formatted": {
|
||||||
|
"doggos": [
|
||||||
|
{
|
||||||
|
"name": "bobby",
|
||||||
|
"age": "2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "buddy",
|
||||||
|
"age": "4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
index
|
index
|
||||||
.search(json!({ "q": "pésti", "attributesToRetrieve": [], "attributesToHighlight": ["doggos.age"], "attributesToCrop": ["doggos.name"] }),
|
.search(json!({ "q": "pésti", "attributesToRetrieve": [], "attributesToHighlight": ["doggos.age"], "attributesToCrop": ["doggos.name"] }),
|
||||||
|response, code| {
|
|response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"_formatted": {
|
@r###"
|
||||||
"doggos": [
|
|
||||||
{
|
{
|
||||||
"name": "bobby",
|
"_formatted": {
|
||||||
"age": "2",
|
"doggos": [
|
||||||
},
|
{
|
||||||
{
|
"name": "bobby",
|
||||||
"name": "buddy",
|
"age": "2"
|
||||||
"age": "4",
|
},
|
||||||
},
|
{
|
||||||
],
|
"name": "buddy",
|
||||||
},
|
"age": "4"
|
||||||
})
|
}
|
||||||
);
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
@ -297,54 +354,66 @@ async fn displayedattr_2_smol() {
|
|||||||
.search(json!({ "attributesToRetrieve": ["father", "id"], "attributesToHighlight": ["mother"], "attributesToCrop": ["cattos"] }),
|
.search(json!({ "attributesToRetrieve": ["father", "id"], "attributesToHighlight": ["mother"], "attributesToCrop": ["cattos"] }),
|
||||||
|response, code| {
|
|response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"id": 852,
|
@r###"
|
||||||
})
|
{
|
||||||
);
|
"id": 852
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
index
|
index
|
||||||
.search(json!({ "attributesToRetrieve": ["id"] }), |response, code| {
|
.search(json!({ "attributesToRetrieve": ["id"] }), |response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"id": 852,
|
@r###"
|
||||||
})
|
{
|
||||||
);
|
"id": 852
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
index
|
index
|
||||||
.search(json!({ "attributesToHighlight": ["id"] }), |response, code| {
|
.search(json!({ "attributesToHighlight": ["id"] }), |response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"id": 852,
|
@r###"
|
||||||
"_formatted": {
|
{
|
||||||
"id": "852",
|
"id": 852,
|
||||||
}
|
"_formatted": {
|
||||||
})
|
"id": "852"
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
index
|
index
|
||||||
.search(json!({ "attributesToCrop": ["id"] }), |response, code| {
|
.search(json!({ "attributesToCrop": ["id"] }), |response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"id": 852,
|
@r###"
|
||||||
"_formatted": {
|
{
|
||||||
"id": "852",
|
"id": 852,
|
||||||
}
|
"_formatted": {
|
||||||
})
|
"id": "852"
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@ -353,15 +422,18 @@ async fn displayedattr_2_smol() {
|
|||||||
json!({ "attributesToHighlight": ["id"], "attributesToCrop": ["id"] }),
|
json!({ "attributesToHighlight": ["id"], "attributesToCrop": ["id"] }),
|
||||||
|response, code| {
|
|response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"id": 852,
|
@r###"
|
||||||
"_formatted": {
|
{
|
||||||
"id": "852",
|
"id": 852,
|
||||||
}
|
"_formatted": {
|
||||||
})
|
"id": "852"
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
@ -369,31 +441,41 @@ async fn displayedattr_2_smol() {
|
|||||||
index
|
index
|
||||||
.search(json!({ "attributesToHighlight": ["cattos"] }), |response, code| {
|
.search(json!({ "attributesToHighlight": ["cattos"] }), |response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"id": 852,
|
@r###"
|
||||||
})
|
{
|
||||||
);
|
"id": 852
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
index
|
index
|
||||||
.search(json!({ "attributesToCrop": ["cattos"] }), |response, code| {
|
.search(json!({ "attributesToCrop": ["cattos"] }), |response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"id": 852,
|
@r###"
|
||||||
})
|
{
|
||||||
);
|
"id": 852
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
index
|
index
|
||||||
.search(json!({ "attributesToRetrieve": ["cattos"] }), |response, code| {
|
.search(json!({ "attributesToRetrieve": ["cattos"] }), |response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(response["hits"][0], json!({}));
|
allow_duplicates! {
|
||||||
|
assert_json_snapshot!(response["hits"][0],
|
||||||
|
{ "._rankingScore" => "[score]" },
|
||||||
|
@"{}")
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
@ -402,7 +484,11 @@ async fn displayedattr_2_smol() {
|
|||||||
json!({ "attributesToRetrieve": ["cattos"], "attributesToHighlight": ["cattos"], "attributesToCrop": ["cattos"] }),
|
json!({ "attributesToRetrieve": ["cattos"], "attributesToHighlight": ["cattos"], "attributesToCrop": ["cattos"] }),
|
||||||
|response, code| {
|
|response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
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"] }),
|
json!({ "attributesToRetrieve": ["cattos"], "attributesToHighlight": ["id"] }),
|
||||||
|response, code| {
|
|response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"_formatted": {
|
@r###"
|
||||||
"id": "852",
|
{
|
||||||
}
|
"_formatted": {
|
||||||
})
|
"id": "852"
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
@ -430,14 +519,17 @@ async fn displayedattr_2_smol() {
|
|||||||
json!({ "attributesToRetrieve": ["cattos"], "attributesToCrop": ["id"] }),
|
json!({ "attributesToRetrieve": ["cattos"], "attributesToCrop": ["id"] }),
|
||||||
|response, code| {
|
|response, code| {
|
||||||
assert_eq!(code, 200, "{}", response);
|
assert_eq!(code, 200, "{}", response);
|
||||||
assert_eq!(
|
allow_duplicates! {
|
||||||
response["hits"][0],
|
assert_json_snapshot!(response["hits"][0],
|
||||||
json!({
|
{ "._rankingScore" => "[score]" },
|
||||||
"_formatted": {
|
@r###"
|
||||||
"id": "852",
|
{
|
||||||
}
|
"_formatted": {
|
||||||
})
|
"id": "852"
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
"###)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
@ -65,7 +65,7 @@ async fn simple_search_single_index() {
|
|||||||
]}))
|
]}))
|
||||||
.await;
|
.await;
|
||||||
snapshot!(code, @"200 OK");
|
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",
|
"indexUid": "test",
|
||||||
@ -170,7 +170,7 @@ async fn simple_search_two_indexes() {
|
|||||||
]}))
|
]}))
|
||||||
.await;
|
.await;
|
||||||
snapshot!(code, @"200 OK");
|
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",
|
"indexUid": "test",
|
||||||
|
@ -53,6 +53,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
&mut ctx,
|
&mut ctx,
|
||||||
&(!query.trim().is_empty()).then(|| query.trim().to_owned()),
|
&(!query.trim().is_empty()).then(|| query.trim().to_owned()),
|
||||||
TermsMatchingStrategy::Last,
|
TermsMatchingStrategy::Last,
|
||||||
|
milli::score_details::ScoringStrategy::Skip,
|
||||||
false,
|
false,
|
||||||
&None,
|
&None,
|
||||||
&None,
|
&None,
|
||||||
|
@ -2488,8 +2488,12 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
let rtxn = index.read_txn().unwrap();
|
let rtxn = index.read_txn().unwrap();
|
||||||
let search = Search::new(&rtxn, &index);
|
let search = Search::new(&rtxn, &index);
|
||||||
let SearchResult { matching_words: _, candidates: _, mut documents_ids } =
|
let SearchResult {
|
||||||
search.execute().unwrap();
|
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();
|
let primary_key_id = index.fields_ids_map(&rtxn).unwrap().id("primary_key").unwrap();
|
||||||
documents_ids.sort_unstable();
|
documents_ids.sort_unstable();
|
||||||
let docs = index.documents(&rtxn, documents_ids).unwrap();
|
let docs = index.documents(&rtxn, documents_ids).unwrap();
|
||||||
|
@ -17,6 +17,7 @@ mod fields_ids_map;
|
|||||||
pub mod heed_codec;
|
pub mod heed_codec;
|
||||||
pub mod index;
|
pub mod index;
|
||||||
pub mod proximity;
|
pub mod proximity;
|
||||||
|
pub mod score_details;
|
||||||
mod search;
|
mod search;
|
||||||
pub mod update;
|
pub mod update;
|
||||||
|
|
||||||
|
314
milli/src/score_details.rs
Normal file
314
milli/src/score_details.rs
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
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,
|
||||||
|
"attribute_ranking_order_score": 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 {
|
||||||
|
unimplemented!("position not preceded by attribute");
|
||||||
|
};
|
||||||
|
|
||||||
|
attribute_details
|
||||||
|
.insert("query_word_distance_score".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))
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ use roaring::bitmap::RoaringBitmap;
|
|||||||
pub use self::facet::{FacetDistribution, Filter, DEFAULT_VALUES_PER_FACET};
|
pub use self::facet::{FacetDistribution, Filter, DEFAULT_VALUES_PER_FACET};
|
||||||
pub use self::new::matches::{FormatOptions, MatchBounds, Matcher, MatcherBuilder, MatchingWords};
|
pub use self::new::matches::{FormatOptions, MatchBounds, Matcher, MatcherBuilder, MatchingWords};
|
||||||
use self::new::PartialSearchResult;
|
use self::new::PartialSearchResult;
|
||||||
|
use crate::score_details::{ScoreDetails, ScoringStrategy};
|
||||||
use crate::{
|
use crate::{
|
||||||
execute_search, AscDesc, DefaultSearchLogger, DocumentId, Index, Result, SearchContext,
|
execute_search, AscDesc, DefaultSearchLogger, DocumentId, Index, Result, SearchContext,
|
||||||
};
|
};
|
||||||
@ -29,6 +30,7 @@ pub struct Search<'a> {
|
|||||||
sort_criteria: Option<Vec<AscDesc>>,
|
sort_criteria: Option<Vec<AscDesc>>,
|
||||||
geo_strategy: new::GeoSortStrategy,
|
geo_strategy: new::GeoSortStrategy,
|
||||||
terms_matching_strategy: TermsMatchingStrategy,
|
terms_matching_strategy: TermsMatchingStrategy,
|
||||||
|
scoring_strategy: ScoringStrategy,
|
||||||
words_limit: usize,
|
words_limit: usize,
|
||||||
exhaustive_number_hits: bool,
|
exhaustive_number_hits: bool,
|
||||||
rtxn: &'a heed::RoTxn<'a>,
|
rtxn: &'a heed::RoTxn<'a>,
|
||||||
@ -45,6 +47,7 @@ impl<'a> Search<'a> {
|
|||||||
sort_criteria: None,
|
sort_criteria: None,
|
||||||
geo_strategy: new::GeoSortStrategy::default(),
|
geo_strategy: new::GeoSortStrategy::default(),
|
||||||
terms_matching_strategy: TermsMatchingStrategy::default(),
|
terms_matching_strategy: TermsMatchingStrategy::default(),
|
||||||
|
scoring_strategy: Default::default(),
|
||||||
exhaustive_number_hits: false,
|
exhaustive_number_hits: false,
|
||||||
words_limit: 10,
|
words_limit: 10,
|
||||||
rtxn,
|
rtxn,
|
||||||
@ -77,6 +80,11 @@ impl<'a> Search<'a> {
|
|||||||
self
|
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> {
|
pub fn words_limit(&mut self, value: usize) -> &mut Search<'a> {
|
||||||
self.words_limit = value;
|
self.words_limit = value;
|
||||||
self
|
self
|
||||||
@ -93,7 +101,7 @@ impl<'a> Search<'a> {
|
|||||||
self
|
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.
|
/// this will increase the search time but allows finite pagination.
|
||||||
pub fn exhaustive_number_hits(&mut self, exhaustive_number_hits: bool) -> &mut Search<'a> {
|
pub fn exhaustive_number_hits(&mut self, exhaustive_number_hits: bool) -> &mut Search<'a> {
|
||||||
self.exhaustive_number_hits = exhaustive_number_hits;
|
self.exhaustive_number_hits = exhaustive_number_hits;
|
||||||
@ -102,11 +110,12 @@ impl<'a> Search<'a> {
|
|||||||
|
|
||||||
pub fn execute(&self) -> Result<SearchResult> {
|
pub fn execute(&self) -> Result<SearchResult> {
|
||||||
let mut ctx = SearchContext::new(self.index, self.rtxn);
|
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(
|
execute_search(
|
||||||
&mut ctx,
|
&mut ctx,
|
||||||
&self.query,
|
&self.query,
|
||||||
self.terms_matching_strategy,
|
self.terms_matching_strategy,
|
||||||
|
self.scoring_strategy,
|
||||||
self.exhaustive_number_hits,
|
self.exhaustive_number_hits,
|
||||||
&self.filter,
|
&self.filter,
|
||||||
&self.sort_criteria,
|
&self.sort_criteria,
|
||||||
@ -124,7 +133,7 @@ impl<'a> Search<'a> {
|
|||||||
None => MatchingWords::default(),
|
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,
|
sort_criteria,
|
||||||
geo_strategy: _,
|
geo_strategy: _,
|
||||||
terms_matching_strategy,
|
terms_matching_strategy,
|
||||||
|
scoring_strategy,
|
||||||
words_limit,
|
words_limit,
|
||||||
exhaustive_number_hits,
|
exhaustive_number_hits,
|
||||||
rtxn: _,
|
rtxn: _,
|
||||||
@ -150,6 +160,7 @@ impl fmt::Debug for Search<'_> {
|
|||||||
.field("limit", limit)
|
.field("limit", limit)
|
||||||
.field("sort_criteria", sort_criteria)
|
.field("sort_criteria", sort_criteria)
|
||||||
.field("terms_matching_strategy", terms_matching_strategy)
|
.field("terms_matching_strategy", terms_matching_strategy)
|
||||||
|
.field("scoring_strategy", scoring_strategy)
|
||||||
.field("exhaustive_number_hits", exhaustive_number_hits)
|
.field("exhaustive_number_hits", exhaustive_number_hits)
|
||||||
.field("words_limit", words_limit)
|
.field("words_limit", words_limit)
|
||||||
.finish()
|
.finish()
|
||||||
@ -160,8 +171,8 @@ impl fmt::Debug for Search<'_> {
|
|||||||
pub struct SearchResult {
|
pub struct SearchResult {
|
||||||
pub matching_words: MatchingWords,
|
pub matching_words: MatchingWords,
|
||||||
pub candidates: RoaringBitmap,
|
pub candidates: RoaringBitmap,
|
||||||
// TODO those documents ids should be associated with their criteria scores.
|
|
||||||
pub documents_ids: Vec<DocumentId>,
|
pub documents_ids: Vec<DocumentId>,
|
||||||
|
pub document_scores: Vec<Vec<ScoreDetails>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
@ -3,14 +3,18 @@ use roaring::RoaringBitmap;
|
|||||||
use super::logger::SearchLogger;
|
use super::logger::SearchLogger;
|
||||||
use super::ranking_rules::{BoxRankingRule, RankingRuleQueryTrait};
|
use super::ranking_rules::{BoxRankingRule, RankingRuleQueryTrait};
|
||||||
use super::SearchContext;
|
use super::SearchContext;
|
||||||
|
use crate::score_details::{ScoreDetails, ScoringStrategy};
|
||||||
use crate::search::new::distinct::{apply_distinct_rule, distinct_single_docid, DistinctOutput};
|
use crate::search::new::distinct::{apply_distinct_rule, distinct_single_docid, DistinctOutput};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
pub struct BucketSortOutput {
|
pub struct BucketSortOutput {
|
||||||
pub docids: Vec<u32>,
|
pub docids: Vec<u32>,
|
||||||
|
pub scores: Vec<Vec<ScoreDetails>>,
|
||||||
pub all_candidates: RoaringBitmap,
|
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>(
|
pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
|
||||||
ctx: &mut SearchContext<'ctx>,
|
ctx: &mut SearchContext<'ctx>,
|
||||||
mut ranking_rules: Vec<BoxRankingRule<'ctx, Q>>,
|
mut ranking_rules: Vec<BoxRankingRule<'ctx, Q>>,
|
||||||
@ -18,6 +22,7 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
|
|||||||
universe: &RoaringBitmap,
|
universe: &RoaringBitmap,
|
||||||
from: usize,
|
from: usize,
|
||||||
length: usize,
|
length: usize,
|
||||||
|
scoring_strategy: ScoringStrategy,
|
||||||
logger: &mut dyn SearchLogger<Q>,
|
logger: &mut dyn SearchLogger<Q>,
|
||||||
) -> Result<BucketSortOutput> {
|
) -> Result<BucketSortOutput> {
|
||||||
logger.initial_query(query);
|
logger.initial_query(query);
|
||||||
@ -31,7 +36,11 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
if universe.len() < from as u64 {
|
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 ranking_rules.is_empty() {
|
||||||
if let Some(distinct_fid) = distinct_fid {
|
if let Some(distinct_fid) = distinct_fid {
|
||||||
@ -49,22 +58,32 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
|
|||||||
}
|
}
|
||||||
let mut all_candidates = universe - excluded;
|
let mut all_candidates = universe - excluded;
|
||||||
all_candidates.extend(results.iter().copied());
|
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 {
|
} else {
|
||||||
let docids = universe.iter().skip(from).take(length).collect();
|
let docids: Vec<u32> = universe.iter().skip(from).take(length).collect();
|
||||||
return Ok(BucketSortOutput { docids, all_candidates: universe.clone() });
|
return Ok(BucketSortOutput {
|
||||||
|
scores: vec![Default::default(); docids.len()],
|
||||||
|
docids,
|
||||||
|
all_candidates: universe.clone(),
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let ranking_rules_len = ranking_rules.len();
|
let ranking_rules_len = ranking_rules.len();
|
||||||
|
|
||||||
logger.start_iteration_ranking_rule(0, ranking_rules[0].as_ref(), query, universe);
|
logger.start_iteration_ranking_rule(0, ranking_rules[0].as_ref(), query, universe);
|
||||||
|
|
||||||
ranking_rules[0].start_iteration(ctx, logger, universe, query)?;
|
ranking_rules[0].start_iteration(ctx, logger, universe, query)?;
|
||||||
|
|
||||||
|
let mut ranking_rule_scores: Vec<ScoreDetails> = vec![];
|
||||||
|
|
||||||
let mut ranking_rule_universes: Vec<RoaringBitmap> =
|
let mut ranking_rule_universes: Vec<RoaringBitmap> =
|
||||||
vec![RoaringBitmap::default(); ranking_rules_len];
|
vec![RoaringBitmap::default(); ranking_rules_len];
|
||||||
ranking_rule_universes[0] = universe.clone();
|
ranking_rule_universes[0] = universe.clone();
|
||||||
|
|
||||||
let mut cur_ranking_rule_index = 0;
|
let mut cur_ranking_rule_index = 0;
|
||||||
|
|
||||||
/// Finish iterating over the current ranking rule, yielding
|
/// Finish iterating over the current ranking rule, yielding
|
||||||
@ -89,11 +108,15 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
|
|||||||
} else {
|
} else {
|
||||||
cur_ranking_rule_index -= 1;
|
cur_ranking_rule_index -= 1;
|
||||||
}
|
}
|
||||||
|
if ranking_rule_scores.len() > cur_ranking_rule_index {
|
||||||
|
ranking_rule_scores.pop();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut all_candidates = universe.clone();
|
let mut all_candidates = universe.clone();
|
||||||
let mut valid_docids = vec![];
|
let mut valid_docids = vec![];
|
||||||
|
let mut valid_scores = vec![];
|
||||||
let mut cur_offset = 0usize;
|
let mut cur_offset = 0usize;
|
||||||
|
|
||||||
macro_rules! maybe_add_to_results {
|
macro_rules! maybe_add_to_results {
|
||||||
@ -104,21 +127,26 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
|
|||||||
length,
|
length,
|
||||||
logger,
|
logger,
|
||||||
&mut valid_docids,
|
&mut valid_docids,
|
||||||
|
&mut valid_scores,
|
||||||
&mut all_candidates,
|
&mut all_candidates,
|
||||||
&mut ranking_rule_universes,
|
&mut ranking_rule_universes,
|
||||||
&mut ranking_rules,
|
&mut ranking_rules,
|
||||||
cur_ranking_rule_index,
|
cur_ranking_rule_index,
|
||||||
&mut cur_offset,
|
&mut cur_offset,
|
||||||
distinct_fid,
|
distinct_fid,
|
||||||
|
&ranking_rule_scores,
|
||||||
$candidates,
|
$candidates,
|
||||||
)?;
|
)?;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
while valid_docids.len() < length {
|
while valid_docids.len() < length {
|
||||||
// The universe for this bucket is zero or one element, so we don't need to sort
|
// The universe for this bucket is zero, so we don't need to sort
|
||||||
// anything, just extend the results and go back to the parent ranking rule.
|
// anything, just go back to the parent ranking rule.
|
||||||
if ranking_rule_universes[cur_ranking_rule_index].len() <= 1 {
|
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]);
|
let bucket = std::mem::take(&mut ranking_rule_universes[cur_ranking_rule_index]);
|
||||||
maybe_add_to_results!(bucket);
|
maybe_add_to_results!(bucket);
|
||||||
back!();
|
back!();
|
||||||
@ -130,6 +158,8 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ranking_rule_scores.push(next_bucket.score);
|
||||||
|
|
||||||
logger.next_bucket_ranking_rule(
|
logger.next_bucket_ranking_rule(
|
||||||
cur_ranking_rule_index,
|
cur_ranking_rule_index,
|
||||||
ranking_rules[cur_ranking_rule_index].as_ref(),
|
ranking_rules[cur_ranking_rule_index].as_ref(),
|
||||||
@ -143,10 +173,11 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
|
|||||||
ranking_rule_universes[cur_ranking_rule_index] -= &next_bucket.candidates;
|
ranking_rule_universes[cur_ranking_rule_index] -= &next_bucket.candidates;
|
||||||
|
|
||||||
if cur_ranking_rule_index == ranking_rules_len - 1
|
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
|
|| cur_offset + (next_bucket.candidates.len() as usize) < from
|
||||||
{
|
{
|
||||||
maybe_add_to_results!(next_bucket.candidates);
|
maybe_add_to_results!(next_bucket.candidates);
|
||||||
|
ranking_rule_scores.pop();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +197,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`
|
/// Add the candidates to the results. Take `distinct`, `from`, `length`, and `cur_offset`
|
||||||
@ -179,14 +210,18 @@ fn maybe_add_to_results<'ctx, Q: RankingRuleQueryTrait>(
|
|||||||
logger: &mut dyn SearchLogger<Q>,
|
logger: &mut dyn SearchLogger<Q>,
|
||||||
|
|
||||||
valid_docids: &mut Vec<u32>,
|
valid_docids: &mut Vec<u32>,
|
||||||
|
valid_scores: &mut Vec<Vec<ScoreDetails>>,
|
||||||
all_candidates: &mut RoaringBitmap,
|
all_candidates: &mut RoaringBitmap,
|
||||||
|
|
||||||
ranking_rule_universes: &mut [RoaringBitmap],
|
ranking_rule_universes: &mut [RoaringBitmap],
|
||||||
ranking_rules: &mut [BoxRankingRule<'ctx, Q>],
|
ranking_rules: &mut [BoxRankingRule<'ctx, Q>],
|
||||||
|
|
||||||
cur_ranking_rule_index: usize,
|
cur_ranking_rule_index: usize,
|
||||||
|
|
||||||
cur_offset: &mut usize,
|
cur_offset: &mut usize,
|
||||||
|
|
||||||
distinct_fid: Option<u16>,
|
distinct_fid: Option<u16>,
|
||||||
|
ranking_rule_scores: &[ScoreDetails],
|
||||||
candidates: RoaringBitmap,
|
candidates: RoaringBitmap,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// First apply the distinct rule on the candidates, reducing the universes if necessary
|
// First apply the distinct rule on the candidates, reducing the universes if necessary
|
||||||
@ -231,13 +266,17 @@ fn maybe_add_to_results<'ctx, Q: RankingRuleQueryTrait>(
|
|||||||
let candidates =
|
let candidates =
|
||||||
candidates.iter().take(length - valid_docids.len()).copied().collect::<Vec<_>>();
|
candidates.iter().take(length - valid_docids.len()).copied().collect::<Vec<_>>();
|
||||||
logger.add_to_results(&candidates);
|
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 {
|
} else {
|
||||||
// if we have passed the offset already, add some of the documents (up to the limit)
|
// 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>>();
|
let candidates = candidates.iter().take(length - valid_docids.len()).collect::<Vec<u32>>();
|
||||||
logger.add_to_results(&candidates);
|
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;
|
*cur_offset += candidates.len() as usize;
|
||||||
|
@ -2,6 +2,7 @@ use roaring::{MultiOps, RoaringBitmap};
|
|||||||
|
|
||||||
use super::query_graph::QueryGraph;
|
use super::query_graph::QueryGraph;
|
||||||
use super::ranking_rules::{RankingRule, RankingRuleOutput};
|
use super::ranking_rules::{RankingRule, RankingRuleOutput};
|
||||||
|
use crate::score_details::{self, ScoreDetails};
|
||||||
use crate::search::new::query_graph::QueryNodeData;
|
use crate::search::new::query_graph::QueryNodeData;
|
||||||
use crate::search::new::query_term::ExactTerm;
|
use crate::search::new::query_term::ExactTerm;
|
||||||
use crate::{Result, SearchContext, SearchLogger};
|
use crate::{Result, SearchContext, SearchLogger};
|
||||||
@ -244,7 +245,13 @@ impl State {
|
|||||||
candidates &= universe;
|
candidates &= universe;
|
||||||
(
|
(
|
||||||
State::AttributeStarts(query_graph.clone(), candidates_per_attribute),
|
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) => {
|
State::AttributeStarts(query_graph, candidates_per_attribute) => {
|
||||||
@ -257,12 +264,24 @@ impl State {
|
|||||||
candidates &= universe;
|
candidates &= universe;
|
||||||
(
|
(
|
||||||
State::Empty(query_graph.clone()),
|
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) => (
|
||||||
State::Empty(query_graph.clone()),
|
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)
|
(state, output)
|
||||||
|
@ -8,6 +8,7 @@ use rstar::RTree;
|
|||||||
|
|
||||||
use super::ranking_rules::{RankingRule, RankingRuleOutput, RankingRuleQueryTrait};
|
use super::ranking_rules::{RankingRule, RankingRuleOutput, RankingRuleQueryTrait};
|
||||||
use crate::heed_codec::facet::{FieldDocIdFacetCodec, OrderedF64Codec};
|
use crate::heed_codec::facet::{FieldDocIdFacetCodec, OrderedF64Codec};
|
||||||
|
use crate::score_details::{self, ScoreDetails};
|
||||||
use crate::{
|
use crate::{
|
||||||
distance_between_two_points, lat_lng_to_xyz, GeoPoint, Index, Result, SearchContext,
|
distance_between_two_points, lat_lng_to_xyz, GeoPoint, Index, Result, SearchContext,
|
||||||
SearchLogger,
|
SearchLogger,
|
||||||
@ -80,7 +81,7 @@ pub struct GeoSort<Q: RankingRuleQueryTrait> {
|
|||||||
field_ids: Option<[u16; 2]>,
|
field_ids: Option<[u16; 2]>,
|
||||||
rtree: Option<RTree<GeoPoint>>,
|
rtree: Option<RTree<GeoPoint>>,
|
||||||
|
|
||||||
cached_sorted_docids: VecDeque<u32>,
|
cached_sorted_docids: VecDeque<(u32, [f64; 2])>,
|
||||||
geo_candidates: RoaringBitmap,
|
geo_candidates: RoaringBitmap,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +131,7 @@ impl<Q: RankingRuleQueryTrait> GeoSort<Q> {
|
|||||||
let point = lat_lng_to_xyz(&self.point);
|
let point = lat_lng_to_xyz(&self.point);
|
||||||
for point in rtree.nearest_neighbor_iter(&point) {
|
for point in rtree.nearest_neighbor_iter(&point) {
|
||||||
if self.geo_candidates.contains(point.data.0) {
|
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 {
|
if self.cached_sorted_docids.len() >= cache_size {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -142,7 +143,7 @@ impl<Q: RankingRuleQueryTrait> GeoSort<Q> {
|
|||||||
let point = lat_lng_to_xyz(&opposite_of(self.point));
|
let point = lat_lng_to_xyz(&opposite_of(self.point));
|
||||||
for point in rtree.nearest_neighbor_iter(&point) {
|
for point in rtree.nearest_neighbor_iter(&point) {
|
||||||
if self.geo_candidates.contains(point.data.0) {
|
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 {
|
if self.cached_sorted_docids.len() >= cache_size {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -177,7 +178,7 @@ impl<Q: RankingRuleQueryTrait> GeoSort<Q> {
|
|||||||
// computing the distance between two points is expensive thus we cache the result
|
// computing the distance between two points is expensive thus we cache the result
|
||||||
documents
|
documents
|
||||||
.sort_by_cached_key(|(_, p)| distance_between_two_points(&self.point, p) as usize);
|
.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(())
|
Ok(())
|
||||||
@ -220,12 +221,19 @@ impl<'ctx, Q: RankingRuleQueryTrait> RankingRule<'ctx, Q> for GeoSort<Q> {
|
|||||||
logger: &mut dyn SearchLogger<Q>,
|
logger: &mut dyn SearchLogger<Q>,
|
||||||
universe: &RoaringBitmap,
|
universe: &RoaringBitmap,
|
||||||
) -> Result<Option<RankingRuleOutput<Q>>> {
|
) -> Result<Option<RankingRuleOutput<Q>>> {
|
||||||
assert!(universe.len() > 1);
|
|
||||||
let query = self.query.as_ref().unwrap().clone();
|
let query = self.query.as_ref().unwrap().clone();
|
||||||
self.geo_candidates &= universe;
|
self.geo_candidates &= universe;
|
||||||
|
|
||||||
if self.geo_candidates.is_empty() {
|
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;
|
let ascending = self.ascending;
|
||||||
@ -236,11 +244,16 @@ impl<'ctx, Q: RankingRuleQueryTrait> RankingRule<'ctx, Q> for GeoSort<Q> {
|
|||||||
cache.pop_back()
|
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) {
|
if self.geo_candidates.contains(id) {
|
||||||
return Ok(Some(RankingRuleOutput {
|
return Ok(Some(RankingRuleOutput {
|
||||||
query,
|
query,
|
||||||
candidates: RoaringBitmap::from_iter([id]),
|
candidates: RoaringBitmap::from_iter([id]),
|
||||||
|
score: ScoreDetails::GeoSort(score_details::GeoSort {
|
||||||
|
target_point: self.point,
|
||||||
|
ascending: self.ascending,
|
||||||
|
value: Some(point),
|
||||||
|
}),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ use super::ranking_rule_graph::{
|
|||||||
};
|
};
|
||||||
use super::small_bitmap::SmallBitmap;
|
use super::small_bitmap::SmallBitmap;
|
||||||
use super::{QueryGraph, RankingRule, RankingRuleOutput, SearchContext};
|
use super::{QueryGraph, RankingRule, RankingRuleOutput, SearchContext};
|
||||||
|
use crate::score_details::Rank;
|
||||||
use crate::search::new::query_term::LocatedQueryTermSubset;
|
use crate::search::new::query_term::LocatedQueryTermSubset;
|
||||||
use crate::search::new::ranking_rule_graph::PathVisitor;
|
use crate::search::new::ranking_rule_graph::PathVisitor;
|
||||||
use crate::{Result, TermsMatchingStrategy};
|
use crate::{Result, TermsMatchingStrategy};
|
||||||
@ -118,6 +119,8 @@ pub struct GraphBasedRankingRuleState<G: RankingRuleGraphTrait> {
|
|||||||
all_costs: MappedInterner<QueryNode, Vec<u64>>,
|
all_costs: MappedInterner<QueryNode, Vec<u64>>,
|
||||||
/// An index in the first element of `all_distances`, giving the cost of the next bucket
|
/// An index in the first element of `all_distances`, giving the cost of the next bucket
|
||||||
cur_cost: u64,
|
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> {
|
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,
|
_universe: &RoaringBitmap,
|
||||||
query_graph: &QueryGraph,
|
query_graph: &QueryGraph,
|
||||||
) -> Result<()> {
|
) -> 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 {
|
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 {
|
match terms_matching_strategy {
|
||||||
TermsMatchingStrategy::Last => {
|
TermsMatchingStrategy::Last => {
|
||||||
let removal_order =
|
let removal_order =
|
||||||
@ -139,13 +155,12 @@ impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBase
|
|||||||
let mut forbidden_nodes =
|
let mut forbidden_nodes =
|
||||||
SmallBitmap::for_interned_values_in(&query_graph.nodes);
|
SmallBitmap::for_interned_values_in(&query_graph.nodes);
|
||||||
let mut costs = query_graph.nodes.map(|_| None);
|
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 ns in removal_order {
|
||||||
for n in ns.iter() {
|
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);
|
forbidden_nodes.union(&ns);
|
||||||
cost += 100;
|
|
||||||
}
|
}
|
||||||
costs
|
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
|
// Then pre-compute the cost of all paths from each node to the end node
|
||||||
let all_costs = graph.find_all_costs_to_end();
|
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 {
|
let state = GraphBasedRankingRuleState {
|
||||||
graph,
|
graph,
|
||||||
conditions_cache: condition_docids_cache,
|
conditions_cache: condition_docids_cache,
|
||||||
dead_ends_cache,
|
dead_ends_cache,
|
||||||
all_costs,
|
all_costs,
|
||||||
cur_cost: 0,
|
cur_cost: 0,
|
||||||
|
next_max_cost,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.state = Some(state);
|
self.state = Some(state);
|
||||||
@ -181,17 +200,13 @@ impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBase
|
|||||||
logger: &mut dyn SearchLogger<QueryGraph>,
|
logger: &mut dyn SearchLogger<QueryGraph>,
|
||||||
universe: &RoaringBitmap,
|
universe: &RoaringBitmap,
|
||||||
) -> Result<Option<RankingRuleOutput<QueryGraph>>> {
|
) -> 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`,
|
// Will crash if `next_bucket` is called before `start_iteration` or after `end_iteration`,
|
||||||
// should never happen
|
// should never happen
|
||||||
let mut state = self.state.take().unwrap();
|
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
|
// Retrieve the cost of the paths to compute
|
||||||
let Some(&cost) = state
|
let Some(&cost) = all_costs
|
||||||
.all_costs
|
|
||||||
.get(state.graph.query_graph.root_node)
|
|
||||||
.iter()
|
.iter()
|
||||||
.find(|c| **c >= state.cur_cost) else {
|
.find(|c| **c >= state.cur_cost) else {
|
||||||
self.state = None;
|
self.state = None;
|
||||||
@ -207,8 +222,12 @@ impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBase
|
|||||||
dead_ends_cache,
|
dead_ends_cache,
|
||||||
all_costs,
|
all_costs,
|
||||||
cur_cost: _,
|
cur_cost: _,
|
||||||
|
next_max_cost,
|
||||||
} = &mut state;
|
} = &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 universe = universe.clone();
|
||||||
|
|
||||||
let mut used_conditions = SmallBitmap::for_interned_values_in(&graph.conditions_interner);
|
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
|
// We modify the next query graph so that it only contains the subgraph
|
||||||
// that was used to compute this bucket
|
// 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
|
let paths: Vec<Vec<(Option<LocatedQueryTermSubset>, LocatedQueryTermSubset)>> = good_paths
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -325,7 +342,7 @@ impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBase
|
|||||||
|
|
||||||
self.state = Some(state);
|
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(
|
fn end_iteration(
|
||||||
|
@ -510,6 +510,7 @@ mod tests {
|
|||||||
&mut ctx,
|
&mut ctx,
|
||||||
&Some(query.to_string()),
|
&Some(query.to_string()),
|
||||||
crate::TermsMatchingStrategy::default(),
|
crate::TermsMatchingStrategy::default(),
|
||||||
|
crate::score_details::ScoringStrategy::Skip,
|
||||||
false,
|
false,
|
||||||
&None,
|
&None,
|
||||||
&None,
|
&None,
|
||||||
|
@ -44,6 +44,7 @@ use self::geo_sort::GeoSort;
|
|||||||
pub use self::geo_sort::Strategy as GeoSortStrategy;
|
pub use self::geo_sort::Strategy as GeoSortStrategy;
|
||||||
use self::graph_based_ranking_rule::Words;
|
use self::graph_based_ranking_rule::Words;
|
||||||
use self::interner::Interned;
|
use self::interner::Interned;
|
||||||
|
use crate::score_details::{ScoreDetails, ScoringStrategy};
|
||||||
use crate::search::new::distinct::apply_distinct_rule;
|
use crate::search::new::distinct::apply_distinct_rule;
|
||||||
use crate::{AscDesc, DocumentId, Filter, Index, Member, Result, TermsMatchingStrategy, UserError};
|
use crate::{AscDesc, DocumentId, Filter, Index, Member, Result, TermsMatchingStrategy, UserError};
|
||||||
|
|
||||||
@ -350,6 +351,7 @@ pub fn execute_search(
|
|||||||
ctx: &mut SearchContext,
|
ctx: &mut SearchContext,
|
||||||
query: &Option<String>,
|
query: &Option<String>,
|
||||||
terms_matching_strategy: TermsMatchingStrategy,
|
terms_matching_strategy: TermsMatchingStrategy,
|
||||||
|
scoring_strategy: ScoringStrategy,
|
||||||
exhaustive_number_hits: bool,
|
exhaustive_number_hits: bool,
|
||||||
filters: &Option<Filter>,
|
filters: &Option<Filter>,
|
||||||
sort_criteria: &Option<Vec<AscDesc>>,
|
sort_criteria: &Option<Vec<AscDesc>>,
|
||||||
@ -411,7 +413,16 @@ pub fn execute_search(
|
|||||||
universe =
|
universe =
|
||||||
resolve_universe(ctx, &universe, &graph, terms_matching_strategy, query_graph_logger)?;
|
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 {
|
} else {
|
||||||
let ranking_rules =
|
let ranking_rules =
|
||||||
get_ranking_rules_for_placeholder_search(ctx, sort_criteria, geo_strategy)?;
|
get_ranking_rules_for_placeholder_search(ctx, sort_criteria, geo_strategy)?;
|
||||||
@ -422,17 +433,20 @@ pub fn execute_search(
|
|||||||
&universe,
|
&universe,
|
||||||
from,
|
from,
|
||||||
length,
|
length,
|
||||||
|
scoring_strategy,
|
||||||
placeholder_search_logger,
|
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
|
// The candidates is the universe unless the exhaustive number of hits
|
||||||
// is requested and a distinct attribute is set.
|
// is requested and a distinct attribute is set.
|
||||||
if exhaustive_number_hits {
|
if exhaustive_number_hits {
|
||||||
if let Some(f) = ctx.index.distinct_field(ctx.txn)? {
|
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;
|
all_candidates = apply_distinct_rule(ctx, distinct_fid, &all_candidates)?.remaining;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -440,6 +454,7 @@ pub fn execute_search(
|
|||||||
|
|
||||||
Ok(PartialSearchResult {
|
Ok(PartialSearchResult {
|
||||||
candidates: all_candidates,
|
candidates: all_candidates,
|
||||||
|
document_scores: scores,
|
||||||
documents_ids: docids,
|
documents_ids: docids,
|
||||||
located_query_terms,
|
located_query_terms,
|
||||||
})
|
})
|
||||||
@ -491,4 +506,5 @@ pub struct PartialSearchResult {
|
|||||||
pub located_query_terms: Option<Vec<LocatedQueryTerm>>,
|
pub located_query_terms: Option<Vec<LocatedQueryTerm>>,
|
||||||
pub candidates: RoaringBitmap,
|
pub candidates: RoaringBitmap,
|
||||||
pub documents_ids: Vec<DocumentId>,
|
pub documents_ids: Vec<DocumentId>,
|
||||||
|
pub document_scores: Vec<Vec<ScoreDetails>>,
|
||||||
}
|
}
|
||||||
|
@ -342,6 +342,25 @@ impl QueryGraph {
|
|||||||
}
|
}
|
||||||
res
|
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 {
|
fn add_node(nodes_data: &mut Vec<QueryNodeData>, node_data: QueryNodeData) -> u16 {
|
||||||
|
@ -49,10 +49,15 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
|
|||||||
if let Some((cost_of_ignoring, forbidden_nodes)) =
|
if let Some((cost_of_ignoring, forbidden_nodes)) =
|
||||||
cost_of_ignoring_node.get(dest_idx)
|
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 {
|
let new_edge_id = edges_store.insert(Some(Edge {
|
||||||
source_node: source_id,
|
source_node: source_id,
|
||||||
dest_node: dest_idx,
|
dest_node: dest_idx,
|
||||||
cost: *cost_of_ignoring,
|
cost: *cost_of_ignoring * dest_size as u32,
|
||||||
condition: None,
|
condition: None,
|
||||||
nodes_to_skip: forbidden_nodes.clone(),
|
nodes_to_skip: forbidden_nodes.clone(),
|
||||||
}));
|
}));
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use roaring::RoaringBitmap;
|
use roaring::RoaringBitmap;
|
||||||
|
|
||||||
use super::{ComputedCondition, RankingRuleGraphTrait};
|
use super::{ComputedCondition, RankingRuleGraphTrait};
|
||||||
|
use crate::score_details::{Rank, ScoreDetails};
|
||||||
use crate::search::new::interner::{DedupInterner, Interned};
|
use crate::search::new::interner::{DedupInterner, Interned};
|
||||||
use crate::search::new::query_term::{ExactTerm, LocatedQueryTermSubset};
|
use crate::search::new::query_term::{ExactTerm, LocatedQueryTermSubset};
|
||||||
use crate::search::new::resolve_query_graph::compute_query_term_subset_docids;
|
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)])
|
Ok(vec![(0, exact_condition), (dest_node.term_ids.len() as u32, skip_condition)])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rank_to_score(rank: Rank) -> ScoreDetails {
|
||||||
|
ScoreDetails::Exactness(rank)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ use fxhash::FxHashSet;
|
|||||||
use roaring::RoaringBitmap;
|
use roaring::RoaringBitmap;
|
||||||
|
|
||||||
use super::{ComputedCondition, RankingRuleGraphTrait};
|
use super::{ComputedCondition, RankingRuleGraphTrait};
|
||||||
|
use crate::score_details::{Rank, ScoreDetails};
|
||||||
use crate::search::new::interner::{DedupInterner, Interned};
|
use crate::search::new::interner::{DedupInterner, Interned};
|
||||||
use crate::search::new::query_term::LocatedQueryTermSubset;
|
use crate::search::new::query_term::LocatedQueryTermSubset;
|
||||||
use crate::search::new::resolve_query_graph::compute_query_term_subset_docids_within_field_id;
|
use crate::search::new::resolve_query_graph::compute_query_term_subset_docids_within_field_id;
|
||||||
@ -68,13 +69,42 @@ impl RankingRuleGraphTrait for FidGraph {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut edges = vec![];
|
let mut edges = vec![];
|
||||||
for fid in all_fields {
|
for fid in all_fields.iter().copied() {
|
||||||
edges.push((
|
edges.push((
|
||||||
fid as u32 * term.term_ids.len() as u32,
|
fid as u32 * term.term_ids.len() as u32,
|
||||||
conditions_interner.insert(FidCondition { term: term.clone(), fid }),
|
conditions_interner.insert(FidCondition { term: term.clone(), fid }),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
Ok(edges)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rank_to_score(rank: Rank) -> ScoreDetails {
|
||||||
|
ScoreDetails::Fid(rank)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ use super::interner::{DedupInterner, FixedSizeInterner, Interned, MappedInterner
|
|||||||
use super::query_term::LocatedQueryTermSubset;
|
use super::query_term::LocatedQueryTermSubset;
|
||||||
use super::small_bitmap::SmallBitmap;
|
use super::small_bitmap::SmallBitmap;
|
||||||
use super::{QueryGraph, QueryNode, SearchContext};
|
use super::{QueryGraph, QueryNode, SearchContext};
|
||||||
|
use crate::score_details::{Rank, ScoreDetails};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
pub struct ComputedCondition {
|
pub struct ComputedCondition {
|
||||||
@ -110,6 +111,9 @@ pub trait RankingRuleGraphTrait: Sized + 'static {
|
|||||||
source_node: Option<&LocatedQueryTermSubset>,
|
source_node: Option<&LocatedQueryTermSubset>,
|
||||||
dest_node: &LocatedQueryTermSubset,
|
dest_node: &LocatedQueryTermSubset,
|
||||||
) -> Result<Vec<(u32, Interned<Self::Condition>)>>;
|
) -> 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.
|
/// The graph used by graph-based ranking rules.
|
||||||
|
@ -2,6 +2,7 @@ use fxhash::{FxHashMap, FxHashSet};
|
|||||||
use roaring::RoaringBitmap;
|
use roaring::RoaringBitmap;
|
||||||
|
|
||||||
use super::{ComputedCondition, RankingRuleGraphTrait};
|
use super::{ComputedCondition, RankingRuleGraphTrait};
|
||||||
|
use crate::score_details::{Rank, ScoreDetails};
|
||||||
use crate::search::new::interner::{DedupInterner, Interned};
|
use crate::search::new::interner::{DedupInterner, Interned};
|
||||||
use crate::search::new::query_term::LocatedQueryTermSubset;
|
use crate::search::new::query_term::LocatedQueryTermSubset;
|
||||||
use crate::search::new::resolve_query_graph::compute_query_term_subset_docids_within_position;
|
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();
|
let mut positions_for_costs = FxHashMap::<u32, Vec<u16>>::default();
|
||||||
|
|
||||||
for position in all_positions {
|
for position in all_positions {
|
||||||
|
// FIXME: bucketed position???
|
||||||
|
let distance = position.abs_diff(*term.positions.start());
|
||||||
let cost = {
|
let cost = {
|
||||||
let mut cost = 0;
|
let mut cost = 0;
|
||||||
for i in 0..term.term_ids.len() {
|
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,
|
// 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
|
// 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
|
// 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
|
cost
|
||||||
};
|
};
|
||||||
positions_for_costs.entry(cost).or_default().push(position);
|
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 {
|
for (cost, positions) in positions_for_costs {
|
||||||
edges.push((
|
edges.push((
|
||||||
cost,
|
cost,
|
||||||
@ -100,12 +105,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)
|
Ok(edges)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rank_to_score(rank: Rank) -> ScoreDetails {
|
||||||
|
ScoreDetails::Position(rank)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cost_from_position(sum_positions: u32) -> u32 {
|
fn cost_from_distance(distance: u32) -> u32 {
|
||||||
match sum_positions {
|
match distance {
|
||||||
0 => 0,
|
0 => 0,
|
||||||
1 => 1,
|
1 => 1,
|
||||||
2..=4 => 2,
|
2..=4 => 2,
|
||||||
|
@ -12,11 +12,11 @@ pub fn build_edges(
|
|||||||
left_term: Option<&LocatedQueryTermSubset>,
|
left_term: Option<&LocatedQueryTermSubset>,
|
||||||
right_term: &LocatedQueryTermSubset,
|
right_term: &LocatedQueryTermSubset,
|
||||||
) -> Result<Vec<(u32, Interned<ProximityCondition>)>> {
|
) -> 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 {
|
let Some(left_term) = left_term else {
|
||||||
return Ok(vec![(
|
return Ok(vec![(
|
||||||
(right_ngram_length - 1) as u32,
|
right_ngram_max as u32,
|
||||||
conditions_interner.insert(ProximityCondition::Term { term: right_term.clone() }),
|
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`
|
// The remaining query graph represents `the sun .. are beautiful`
|
||||||
// but `sun` and `are` have no proximity condition between them
|
// but `sun` and `are` have no proximity condition between them
|
||||||
return Ok(vec![(
|
return Ok(vec![(
|
||||||
(right_ngram_length - 1) as u32,
|
right_ngram_max as u32,
|
||||||
conditions_interner.insert(ProximityCondition::Term { term: right_term.clone() }),
|
conditions_interner.insert(ProximityCondition::Term { term: right_term.clone() }),
|
||||||
)]);
|
)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut conditions = vec![];
|
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((
|
conditions.push((
|
||||||
cost as u32,
|
cost as u32,
|
||||||
conditions_interner.insert(ProximityCondition::Uninit {
|
conditions_interner.insert(ProximityCondition::Uninit {
|
||||||
left_term: left_term.clone(),
|
left_term: left_term.clone(),
|
||||||
right_term: right_term.clone(),
|
right_term: right_term.clone(),
|
||||||
cost: cost as u8,
|
cost: (cost + 1) as u8,
|
||||||
}),
|
}),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
conditions.push((
|
conditions.push((
|
||||||
(7 + right_ngram_length) as u32,
|
(7 + right_ngram_max) as u32,
|
||||||
conditions_interner.insert(ProximityCondition::Term { term: right_term.clone() }),
|
conditions_interner.insert(ProximityCondition::Term { term: right_term.clone() }),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ pub mod compute_docids;
|
|||||||
use roaring::RoaringBitmap;
|
use roaring::RoaringBitmap;
|
||||||
|
|
||||||
use super::{ComputedCondition, RankingRuleGraphTrait};
|
use super::{ComputedCondition, RankingRuleGraphTrait};
|
||||||
|
use crate::score_details::{Rank, ScoreDetails};
|
||||||
use crate::search::new::interner::{DedupInterner, Interned};
|
use crate::search::new::interner::{DedupInterner, Interned};
|
||||||
use crate::search::new::query_term::LocatedQueryTermSubset;
|
use crate::search::new::query_term::LocatedQueryTermSubset;
|
||||||
use crate::search::new::SearchContext;
|
use crate::search::new::SearchContext;
|
||||||
@ -36,4 +37,8 @@ impl RankingRuleGraphTrait for ProximityGraph {
|
|||||||
) -> Result<Vec<(u32, Interned<Self::Condition>)>> {
|
) -> Result<Vec<(u32, Interned<Self::Condition>)>> {
|
||||||
build::build_edges(ctx, conditions_interner, source_term, dest_term)
|
build::build_edges(ctx, conditions_interner, source_term, dest_term)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rank_to_score(rank: Rank) -> ScoreDetails {
|
||||||
|
ScoreDetails::Proximity(rank)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use roaring::RoaringBitmap;
|
use roaring::RoaringBitmap;
|
||||||
|
|
||||||
use super::{ComputedCondition, RankingRuleGraphTrait};
|
use super::{ComputedCondition, RankingRuleGraphTrait};
|
||||||
|
use crate::score_details::{self, Rank, ScoreDetails};
|
||||||
use crate::search::new::interner::{DedupInterner, Interned};
|
use crate::search::new::interner::{DedupInterner, Interned};
|
||||||
use crate::search::new::query_term::LocatedQueryTermSubset;
|
use crate::search::new::query_term::LocatedQueryTermSubset;
|
||||||
use crate::search::new::resolve_query_graph::compute_query_term_subset_docids;
|
use crate::search::new::resolve_query_graph::compute_query_term_subset_docids;
|
||||||
@ -75,4 +76,8 @@ impl RankingRuleGraphTrait for TypoGraph {
|
|||||||
}
|
}
|
||||||
Ok(edges)
|
Ok(edges)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rank_to_score(rank: Rank) -> ScoreDetails {
|
||||||
|
ScoreDetails::Typo(score_details::Typo::from_rank(rank))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use roaring::RoaringBitmap;
|
use roaring::RoaringBitmap;
|
||||||
|
|
||||||
use super::{ComputedCondition, RankingRuleGraphTrait};
|
use super::{ComputedCondition, RankingRuleGraphTrait};
|
||||||
|
use crate::score_details::{self, Rank, ScoreDetails};
|
||||||
use crate::search::new::interner::{DedupInterner, Interned};
|
use crate::search::new::interner::{DedupInterner, Interned};
|
||||||
use crate::search::new::query_term::LocatedQueryTermSubset;
|
use crate::search::new::query_term::LocatedQueryTermSubset;
|
||||||
use crate::search::new::resolve_query_graph::compute_query_term_subset_docids;
|
use crate::search::new::resolve_query_graph::compute_query_term_subset_docids;
|
||||||
@ -41,9 +42,10 @@ impl RankingRuleGraphTrait for WordsGraph {
|
|||||||
_from: Option<&LocatedQueryTermSubset>,
|
_from: Option<&LocatedQueryTermSubset>,
|
||||||
to_term: &LocatedQueryTermSubset,
|
to_term: &LocatedQueryTermSubset,
|
||||||
) -> Result<Vec<(u32, Interned<Self::Condition>)>> {
|
) -> Result<Vec<(u32, Interned<Self::Condition>)>> {
|
||||||
Ok(vec![(
|
Ok(vec![(0, conditions_interner.insert(WordsCondition { term: to_term.clone() }))])
|
||||||
to_term.term_ids.len() as u32,
|
}
|
||||||
conditions_interner.insert(WordsCondition { term: to_term.clone() }),
|
|
||||||
)])
|
fn rank_to_score(rank: Rank) -> ScoreDetails {
|
||||||
|
ScoreDetails::Words(score_details::Words::from_rank(rank))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ use roaring::RoaringBitmap;
|
|||||||
|
|
||||||
use super::logger::SearchLogger;
|
use super::logger::SearchLogger;
|
||||||
use super::{QueryGraph, SearchContext};
|
use super::{QueryGraph, SearchContext};
|
||||||
|
use crate::score_details::ScoreDetails;
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
/// An internal trait implemented by only [`PlaceholderQuery`] and [`QueryGraph`]
|
/// An internal trait implemented by only [`PlaceholderQuery`] and [`QueryGraph`]
|
||||||
@ -66,4 +67,6 @@ pub struct RankingRuleOutput<Q> {
|
|||||||
pub query: Q,
|
pub query: Q,
|
||||||
/// The allowed candidates for the child ranking rule
|
/// The allowed candidates for the child ranking rule
|
||||||
pub candidates: RoaringBitmap,
|
pub candidates: RoaringBitmap,
|
||||||
|
/// The score for the candidates of the current bucket
|
||||||
|
pub score: ScoreDetails,
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
use heed::BytesDecode;
|
||||||
use roaring::RoaringBitmap;
|
use roaring::RoaringBitmap;
|
||||||
|
|
||||||
use super::logger::SearchLogger;
|
use super::logger::SearchLogger;
|
||||||
use super::{RankingRule, RankingRuleOutput, RankingRuleQueryTrait, SearchContext};
|
use super::{RankingRule, RankingRuleOutput, RankingRuleQueryTrait, SearchContext};
|
||||||
use crate::heed_codec::facet::FacetGroupKeyCodec;
|
use crate::heed_codec::facet::{FacetGroupKeyCodec, OrderedF64Codec};
|
||||||
use crate::heed_codec::ByteSliceRefCodec;
|
use crate::heed_codec::{ByteSliceRefCodec, StrRefCodec};
|
||||||
|
use crate::score_details::{self, ScoreDetails};
|
||||||
use crate::search::facet::{ascending_facet_sort, descending_facet_sort};
|
use crate::search::facet::{ascending_facet_sort, descending_facet_sort};
|
||||||
use crate::{FieldId, Index, Result};
|
use crate::{FieldId, Index, Result};
|
||||||
|
|
||||||
@ -49,6 +51,7 @@ pub struct Sort<'ctx, Query> {
|
|||||||
is_ascending: bool,
|
is_ascending: bool,
|
||||||
original_query: Option<Query>,
|
original_query: Option<Query>,
|
||||||
iter: Option<RankingRuleOutputIterWrapper<'ctx, Query>>,
|
iter: Option<RankingRuleOutputIterWrapper<'ctx, Query>>,
|
||||||
|
must_redact: bool,
|
||||||
}
|
}
|
||||||
impl<'ctx, Query> Sort<'ctx, Query> {
|
impl<'ctx, Query> Sort<'ctx, Query> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
@ -59,15 +62,30 @@ impl<'ctx, Query> Sort<'ctx, Query> {
|
|||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let fields_ids_map = index.fields_ids_map(rtxn)?;
|
let fields_ids_map = index.fields_ids_map(rtxn)?;
|
||||||
let field_id = fields_ids_map.id(&field_name);
|
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> {
|
impl<'ctx, Query: RankingRuleQueryTrait> RankingRule<'ctx, Query> for Sort<'ctx, Query> {
|
||||||
fn id(&self) -> String {
|
fn id(&self) -> String {
|
||||||
let Self { field_name, is_ascending, .. } = self;
|
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(
|
fn start_iteration(
|
||||||
&mut self,
|
&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))
|
(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 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(
|
RankingRuleOutputIterWrapper::new(Box::new(number_iter.chain(string_iter).map(
|
||||||
move |r| {
|
move |r| {
|
||||||
let (docids, _) = r?;
|
let (docids, value) = r?;
|
||||||
Ok(RankingRuleOutput { query: query_graph.clone(), candidates: docids })
|
Ok(RankingRuleOutput {
|
||||||
|
query: query_graph.clone(),
|
||||||
|
candidates: docids,
|
||||||
|
score: ScoreDetails::Sort(score_details::Sort {
|
||||||
|
field_name: field_name.clone(),
|
||||||
|
ascending,
|
||||||
|
redacted: must_redact,
|
||||||
|
value,
|
||||||
|
}),
|
||||||
|
})
|
||||||
},
|
},
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
@ -146,7 +197,16 @@ impl<'ctx, Query: RankingRuleQueryTrait> RankingRule<'ctx, Query> for Sort<'ctx,
|
|||||||
Ok(Some(bucket))
|
Ok(Some(bucket))
|
||||||
} else {
|
} else {
|
||||||
let query = self.original_query.as_ref().unwrap().clone();
|
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,
|
||||||
|
}),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,8 +122,11 @@ fn test_attribute_fid_simple() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
s.query("the quick brown fox jumps over the lazy dog");
|
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);
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[2, 6, 5, 4, 3, 9, 7, 8, 11, 10, 12, 13, 14, 0]");
|
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]
|
#[test]
|
||||||
@ -135,6 +138,11 @@ fn test_attribute_fid_ngrams() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
s.query("the quick brown fox jumps over the lazy dog");
|
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);
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[2, 6, 5, 4, 3, 9, 7, 8, 11, 10, 12, 13, 14, 0]");
|
|
||||||
|
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:#?}"));
|
||||||
}
|
}
|
||||||
|
@ -137,8 +137,13 @@ fn test_attribute_position_simple() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
s.query("quick brown");
|
s.query("quick brown");
|
||||||
let SearchResult { documents_ids, .. } = s.execute().unwrap();
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[10, 11, 12, 13, 2, 3, 4, 1, 0, 6, 8, 7, 9, 5]");
|
|
||||||
|
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]
|
#[test]
|
||||||
fn test_attribute_position_repeated() {
|
fn test_attribute_position_repeated() {
|
||||||
@ -149,8 +154,13 @@ fn test_attribute_position_repeated() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
s.query("a a a a a");
|
s.query("a a a a a");
|
||||||
let SearchResult { documents_ids, .. } = s.execute().unwrap();
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[5, 7, 8, 9, 6]");
|
|
||||||
|
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]
|
#[test]
|
||||||
@ -162,8 +172,13 @@ fn test_attribute_position_different_fields() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
s.query("quick brown");
|
s.query("quick brown");
|
||||||
let SearchResult { documents_ids, .. } = s.execute().unwrap();
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[10, 11, 12, 13, 2, 3, 4, 1, 0, 6, 8, 7, 9, 5]");
|
|
||||||
|
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]
|
#[test]
|
||||||
@ -175,6 +190,11 @@ fn test_attribute_position_ngrams() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
s.query("quick brown");
|
s.query("quick brown");
|
||||||
let SearchResult { documents_ids, .. } = s.execute().unwrap();
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[10, 11, 12, 13, 2, 3, 4, 1, 0, 6, 8, 7, 9, 5]");
|
|
||||||
|
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:#?}"));
|
||||||
}
|
}
|
||||||
|
@ -474,8 +474,14 @@ fn test_exactness_simple_ordered() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
||||||
s.query("the quick brown fox jumps over the lazy dog");
|
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);
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 8, 7, 6, 5, 4, 3, 2, 1]");
|
|
||||||
|
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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
[
|
[
|
||||||
@ -501,8 +507,14 @@ fn test_exactness_simple_reversed() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
||||||
s.query("the quick brown fox jumps over the lazy dog");
|
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);
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 8, 3, 4, 5, 6, 7]");
|
|
||||||
|
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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
[
|
[
|
||||||
@ -519,8 +531,14 @@ fn test_exactness_simple_reversed() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
||||||
s.query("the quick brown fox jumps over the lazy dog");
|
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);
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 8, 3, 4, 5, 6, 7]");
|
|
||||||
|
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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
[
|
[
|
||||||
@ -544,8 +562,14 @@ fn test_exactness_simple_random() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
||||||
s.query("the quick brown fox jumps over the lazy dog");
|
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);
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[8, 7, 4, 6, 3, 5]");
|
|
||||||
|
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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
[
|
[
|
||||||
@ -568,8 +592,14 @@ fn test_exactness_attribute_starts_with_simple() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
||||||
s.query("this balcony");
|
s.query("this balcony");
|
||||||
let SearchResult { documents_ids, .. } = s.execute().unwrap();
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[2, 1, 0]");
|
|
||||||
|
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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
[
|
[
|
||||||
@ -589,8 +619,14 @@ fn test_exactness_attribute_starts_with_phrase() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
||||||
s.query("\"overlooking the sea\" is a beautiful balcony");
|
s.query("\"overlooking the sea\" is a beautiful balcony");
|
||||||
let SearchResult { documents_ids, .. } = s.execute().unwrap();
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[6, 5, 4, 1]");
|
|
||||||
|
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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
[
|
[
|
||||||
@ -604,8 +640,14 @@ fn test_exactness_attribute_starts_with_phrase() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
||||||
s.query("overlooking the sea is a beautiful balcony");
|
s.query("overlooking the sea is a beautiful balcony");
|
||||||
let SearchResult { documents_ids, .. } = s.execute().unwrap();
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[6, 5, 4, 3, 1, 7]");
|
|
||||||
|
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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
[
|
[
|
||||||
@ -628,8 +670,14 @@ fn test_exactness_all_candidates_with_typo() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
||||||
s.query("overlocking the sea is a beautiful balcony");
|
s.query("overlocking the sea is a beautiful balcony");
|
||||||
let SearchResult { documents_ids, .. } = s.execute().unwrap();
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[4, 5, 6, 1, 7]");
|
|
||||||
|
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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
// "overlooking" is returned here because the term matching strategy allows it
|
// "overlooking" is returned here because the term matching strategy allows it
|
||||||
// but it has the worst exactness score (0 exact words)
|
// 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);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
||||||
s.query("the quick brown fox jumps over the lazy dog");
|
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);
|
||||||
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 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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
|
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
@ -702,7 +756,13 @@ fn test_words_after_exactness() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
||||||
s.query("the quick brown fox jumps over the lazy dog");
|
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]");
|
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);
|
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);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
||||||
s.query("the quick brown fox jumps over the lazy dog");
|
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]");
|
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);
|
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);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
||||||
s.query("the quick brown fox jumps over the lazy dog");
|
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]");
|
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[0, 1, 2]");
|
||||||
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
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);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
||||||
s.query("quick brown fox extra");
|
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]");
|
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[2, 1, 0, 4, 3]");
|
||||||
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
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);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
s.terms_matching_strategy(TermsMatchingStrategy::Last);
|
||||||
s.query("extraordinarily quick brown fox");
|
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]");
|
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[1, 0, 4, 3]");
|
||||||
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ use heed::RoTxn;
|
|||||||
use maplit::hashset;
|
use maplit::hashset;
|
||||||
|
|
||||||
use crate::index::tests::TempIndex;
|
use crate::index::tests::TempIndex;
|
||||||
|
use crate::score_details::ScoreDetails;
|
||||||
use crate::search::new::tests::collect_field_values;
|
use crate::search::new::tests::collect_field_values;
|
||||||
use crate::{AscDesc, Criterion, GeoSortStrategy, Member, Search, SearchResult};
|
use crate::{AscDesc, Criterion, GeoSortStrategy, Member, Search, SearchResult};
|
||||||
|
|
||||||
@ -28,30 +29,37 @@ fn execute_iterative_and_rtree_returns_the_same<'a>(
|
|||||||
rtxn: &RoTxn<'a>,
|
rtxn: &RoTxn<'a>,
|
||||||
index: &TempIndex,
|
index: &TempIndex,
|
||||||
search: &mut Search<'a>,
|
search: &mut Search<'a>,
|
||||||
) -> Vec<usize> {
|
) -> (Vec<usize>, Vec<Vec<ScoreDetails>>) {
|
||||||
search.geo_sort_strategy(GeoSortStrategy::AlwaysIterative(2));
|
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);
|
let iterative_ids_bucketed = collect_field_values(index, rtxn, "id", &documents_ids);
|
||||||
|
|
||||||
search.geo_sort_strategy(GeoSortStrategy::AlwaysIterative(1000));
|
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);
|
let iterative_ids = collect_field_values(index, rtxn, "id", &documents_ids);
|
||||||
|
|
||||||
assert_eq!(iterative_ids_bucketed, iterative_ids, "iterative bucket");
|
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));
|
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);
|
let rtree_ids_bucketed = collect_field_values(index, rtxn, "id", &documents_ids);
|
||||||
|
|
||||||
search.geo_sort_strategy(GeoSortStrategy::AlwaysRtree(1000));
|
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);
|
let rtree_ids = collect_field_values(index, rtxn, "id", &documents_ids);
|
||||||
|
|
||||||
assert_eq!(rtree_ids_bucketed, rtree_ids, "rtree bucket");
|
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_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]
|
#[test]
|
||||||
@ -73,14 +81,17 @@ fn test_geo_sort() {
|
|||||||
let rtxn = index.read_txn().unwrap();
|
let rtxn = index.read_txn().unwrap();
|
||||||
|
|
||||||
let mut s = Search::new(&rtxn, &index);
|
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.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!("{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.]))]);
|
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!("{ids:?}"), @"[5, 4, 3, 2, 1, 0, 6, 8, 7, 10, 9]");
|
||||||
|
insta::assert_snapshot!(format!("{scores:#?}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -101,52 +112,63 @@ fn test_geo_sort_around_the_edge_of_the_flat_earth() {
|
|||||||
let rtxn = index.read_txn().unwrap();
|
let rtxn = index.read_txn().unwrap();
|
||||||
|
|
||||||
let mut s = Search::new(&rtxn, &index);
|
let mut s = Search::new(&rtxn, &index);
|
||||||
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
|
|
||||||
// --- asc
|
// --- asc
|
||||||
s.sort_criteria(vec![AscDesc::Asc(Member::Geo([0., 0.]))]);
|
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!("{ids:?}"), @"[0, 1, 2, 3, 4]");
|
||||||
|
insta::assert_snapshot!(format!("{scores:#?}"));
|
||||||
|
|
||||||
// ensuring the lat doesn't wrap around
|
// ensuring the lat doesn't wrap around
|
||||||
s.sort_criteria(vec![AscDesc::Asc(Member::Geo([85., 0.]))]);
|
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!("{ids:?}"), @"[1, 0, 3, 4, 2]");
|
||||||
|
insta::assert_snapshot!(format!("{scores:#?}"));
|
||||||
|
|
||||||
s.sort_criteria(vec![AscDesc::Asc(Member::Geo([-85., 0.]))]);
|
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!("{ids:?}"), @"[2, 0, 3, 4, 1]");
|
||||||
|
insta::assert_snapshot!(format!("{scores:#?}"));
|
||||||
|
|
||||||
// ensuring the lng does wrap around
|
// ensuring the lng does wrap around
|
||||||
s.sort_criteria(vec![AscDesc::Asc(Member::Geo([0., 175.]))]);
|
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!("{ids:?}"), @"[3, 4, 2, 1, 0]");
|
||||||
|
insta::assert_snapshot!(format!("{scores:#?}"));
|
||||||
|
|
||||||
s.sort_criteria(vec![AscDesc::Asc(Member::Geo([0., -175.]))]);
|
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!("{ids:?}"), @"[4, 3, 2, 1, 0]");
|
||||||
|
insta::assert_snapshot!(format!("{scores:#?}"));
|
||||||
|
|
||||||
// --- desc
|
// --- desc
|
||||||
s.sort_criteria(vec![AscDesc::Desc(Member::Geo([0., 0.]))]);
|
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!("{ids:?}"), @"[4, 3, 2, 1, 0]");
|
||||||
|
insta::assert_snapshot!(format!("{scores:#?}"));
|
||||||
|
|
||||||
// ensuring the lat doesn't wrap around
|
// ensuring the lat doesn't wrap around
|
||||||
s.sort_criteria(vec![AscDesc::Desc(Member::Geo([85., 0.]))]);
|
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!("{ids:?}"), @"[2, 4, 3, 0, 1]");
|
||||||
|
insta::assert_snapshot!(format!("{scores:#?}"));
|
||||||
|
|
||||||
s.sort_criteria(vec![AscDesc::Desc(Member::Geo([-85., 0.]))]);
|
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!("{ids:?}"), @"[1, 4, 3, 0, 2]");
|
||||||
|
insta::assert_snapshot!(format!("{scores:#?}"));
|
||||||
|
|
||||||
// ensuring the lng does wrap around
|
// ensuring the lng does wrap around
|
||||||
s.sort_criteria(vec![AscDesc::Desc(Member::Geo([0., 175.]))]);
|
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!("{ids:?}"), @"[0, 1, 2, 4, 3]");
|
||||||
|
insta::assert_snapshot!(format!("{scores:#?}"));
|
||||||
|
|
||||||
s.sort_criteria(vec![AscDesc::Desc(Member::Geo([0., -175.]))]);
|
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!("{ids:?}"), @"[0, 1, 2, 3, 4]");
|
||||||
|
insta::assert_snapshot!(format!("{scores:#?}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -166,19 +188,98 @@ fn geo_sort_mixed_with_words() {
|
|||||||
let rtxn = index.read_txn().unwrap();
|
let rtxn = index.read_txn().unwrap();
|
||||||
|
|
||||||
let mut s = Search::new(&rtxn, &index);
|
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.sort_criteria(vec![AscDesc::Asc(Member::Geo([0., 0.]))]);
|
||||||
|
|
||||||
s.query("jean");
|
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!("{ids:?}"), @"[0, 2, 3]");
|
||||||
|
insta::assert_snapshot!(format!("{scores:#?}"));
|
||||||
|
|
||||||
s.query("bob");
|
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!("{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");
|
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!("{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]
|
#[test]
|
||||||
@ -198,9 +299,11 @@ fn geo_sort_without_any_geo_faceted_documents() {
|
|||||||
let rtxn = index.read_txn().unwrap();
|
let rtxn = index.read_txn().unwrap();
|
||||||
|
|
||||||
let mut s = Search::new(&rtxn, &index);
|
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.sort_criteria(vec![AscDesc::Asc(Member::Geo([0., 0.]))]);
|
||||||
|
|
||||||
s.query("jean");
|
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!("{ids:?}"), @"[0, 2, 3]");
|
||||||
|
insta::assert_snapshot!(format!("{scores:#?}"));
|
||||||
}
|
}
|
||||||
|
@ -80,10 +80,13 @@ fn test_2gram_simple() {
|
|||||||
|
|
||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
s.query("sun flower");
|
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
|
// will also match documents with "sunflower" + prefix tolerance
|
||||||
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[0, 1, 2, 3, 5]");
|
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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
[
|
[
|
||||||
|
@ -124,6 +124,8 @@ fn create_edge_cases_index() -> TempIndex {
|
|||||||
},
|
},
|
||||||
// The next 5 documents lay out a trap with the split word, phrase search, or synonym `sun flower`.
|
// 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 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
|
// If the query is `sunflower wilting`, then we should make sure that
|
||||||
// the proximity condition `flower wilting: sprx N` also comes with the condition
|
// the proximity condition `flower wilting: sprx N` also comes with the condition
|
||||||
// `sun wilting: sprx N+1`, but this is not the exact condition we use for now.
|
// `sun wilting: sprx N+1`, but this is not the exact condition we use for now.
|
||||||
@ -140,6 +142,7 @@ fn create_edge_cases_index() -> TempIndex {
|
|||||||
{
|
{
|
||||||
"id": 3,
|
"id": 3,
|
||||||
// This document matches the query `sunflower wilting`, but the sprximity condition
|
// 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`
|
// between `sunflower` and `wilting` cannot be through the split-word `Sun Flower`
|
||||||
// which would reduce to only `flower` and `wilting` being in sprximity.
|
// which would reduce to only `flower` and `wilting` being in sprximity.
|
||||||
"text": "A flower wilting under the sun, unlike a sunflower"
|
"text": "A flower wilting under the sun, unlike a sunflower"
|
||||||
@ -270,13 +273,13 @@ fn test_proximity_simple() {
|
|||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
s.query("the quick brown fox jumps over the lazy dog");
|
s.query("the quick brown fox jumps over the lazy dog");
|
||||||
let SearchResult { documents_ids, .. } = s.execute().unwrap();
|
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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
[
|
[
|
||||||
"\"the quickbrown fox jumps over the lazy dog\"",
|
|
||||||
"\"the quack brown 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 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 lazy dog\"",
|
||||||
"\"the really quick brown fox jumps over the very lazy dog\"",
|
"\"the really quick brown fox jumps over the very lazy dog\"",
|
||||||
"\"brown quick fox jumps over the lazy dog\"",
|
"\"brown quick fox jumps over the lazy dog\"",
|
||||||
@ -295,9 +298,12 @@ fn test_proximity_split_word() {
|
|||||||
|
|
||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
s.query("sunflower wilting");
|
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!("{documents_ids:?}"), @"[2, 4, 5, 1, 3]");
|
||||||
|
insta::assert_snapshot!(format!("{document_scores:#?}"));
|
||||||
|
|
||||||
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
// "2" and "4" should be swapped ideally
|
// "2" and "4" should be swapped ideally
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
@ -312,9 +318,11 @@ fn test_proximity_split_word() {
|
|||||||
|
|
||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
s.query("\"sun flower\" wilting");
|
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!("{documents_ids:?}"), @"[2, 4, 1]");
|
||||||
|
insta::assert_snapshot!(format!("{document_scores:#?}"));
|
||||||
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
// "2" and "4" should be swapped ideally
|
// "2" and "4" should be swapped ideally
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
@ -337,9 +345,11 @@ fn test_proximity_split_word() {
|
|||||||
|
|
||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
s.query("xyz wilting");
|
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!("{documents_ids:?}"), @"[2, 4, 1]");
|
||||||
|
insta::assert_snapshot!(format!("{document_scores:#?}"));
|
||||||
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
// "2" and "4" should be swapped ideally
|
// "2" and "4" should be swapped ideally
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
@ -358,9 +368,11 @@ fn test_proximity_prefix_db() {
|
|||||||
|
|
||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
s.query("best s");
|
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!("{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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
|
|
||||||
// This test illustrates the loss of precision from using the prefix DB
|
// This test illustrates the loss of precision from using the prefix DB
|
||||||
@ -381,9 +393,11 @@ fn test_proximity_prefix_db() {
|
|||||||
// Difference when using the `su` prefix, which is not in the prefix DB
|
// Difference when using the `su` prefix, which is not in the prefix DB
|
||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
s.query("best su");
|
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!("{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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
|
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
@ -406,9 +420,11 @@ fn test_proximity_prefix_db() {
|
|||||||
|
|
||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
s.query("best win");
|
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!("{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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
|
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
@ -428,9 +444,11 @@ fn test_proximity_prefix_db() {
|
|||||||
|
|
||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
s.query("best wint");
|
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!("{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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
|
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
@ -450,9 +468,11 @@ fn test_proximity_prefix_db() {
|
|||||||
|
|
||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
|
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
|
||||||
s.query("best wi");
|
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!("{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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
|
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
|
@ -60,8 +60,41 @@ fn test_trap_basic() {
|
|||||||
let mut s = Search::new(&txn, &index);
|
let mut s = Search::new(&txn, &index);
|
||||||
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
s.terms_matching_strategy(TermsMatchingStrategy::All);
|
||||||
s.query("summer holiday");
|
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!("{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);
|
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
|
||||||
// This is incorrect, 1 should come before 0
|
// This is incorrect, 1 should come before 0
|
||||||
insta::assert_debug_snapshot!(texts, @r###"
|
insta::assert_debug_snapshot!(texts, @r###"
|
||||||
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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"),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
source: milli/src/search/new/tests/stop_words.rs
|
||||||
|
expression: "format!(\"{document_scores:#?}\")"
|
||||||
|
---
|
||||||
|
[
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
]
|
@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
source: milli/src/search/new/tests/typo.rs
|
||||||
|
expression: "format!(\"{document_scores:#?}\")"
|
||||||
|
---
|
||||||
|
[
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
source: milli/src/search/new/tests/typo.rs
|
||||||
|
expression: "format!(\"{document_scores:#?}\")"
|
||||||
|
---
|
||||||
|
[
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
]
|
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
source: milli/src/search/new/tests/typo.rs
|
||||||
|
expression: "format!(\"{document_scores:#?}\")"
|
||||||
|
---
|
||||||
|
[
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user