Compare commits

..

22 Commits

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

# Pull Request

## Related issue

No issue, maintenance

## What does this PR do?
- Remove trailing whitespace in snapshots by adding a trailing `|` at the end of lines that would previously end with fixed-width integers
- This allows contributors whose editor is configured to remove trailing whitespace not to modify the tests when changing an unrelated part of the file containing the tests


Co-authored-by: Louis Dureuil <louis@meilisearch.com>
2023-06-14 13:00:52 +00:00
Louis Dureuil
e0c4682758 Fix tests 2023-06-14 13:30:52 +02:00
Louis Dureuil
d9b4b39922 Add trailing pipe to the snapshots so it doesn't end with trailing whitespace 2023-06-14 13:30:52 +02:00
meili-bors[bot]
4829348d6e Merge #3813
3813: Fix SDK CI for scheduled jobs r=curquiza a=curquiza

The SDK CI does not run for the scheduled job (`cron`) every day, and only works for manual triggers.

I added a job to define the Docker image we use depending on the event: `worflow_dispatch` = manual triggering, or `scheduled` = cron jobs

Co-authored-by: curquiza <clementine@meilisearch.com>
2023-06-12 08:41:03 +00:00
curquiza
b6b6a80b76 Fix SDK CI for scheduled jobs 2023-06-06 10:38:05 +02:00
103 changed files with 9893 additions and 715 deletions

View File

@@ -16,8 +16,23 @@ env:
MEILI_NO_ANALYTICS: 'true'
jobs:
define-docker-image:
runs-on: ubuntu-latest
outputs:
docker-image: ${{ steps.define-image.outputs.docker-image }}
steps:
- uses: actions/checkout@v3
- name: Define the Docker image we need to use
id: define-image
run: |
event=${{ github.event.action }}
echo "docker-image=nightly" >> $GITHUB_OUTPUT
if [[ $event == 'workflow_dispatch' ]]; then
echo "docker-image=${{ github.event.inputs.docker_image }}" >> $GITHUB_OUTPUT
fi
meilisearch-js-tests:
needs: define-docker-image
name: JS SDK tests
runs-on: ubuntu-latest
services:
@@ -52,6 +67,7 @@ jobs:
run: yarn test:env:browser
instant-meilisearch-tests:
needs: define-docker-image
name: instant-meilisearch tests
runs-on: ubuntu-latest
services:
@@ -78,6 +94,7 @@ jobs:
run: yarn build
meilisearch-php-tests:
needs: define-docker-image
name: PHP SDK tests
runs-on: ubuntu-latest
services:
@@ -108,6 +125,7 @@ jobs:
composer remove --dev guzzlehttp/guzzle http-interop/http-factory-guzzle
meilisearch-python-tests:
needs: define-docker-image
name: Python SDK tests
runs-on: ubuntu-latest
services:
@@ -132,6 +150,7 @@ jobs:
run: pipenv run pytest
meilisearch-go-tests:
needs: define-docker-image
name: Go SDK tests
runs-on: ubuntu-latest
services:
@@ -161,6 +180,7 @@ jobs:
run: go test -v ./...
meilisearch-ruby-tests:
needs: define-docker-image
name: Ruby SDK tests
runs-on: ubuntu-latest
services:
@@ -185,6 +205,7 @@ jobs:
run: bundle exec rspec
meilisearch-rust-tests:
needs: define-docker-image
name: Rust SDK tests
runs-on: ubuntu-latest
services:

View File

@@ -236,7 +236,6 @@ InvalidSearchHighlightPreTag , InvalidRequest , BAD_REQUEST ;
InvalidSearchHitsPerPage , InvalidRequest , BAD_REQUEST ;
InvalidSearchLimit , InvalidRequest , BAD_REQUEST ;
InvalidSearchMatchingStrategy , InvalidRequest , BAD_REQUEST ;
InvalidMultiSearchMergeStrategy , InvalidRequest , BAD_REQUEST ;
InvalidSearchOffset , InvalidRequest , BAD_REQUEST ;
InvalidSearchPage , InvalidRequest , BAD_REQUEST ;
InvalidSearchQ , InvalidRequest , BAD_REQUEST ;

View File

@@ -1,26 +1,20 @@
use std::collections::HashMap;
use actix_http::StatusCode;
use actix_web::web::{self, Data};
use actix_web::{HttpRequest, HttpResponse};
use deserr::actix_web::AwebJson;
use deserr::Deserr;
use index_scheduler::IndexScheduler;
use log::debug;
use meilisearch_types::deserr::DeserrJsonError;
use meilisearch_types::error::deserr_codes::InvalidMultiSearchMergeStrategy;
use meilisearch_types::error::ResponseError;
use meilisearch_types::keys::actions;
use meilisearch_types::milli::score_details::NotComparable;
use serde::Serialize;
use crate::analytics::{Analytics, MultiSearchAggregator};
use crate::extractors::authentication::policies::ActionPolicy;
use crate::extractors::authentication::{AuthenticationError, GuardedData};
use crate::extractors::sequential_extractor::SeqHandler;
use crate::milli::score_details::ScoreDetails;
use crate::search::{
add_search_rules, perform_search, SearchHit, SearchQueryWithIndex, SearchResultWithIndex,
add_search_rules, perform_search, SearchQueryWithIndex, SearchResultWithIndex,
};
pub fn configure(cfg: &mut web::ServiceConfig) {
@@ -29,34 +23,13 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
#[derive(Serialize)]
struct SearchResults {
#[serde(skip_serializing_if = "Option::is_none")]
aggregate_hits: Option<Vec<SearchHitWithIndex>>,
results: Vec<SearchResultWithIndex>,
}
#[derive(Serialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
struct SearchHitWithIndex {
pub index_uid: String,
#[serde(flatten)]
pub hit: SearchHit,
}
#[derive(Debug, deserr::Deserr)]
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)]
pub struct SearchQueries {
queries: Vec<SearchQueryWithIndex>,
#[deserr(default, error = DeserrJsonError<InvalidMultiSearchMergeStrategy>, default)]
merge_strategy: MergeStrategy,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserr, Default)]
#[deserr(rename_all = camelCase)]
pub enum MergeStrategy {
#[default]
None,
ByNormalizedScore,
ByScoreDetails,
}
pub async fn multi_search_with_post(
@@ -65,13 +38,7 @@ pub async fn multi_search_with_post(
req: HttpRequest,
analytics: web::Data<dyn Analytics>,
) -> Result<HttpResponse, ResponseError> {
let SearchQueries { queries, merge_strategy } = params.into_inner();
// FIXME: REMOVE UNWRAP
let max_hits = queries
.iter()
.map(|SearchQueryWithIndex { limit, hits_per_page, .. }| hits_per_page.unwrap_or(*limit))
.max()
.unwrap();
let queries = params.into_inner().queries;
let mut multi_aggregate = MultiSearchAggregator::from_queries(&queries, &req);
@@ -137,117 +104,7 @@ pub async fn multi_search_with_post(
debug!("returns: {:?}", search_results);
let aggregate_hits = match merge_strategy {
MergeStrategy::None => None,
MergeStrategy::ByScoreDetails => Some(merge_by_score_details(&search_results, max_hits)),
MergeStrategy::ByNormalizedScore => {
Some(merge_by_normalized_score(&search_results, max_hits))
}
};
Ok(HttpResponse::Ok().json(SearchResults { aggregate_hits, results: search_results }))
}
fn merge_by_score_details(
search_results: &[SearchResultWithIndex],
max_hits: usize,
) -> Vec<SearchHitWithIndex> {
let mut iterators: Vec<_> = search_results
.iter()
.filter_map(|SearchResultWithIndex { index_uid, result }| {
let mut it = result.hits.iter();
let next = it.next()?;
Some((index_uid, it, next))
})
.collect();
let mut hits = Vec::with_capacity(max_hits);
let mut inconsistent_indexes = HashMap::new();
for _ in 0..max_hits {
iterators.sort_by(|(left_uid, _, left_hit), (right_uid, _, right_hit)| {
let error = match ScoreDetails::partial_cmp_iter(
left_hit.ranking_score_raw.iter(),
right_hit.ranking_score_raw.iter(),
) {
Ok(ord) => return ord,
Err(NotComparable(incomparable_index)) => incomparable_index,
};
inconsistent_indexes.entry((left_uid.to_owned(), right_uid.to_owned())).or_insert_with(
|| {
format!(
"Detailed score {:?} is not comparable with {:?}: (left: {:#?}, right: {:#?})",
left_hit.ranking_score_raw.get(error),
right_hit.ranking_score_raw.get(error),
left_hit.ranking_score_raw,
right_hit.ranking_score_raw
)
},
);
std::cmp::Ordering::Less
});
if !inconsistent_indexes.is_empty() {
let mut s = String::new();
for ((left_uid, right_uid), error) in &inconsistent_indexes {
use std::fmt::Write;
writeln!(s, "Indexes {} and {} are inconsistent: {}", left_uid, right_uid, error)
.unwrap();
}
// Replace panic with proper error
panic!("{}", s);
}
let Some((index_uid, it, next)) = iterators.last_mut()
else {
break;
};
let hit = SearchHitWithIndex { index_uid: index_uid.clone(), hit: next.clone() };
if let Some(next_hit) = it.next() {
*next = next_hit;
} else {
iterators.pop();
}
hits.push(hit);
}
hits
}
fn merge_by_normalized_score(
search_results: &[SearchResultWithIndex],
max_hits: usize,
) -> Vec<SearchHitWithIndex> {
let mut iterators: Vec<_> = search_results
.iter()
.filter_map(|SearchResultWithIndex { index_uid, result }| {
let mut it = result.hits.iter();
let next = it.next()?;
Some((index_uid, it, next))
})
.collect();
let mut hits = Vec::with_capacity(max_hits);
for _ in 0..max_hits {
iterators.sort_by_key(|(_, _, hit)| {
ScoreDetails::global_score_linear_scale(hit.ranking_score_raw.iter())
});
let Some((index_uid, it, next)) = iterators.last_mut()
else {
break;
};
let hit = SearchHitWithIndex { index_uid: index_uid.clone(), hit: next.clone() };
if let Some(next_hit) = it.next() {
*next = next_hit;
} else {
iterators.pop();
}
hits.push(hit);
}
hits
Ok(HttpResponse::Ok().json(SearchResults { results: search_results }))
}
/// Local `Result` extension trait to avoid `map_err` boilerplate.

View File

@@ -9,7 +9,7 @@ use meilisearch_auth::IndexSearchRules;
use meilisearch_types::deserr::DeserrJsonError;
use meilisearch_types::error::deserr_codes::*;
use meilisearch_types::index_uid::IndexUid;
use meilisearch_types::milli::score_details::ScoreDetails;
use meilisearch_types::milli::score_details::{ScoreDetails, ScoringStrategy};
use meilisearch_types::settings::DEFAULT_PAGINATION_MAX_TOTAL_HITS;
use meilisearch_types::{milli, Document};
use milli::tokenizer::TokenizerBuilder;
@@ -216,11 +216,9 @@ pub struct SearchHit {
#[serde(rename = "_matchesPosition", skip_serializing_if = "Option::is_none")]
pub matches_position: Option<MatchesPosition>,
#[serde(rename = "_rankingScore", skip_serializing_if = "Option::is_none")]
pub ranking_score: Option<u64>,
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>>,
#[serde(skip)]
pub ranking_score_raw: Vec<ScoreDetails>,
}
#[derive(Serialize, Debug, Clone, PartialEq)]
@@ -302,6 +300,11 @@ pub fn perform_search(
.unwrap_or(DEFAULT_PAGINATION_MAX_TOTAL_HITS);
search.exhaustive_number_hits(is_finite_pagination);
search.scoring_strategy(if query.show_ranking_score || query.show_ranking_score_details {
ScoringStrategy::Detailed
} else {
ScoringStrategy::Skip
});
// compute the offset on the limit depending on the pagination mode.
let (offset, limit) = if is_finite_pagination {
@@ -437,7 +440,7 @@ pub fn perform_search(
}
let ranking_score =
query.show_ranking_score.then(|| ScoreDetails::global_score_linear_scale(score.iter()));
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()));
@@ -447,7 +450,6 @@ pub fn perform_search(
matches_position,
ranking_score_details,
ranking_score,
ranking_score_raw: score,
};
documents.push(hit);
}

View File

@@ -35,8 +35,7 @@ async fn formatted_contain_wildcard() {
"length": 5
}
]
},
"_rankingScore": "[score]"
}
}
"###);
}
@@ -53,8 +52,7 @@ async fn formatted_contain_wildcard() {
@r###"
{
"id": 852,
"cattos": "pésti",
"_rankingScore": "[score]"
"cattos": "pésti"
}
"###)
}
@@ -84,8 +82,7 @@ async fn formatted_contain_wildcard() {
"length": 5
}
]
},
"_rankingScore": "[score]"
}
}
"###)
}
@@ -107,8 +104,7 @@ async fn formatted_contain_wildcard() {
"_formatted": {
"id": "852",
"cattos": "pésti"
},
"_rankingScore": "[score]"
}
}
"###);
}
@@ -129,8 +125,7 @@ async fn formatted_contain_wildcard() {
"_formatted": {
"id": "852",
"cattos": "pésti"
},
"_rankingScore": "[score]"
}
}
"###)
}
@@ -164,8 +159,7 @@ async fn format_nested() {
"name": "buddy",
"age": 4
}
],
"_rankingScore": "[score]"
]
}
"###)
}
@@ -189,8 +183,7 @@ async fn format_nested() {
{
"name": "buddy"
}
],
"_rankingScore": "[score]"
]
}
"###)
}
@@ -223,8 +216,7 @@ async fn format_nested() {
"length": 5
}
]
},
"_rankingScore": "[score]"
}
}
"###)
}
@@ -250,8 +242,7 @@ async fn format_nested() {
"name": "buddy"
}
]
},
"_rankingScore": "[score]"
}
}
"###)
}
@@ -276,8 +267,7 @@ async fn format_nested() {
"name": "buddy"
}
]
},
"_rankingScore": "[score]"
}
}
"###)
}
@@ -312,8 +302,7 @@ async fn format_nested() {
"age": "4"
}
]
},
"_rankingScore": "[score]"
}
}
"###)
}
@@ -340,8 +329,7 @@ async fn format_nested() {
"age": "4"
}
]
},
"_rankingScore": "[score]"
}
}
"###)
}
@@ -371,8 +359,7 @@ async fn displayedattr_2_smol() {
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852,
"_rankingScore": "[score]"
"id": 852
}
"###)
}
@@ -387,8 +374,7 @@ async fn displayedattr_2_smol() {
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852,
"_rankingScore": "[score]"
"id": 852
}
"###)
}
@@ -406,8 +392,7 @@ async fn displayedattr_2_smol() {
"id": 852,
"_formatted": {
"id": "852"
},
"_rankingScore": "[score]"
}
}
"###)
}
@@ -425,8 +410,7 @@ async fn displayedattr_2_smol() {
"id": 852,
"_formatted": {
"id": "852"
},
"_rankingScore": "[score]"
}
}
"###)
}
@@ -446,8 +430,7 @@ async fn displayedattr_2_smol() {
"id": 852,
"_formatted": {
"id": "852"
},
"_rankingScore": "[score]"
}
}
"###)
}
@@ -463,8 +446,7 @@ async fn displayedattr_2_smol() {
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852,
"_rankingScore": "[score]"
"id": 852
}
"###)
}
@@ -479,8 +461,7 @@ async fn displayedattr_2_smol() {
{ "._rankingScore" => "[score]" },
@r###"
{
"id": 852,
"_rankingScore": "[score]"
"id": 852
}
"###)
}
@@ -493,11 +474,7 @@ async fn displayedattr_2_smol() {
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"_rankingScore": "[score]"
}
"###)
@"{}")
}
})
.await;
@@ -510,11 +487,7 @@ async fn displayedattr_2_smol() {
allow_duplicates! {
assert_json_snapshot!(response["hits"][0],
{ "._rankingScore" => "[score]" },
@r###"
{
"_rankingScore": "[score]"
}
"###)
@"{}")
}
}
@@ -533,8 +506,7 @@ async fn displayedattr_2_smol() {
{
"_formatted": {
"id": "852"
},
"_rankingScore": "[score]"
}
}
"###)
}
@@ -554,8 +526,7 @@ async fn displayedattr_2_smol() {
{
"_formatted": {
"id": "852"
},
"_rankingScore": "[score]"
}
}
"###)
}

View File

@@ -72,8 +72,7 @@ async fn simple_search_single_index() {
"hits": [
{
"title": "Gläss",
"id": "450465",
"_rankingScore": "[score]"
"id": "450465"
}
],
"query": "glass",
@@ -87,8 +86,7 @@ async fn simple_search_single_index() {
"hits": [
{
"title": "Captain Marvel",
"id": "299537",
"_rankingScore": "[score]"
"id": "299537"
}
],
"query": "captain",
@@ -179,8 +177,7 @@ async fn simple_search_two_indexes() {
"hits": [
{
"title": "Gläss",
"id": "450465",
"_rankingScore": "[score]"
"id": "450465"
}
],
"query": "glass",
@@ -206,8 +203,7 @@ async fn simple_search_two_indexes() {
"age": 4
}
],
"cattos": "pésti",
"_rankingScore": "[score]"
"cattos": "pésti"
},
{
"id": 654,
@@ -222,8 +218,7 @@ async fn simple_search_two_indexes() {
"cattos": [
"simba",
"pestiféré"
],
"_rankingScore": "[score]"
]
}
],
"query": "pésti",

View File

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

View File

@@ -1466,9 +1466,9 @@ pub(crate) mod tests {
db_snap!(index, field_distribution,
@r###"
age 1
id 2
name 2
age 1 |
id 2 |
name 2 |
"###
);
@@ -1486,9 +1486,9 @@ pub(crate) mod tests {
db_snap!(index, field_distribution,
@r###"
age 1
id 2
name 2
age 1 |
id 2 |
name 2 |
"###
);
@@ -1502,9 +1502,9 @@ pub(crate) mod tests {
db_snap!(index, field_distribution,
@r###"
has_dog 1
id 2
name 2
has_dog 1 |
id 2 |
name 2 |
"###
);
}

View File

@@ -1,5 +1,3 @@
use std::cmp::Ordering;
use serde::Serialize;
use crate::distance_between_two_points;
@@ -17,36 +15,6 @@ pub enum ScoreDetails {
GeoSort(GeoSort),
}
impl PartialOrd for ScoreDetails {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
use ScoreDetails::*;
match (self, other) {
// matching left and right hands => defer to sub impl
(Words(left), Words(right)) => left.partial_cmp(right),
(Typo(left), Typo(right)) => left.partial_cmp(right),
(Proximity(left), Proximity(right)) => left.partial_cmp(right),
(Fid(left), Fid(right)) => left.partial_cmp(right),
(Position(left), Position(right)) => left.partial_cmp(right),
(ExactAttribute(left), ExactAttribute(right)) => left.partial_cmp(right),
(Exactness(left), Exactness(right)) => left.partial_cmp(right),
(Sort(left), Sort(right)) => left.partial_cmp(right),
(GeoSort(left), GeoSort(right)) => left.partial_cmp(right),
// non matching left and right hands => None
// written this way rather than with a single `_` arm, so that adding a new variant
// still results in a compile error
(Words(_), _) => None,
(Typo(_), _) => None,
(Proximity(_), _) => None,
(Fid(_), _) => None,
(Position(_), _) => None,
(ExactAttribute(_), _) => None,
(Exactness(_), _) => None,
(Sort(_), _) => None,
(GeoSort(_), _) => None,
}
}
}
impl ScoreDetails {
pub fn local_score(&self) -> Option<f64> {
self.rank().map(Rank::local_score)
@@ -70,19 +38,15 @@ impl ScoreDetails {
Rank::global_score(details.filter_map(Self::rank))
}
pub fn global_score_linear_scale<'a>(details: impl Iterator<Item = &'a Self>) -> u64 {
(Self::global_score(details) * LINEAR_SCALE_FACTOR).round() as u64
}
/// Panics
///
/// - If Position is not preceded by Fid
/// - If Exactness is not preceded by ExactAttribute
/// - If a sort fid is not contained in the passed `fields_ids_map`.
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 {
@@ -91,7 +55,7 @@ impl ScoreDetails {
"order": order,
"matchingWords": words.matching_words,
"maxMatchingWords": words.max_matching_words,
"score": words.rank().local_score_linear_scale(),
"score": words.rank().local_score(),
});
details_map.insert("words".into(), words_details);
order += 1;
@@ -101,7 +65,7 @@ impl ScoreDetails {
"order": order,
"typoCount": typo.typo_count,
"maxTypoCount": typo.max_typo_count,
"score": typo.rank().local_score_linear_scale(),
"score": typo.rank().local_score(),
});
details_map.insert("typo".into(), typo_details);
order += 1;
@@ -109,16 +73,18 @@ impl ScoreDetails {
ScoreDetails::Proximity(proximity) => {
let proximity_details = serde_json::json!({
"order": order,
"score": proximity.local_score_linear_scale(),
"score": proximity.local_score(),
});
details_map.insert("proximity".into(), proximity_details);
order += 1;
}
ScoreDetails::Fid(fid) => {
// copy the rank for future use in Position.
fid_details = Some(*fid);
// For now, fid is a virtual rule always followed by the "position" rule
let fid_details = serde_json::json!({
"order": order,
"attributes_ranking_order": fid.local_score_linear_scale(),
"attributes_ranking_order": fid.local_score(),
});
details_map.insert("attribute".into(), fid_details);
order += 1;
@@ -131,17 +97,25 @@ impl ScoreDetails {
let attribute_details = attribute_details
.as_object_mut()
.expect("attribute details was not an object");
let Some(fid_details) = fid_details
else {
panic!("position not preceded by attribute");
};
attribute_details.insert(
"attributes_query_word_order".into(),
position.local_score_linear_scale().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,
"exactIn": exact_attribute,
"score": exact_attribute.rank().local_score_linear_scale(),
"matchType": exact_attribute,
"score": exact_attribute.rank().local_score(),
});
details_map.insert("exactness".into(), exactness_details);
order += 1;
@@ -154,10 +128,10 @@ impl ScoreDetails {
let exactness_details = exactness_details
.as_object_mut()
.expect("exactness details was not an object");
if exactness_details.get("exactIn").expect("missing 'exactIn'")
if exactness_details.get("matchType").expect("missing 'matchType'")
== &serde_json::json!(ExactAttribute::NoExactMatch)
{
let score = Rank::global_score_linear_scale(
let score = Rank::global_score(
[ExactAttribute::NoExactMatch.rank(), *details].iter().copied(),
);
*exactness_details.get_mut("score").expect("missing score") = score.into();
@@ -165,14 +139,20 @@ impl ScoreDetails {
// do not update the order since this was already done by exactAttribute
}
ScoreDetails::Sort(details) => {
let sort = format!(
"{}:{}",
details.field_name,
if details.ascending { "asc" } else { "desc" }
);
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": details.value,
"value": value,
});
details_map.insert(sort, sort_details);
order += 1;
@@ -201,57 +181,32 @@ impl ScoreDetails {
}
details_map
}
}
pub fn partial_cmp_iter<'a>(
mut left: impl Iterator<Item = &'a Self>,
mut right: impl Iterator<Item = &'a Self>,
) -> Result<Ordering, NotComparable> {
let mut index = 0;
let mut order = match (left.next(), right.next()) {
(Some(left), Some(right)) => left.partial_cmp(right).incomparable(index)?,
_ => return Ok(Ordering::Equal),
};
for (left, right) in left.zip(right) {
if order != Ordering::Equal {
return Ok(order);
};
index += 1;
order = left.partial_cmp(right).incomparable(index)?;
}
Ok(order)
}
/// 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 NotComparable(pub usize);
trait OptionToNotComparable<T> {
fn incomparable(self, index: usize) -> Result<T, NotComparable>;
}
impl<T> OptionToNotComparable<T> for Option<T> {
fn incomparable(self, index: usize) -> Result<T, NotComparable> {
match self {
Some(t) => Ok(t),
None => Err(NotComparable(index)),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Words {
pub matching_words: u32,
pub max_matching_words: u32,
}
impl PartialOrd for Words {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
(self.max_matching_words == other.max_matching_words)
.then(|| self.matching_words.cmp(&other.matching_words))
}
}
impl Words {
pub fn rank(&self) -> Rank {
Rank { rank: self.matching_words, max_rank: self.max_matching_words }
@@ -262,21 +217,12 @@ impl Words {
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Typo {
pub typo_count: u32,
pub max_typo_count: u32,
}
impl PartialOrd for Typo {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
(self.max_typo_count == other.max_typo_count).then(|| {
// the order is reverted as having fewer typos gives a better score
self.typo_count.cmp(&other.typo_count).reverse()
})
}
}
impl Typo {
pub fn rank(&self) -> Rank {
Rank {
@@ -297,7 +243,7 @@ impl Typo {
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[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.
///
@@ -310,21 +256,11 @@ pub struct Rank {
pub max_rank: u32,
}
impl PartialOrd for Rank {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
(self.max_rank == other.max_rank).then(|| self.rank.cmp(&other.rank))
}
}
impl Rank {
pub fn local_score(self) -> f64 {
self.rank as f64 / self.max_rank as f64
}
pub fn local_score_linear_scale(self) -> u64 {
(self.local_score() * LINEAR_SCALE_FACTOR).round() as u64
}
pub fn global_score(details: impl Iterator<Item = Self>) -> f64 {
let mut rank = Rank { rank: 1, max_rank: 1 };
for inner_rank in details {
@@ -337,25 +273,20 @@ impl Rank {
}
rank.local_score()
}
pub fn global_score_linear_scale(details: impl Iterator<Item = Self>) -> u64 {
(Self::global_score(details) * LINEAR_SCALE_FACTOR).round() as u64
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum ExactAttribute {
// Do not reorder as the order is significant, from least relevant to most relevant
NoExactMatch,
ExactMatch,
MatchesStart,
MatchesFull,
NoExactMatch,
}
impl ExactAttribute {
pub fn rank(&self) -> Rank {
let rank = match self {
ExactAttribute::MatchesFull => 3,
ExactAttribute::ExactMatch => 3,
ExactAttribute::MatchesStart => 2,
ExactAttribute::NoExactMatch => 1,
};
@@ -367,178 +298,19 @@ impl ExactAttribute {
pub struct Sort {
pub field_name: String,
pub ascending: bool,
pub redacted: bool,
pub value: serde_json::Value,
}
impl PartialOrd for Sort {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
if self.field_name != other.field_name {
return None;
}
if self.ascending != other.ascending {
return None;
}
match (&self.value, &other.value) {
(serde_json::Value::Null, serde_json::Value::Null) => Some(Ordering::Equal),
(serde_json::Value::Null, _) => Some(Ordering::Less),
(_, serde_json::Value::Null) => Some(Ordering::Greater),
// numbers are always before strings
(serde_json::Value::Number(_), serde_json::Value::String(_)) => Some(Ordering::Greater),
(serde_json::Value::String(_), serde_json::Value::Number(_)) => Some(Ordering::Less),
(serde_json::Value::Number(left), serde_json::Value::Number(right)) => {
//FIXME: unwrap permitted here?
let order = left.as_f64().unwrap().partial_cmp(&right.as_f64().unwrap())?;
// always reverted, as bigger is better
Some(if self.ascending { order.reverse() } else { order })
}
(serde_json::Value::String(left), serde_json::Value::String(right)) => {
let order = left.cmp(right);
Some(if self.ascending { order.reverse() } else { order })
}
_ => None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct GeoSort {
pub target_point: [f64; 2],
pub ascending: bool,
pub value: Option<[f64; 2]>,
}
impl PartialOrd for GeoSort {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
if self.target_point != other.target_point {
return None;
}
if self.ascending != other.ascending {
return None;
}
Some(match (self.distance(), other.distance()) {
(None, None) => Ordering::Equal,
(None, Some(_)) => Ordering::Less,
(Some(_), None) => Ordering::Greater,
(Some(left), Some(right)) => {
let order = left.partial_cmp(&right)?;
if self.ascending {
// when ascending, the one with the smallest distance has the best score
order.reverse()
} else {
order
}
}
})
}
}
impl GeoSort {
pub fn distance(&self) -> Option<f64> {
self.value.map(|value| distance_between_two_points(&self.target_point, &value))
}
}
const LINEAR_SCALE_FACTOR: f64 = 1000.0;
#[cfg(test)]
mod test {
use super::*;
#[test]
fn compare() {
let left = [
ScoreDetails::Words(Words { matching_words: 3, max_matching_words: 4 }),
ScoreDetails::Sort(Sort {
field_name: "doggo".into(),
ascending: true,
value: "Intel the Beagle".into(),
}),
];
let right = [
ScoreDetails::Words(Words { matching_words: 3, max_matching_words: 4 }),
ScoreDetails::Sort(Sort {
field_name: "doggo".into(),
ascending: true,
value: "Max the Labrador".into(),
}),
];
assert_eq!(
Ok(Ordering::Greater),
ScoreDetails::partial_cmp_iter(left.iter(), right.iter())
);
// equal when all the common components are equal
assert_eq!(
Ok(Ordering::Equal),
ScoreDetails::partial_cmp_iter(left[0..1].iter(), right.iter())
);
let right = [
ScoreDetails::Words(Words { matching_words: 4, max_matching_words: 4 }),
ScoreDetails::Sort(Sort {
field_name: "doggo".into(),
ascending: true,
value: "Max the Labrador".into(),
}),
];
assert_eq!(Ok(Ordering::Less), ScoreDetails::partial_cmp_iter(left.iter(), right.iter()));
}
#[test]
fn sort_not_comparable() {
let left = [
ScoreDetails::Words(Words { matching_words: 3, max_matching_words: 4 }),
ScoreDetails::Sort(Sort {
// not the same field name
field_name: "catto".into(),
ascending: true,
value: "Sylver the cat".into(),
}),
];
let right = [
ScoreDetails::Words(Words { matching_words: 3, max_matching_words: 4 }),
ScoreDetails::Sort(Sort {
field_name: "doggo".into(),
ascending: true,
value: "Max the Labrador".into(),
}),
];
assert_eq!(
Err(NotComparable(1)),
ScoreDetails::partial_cmp_iter(left.iter(), right.iter())
);
let left = [
ScoreDetails::Words(Words { matching_words: 3, max_matching_words: 4 }),
ScoreDetails::Sort(Sort {
field_name: "doggo".into(),
// Not the same order
ascending: false,
value: "Intel the Beagle".into(),
}),
];
let right = [
ScoreDetails::Words(Words { matching_words: 3, max_matching_words: 4 }),
ScoreDetails::Sort(Sort {
field_name: "doggo".into(),
ascending: true,
value: "Max the Labrador".into(),
}),
];
assert_eq!(
Err(NotComparable(1)),
ScoreDetails::partial_cmp_iter(left.iter(), right.iter())
);
}
#[test]
fn sort_behavior() {
let left = Sort { field_name: "price".into(), ascending: true, value: "5400".into() };
let right = Sort { field_name: "price".into(), ascending: true, value: 53.into() };
// number always better match than strings
assert_eq!(Some(Ordering::Less), left.partial_cmp(&right));
let left = Sort { field_name: "price".into(), ascending: false, value: "5400".into() };
let right = Sort { field_name: "price".into(), ascending: false, value: 53.into() };
// true regardless of the sort direction
assert_eq!(Some(Ordering::Less), left.partial_cmp(&right));
}
}

View File

@@ -7,7 +7,7 @@ use roaring::bitmap::RoaringBitmap;
pub use self::facet::{FacetDistribution, Filter, DEFAULT_VALUES_PER_FACET};
pub use self::new::matches::{FormatOptions, MatchBounds, Matcher, MatcherBuilder, MatchingWords};
use self::new::PartialSearchResult;
use crate::score_details::ScoreDetails;
use crate::score_details::{ScoreDetails, ScoringStrategy};
use crate::{
execute_search, AscDesc, DefaultSearchLogger, DocumentId, Index, Result, SearchContext,
};
@@ -30,6 +30,7 @@ pub struct Search<'a> {
sort_criteria: Option<Vec<AscDesc>>,
geo_strategy: new::GeoSortStrategy,
terms_matching_strategy: TermsMatchingStrategy,
scoring_strategy: ScoringStrategy,
words_limit: usize,
exhaustive_number_hits: bool,
rtxn: &'a heed::RoTxn<'a>,
@@ -46,6 +47,7 @@ impl<'a> Search<'a> {
sort_criteria: None,
geo_strategy: new::GeoSortStrategy::default(),
terms_matching_strategy: TermsMatchingStrategy::default(),
scoring_strategy: Default::default(),
exhaustive_number_hits: false,
words_limit: 10,
rtxn,
@@ -78,6 +80,11 @@ impl<'a> Search<'a> {
self
}
pub fn scoring_strategy(&mut self, value: ScoringStrategy) -> &mut Search<'a> {
self.scoring_strategy = value;
self
}
pub fn words_limit(&mut self, value: usize) -> &mut Search<'a> {
self.words_limit = value;
self
@@ -108,6 +115,7 @@ impl<'a> Search<'a> {
&mut ctx,
&self.query,
self.terms_matching_strategy,
self.scoring_strategy,
self.exhaustive_number_hits,
&self.filter,
&self.sort_criteria,
@@ -139,6 +147,7 @@ impl fmt::Debug for Search<'_> {
sort_criteria,
geo_strategy: _,
terms_matching_strategy,
scoring_strategy,
words_limit,
exhaustive_number_hits,
rtxn: _,
@@ -151,6 +160,7 @@ impl fmt::Debug for Search<'_> {
.field("limit", limit)
.field("sort_criteria", sort_criteria)
.field("terms_matching_strategy", terms_matching_strategy)
.field("scoring_strategy", scoring_strategy)
.field("exhaustive_number_hits", exhaustive_number_hits)
.field("words_limit", words_limit)
.finish()

View File

@@ -3,7 +3,7 @@ use roaring::RoaringBitmap;
use super::logger::SearchLogger;
use super::ranking_rules::{BoxRankingRule, RankingRuleQueryTrait};
use super::SearchContext;
use crate::score_details::ScoreDetails;
use crate::score_details::{ScoreDetails, ScoringStrategy};
use crate::search::new::distinct::{apply_distinct_rule, distinct_single_docid, DistinctOutput};
use crate::Result;
@@ -13,6 +13,8 @@ pub struct BucketSortOutput {
pub all_candidates: RoaringBitmap,
}
// TODO: would probably be good to regroup some of these inside of a struct?
#[allow(clippy::too_many_arguments)]
pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
ctx: &mut SearchContext<'ctx>,
mut ranking_rules: Vec<BoxRankingRule<'ctx, Q>>,
@@ -20,6 +22,7 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
universe: &RoaringBitmap,
from: usize,
length: usize,
scoring_strategy: ScoringStrategy,
logger: &mut dyn SearchLogger<Q>,
) -> Result<BucketSortOutput> {
logger.initial_query(query);
@@ -141,7 +144,12 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
while valid_docids.len() < length {
// The universe for this bucket is zero, so we don't need to sort
// anything, just go back to the parent ranking rule.
if ranking_rule_universes[cur_ranking_rule_index].is_empty() {
if ranking_rule_universes[cur_ranking_rule_index].is_empty()
|| (scoring_strategy == ScoringStrategy::Skip
&& ranking_rule_universes[cur_ranking_rule_index].len() == 1)
{
let bucket = std::mem::take(&mut ranking_rule_universes[cur_ranking_rule_index]);
maybe_add_to_results!(bucket);
back!();
continue;
}
@@ -166,6 +174,7 @@ pub fn bucket_sort<'ctx, Q: RankingRuleQueryTrait>(
ranking_rule_universes[cur_ranking_rule_index] -= &next_bucket.candidates;
if cur_ranking_rule_index == ranking_rules_len - 1
|| (scoring_strategy == ScoringStrategy::Skip && next_bucket.candidates.len() <= 1)
|| cur_offset + (next_bucket.candidates.len() as usize) < from
{
maybe_add_to_results!(next_bucket.candidates);

View File

@@ -249,7 +249,7 @@ impl State {
query: query_graph,
candidates,
score: ScoreDetails::ExactAttribute(
score_details::ExactAttribute::MatchesFull,
score_details::ExactAttribute::ExactMatch,
),
}),
)

View File

@@ -134,7 +134,20 @@ impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBase
_universe: &RoaringBitmap,
query_graph: &QueryGraph,
) -> Result<()> {
// the `next_max_cost` is the successor integer to the maximum cost of the paths in the graph.
//
// When there is a matching strategy, it also factors the additional costs of:
// 1. The words that are matched in phrases
// 2. Skipping words (by adding them to the paths with a cost)
let mut next_max_cost = 1;
let removal_cost = if let Some(terms_matching_strategy) = self.terms_matching_strategy {
// add the cost of the phrase to the next_max_cost
next_max_cost += query_graph
.words_in_phrases_count(ctx)
// remove 1 from the words in phrases count, because when there is a phrase we can now have a document
// where only the phrase is matching, and none of the non-phrase words.
// With the `1` that `next_max_cost` is initialized with, this gets counted twice.
.saturating_sub(1) as u64;
match terms_matching_strategy {
TermsMatchingStrategy::Last => {
let removal_order =
@@ -164,8 +177,8 @@ impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBase
// Then pre-compute the cost of all paths from each node to the end node
let all_costs = graph.find_all_costs_to_end();
let next_max_cost =
all_costs.get(graph.query_graph.root_node).iter().copied().max().unwrap_or(0) + 1;
next_max_cost +=
all_costs.get(graph.query_graph.root_node).iter().copied().max().unwrap_or(0);
let state = GraphBasedRankingRuleState {
graph,
@@ -301,8 +314,6 @@ impl<'ctx, G: RankingRuleGraphTrait> RankingRule<'ctx, QueryGraph> for GraphBase
// We modify the next query graph so that it only contains the subgraph
// that was used to compute this bucket
// But we only do it in case the bucket length is >1, because otherwise
// we know the child ranking rule won't be called anyway
let paths: Vec<Vec<(Option<LocatedQueryTermSubset>, LocatedQueryTermSubset)>> = good_paths
.into_iter()

View File

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

View File

@@ -44,7 +44,7 @@ use self::geo_sort::GeoSort;
pub use self::geo_sort::Strategy as GeoSortStrategy;
use self::graph_based_ranking_rule::Words;
use self::interner::Interned;
use crate::score_details::ScoreDetails;
use crate::score_details::{ScoreDetails, ScoringStrategy};
use crate::search::new::distinct::apply_distinct_rule;
use crate::{AscDesc, DocumentId, Filter, Index, Member, Result, TermsMatchingStrategy, UserError};
@@ -351,6 +351,7 @@ pub fn execute_search(
ctx: &mut SearchContext,
query: &Option<String>,
terms_matching_strategy: TermsMatchingStrategy,
scoring_strategy: ScoringStrategy,
exhaustive_number_hits: bool,
filters: &Option<Filter>,
sort_criteria: &Option<Vec<AscDesc>>,
@@ -412,7 +413,16 @@ pub fn execute_search(
universe =
resolve_universe(ctx, &universe, &graph, terms_matching_strategy, query_graph_logger)?;
bucket_sort(ctx, ranking_rules, &graph, &universe, from, length, query_graph_logger)?
bucket_sort(
ctx,
ranking_rules,
&graph,
&universe,
from,
length,
scoring_strategy,
query_graph_logger,
)?
} else {
let ranking_rules =
get_ranking_rules_for_placeholder_search(ctx, sort_criteria, geo_strategy)?;
@@ -423,6 +433,7 @@ pub fn execute_search(
&universe,
from,
length,
scoring_strategy,
placeholder_search_logger,
)?
};

View File

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

View File

@@ -78,6 +78,8 @@ impl RankingRuleGraphTrait for PositionGraph {
let mut positions_for_costs = FxHashMap::<u32, Vec<u16>>::default();
for position in all_positions {
// FIXME: bucketed position???
let distance = position.abs_diff(*term.positions.start());
let cost = {
let mut cost = 0;
for i in 0..term.term_ids.len() {
@@ -85,15 +87,17 @@ impl RankingRuleGraphTrait for PositionGraph {
// Because if two words are in the same bucketed position (e.g. 32) and consecutive,
// then their position cost will be 32+32=64, but an ngram of these two words at the
// same position will have a cost of 32+32+1=65
cost += cost_from_position(position as u32 + i as u32);
cost += cost_from_distance(distance as u32 + i as u32);
}
cost
};
positions_for_costs.entry(cost).or_default().push(position);
}
let mut edges = vec![];
let max_cost = term.term_ids.len() as u32 * 10;
let max_cost_exists = positions_for_costs.contains_key(&max_cost);
let mut edges = vec![];
for (cost, positions) in positions_for_costs {
// TODO: We can improve performances and relevancy by storing
// the term subsets associated to each position fetched
@@ -106,13 +110,14 @@ impl RankingRuleGraphTrait for PositionGraph {
));
}
// artificial empty condition for computing max cost
let max_cost = term.term_ids.len() as u32 * 10;
edges.push((
max_cost,
conditions_interner
.insert(PositionCondition { term: term.clone(), positions: Vec::default() }),
));
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)
}
@@ -122,8 +127,8 @@ impl RankingRuleGraphTrait for PositionGraph {
}
}
fn cost_from_position(sum_positions: u32) -> u32 {
match sum_positions {
fn cost_from_distance(distance: u32) -> u32 {
match distance {
0 => 0,
1 => 1,
2..=4 => 2,

View File

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

View File

@@ -51,6 +51,7 @@ pub struct Sort<'ctx, Query> {
is_ascending: bool,
original_query: Option<Query>,
iter: Option<RankingRuleOutputIterWrapper<'ctx, Query>>,
must_redact: bool,
}
impl<'ctx, Query> Sort<'ctx, Query> {
pub fn new(
@@ -61,8 +62,23 @@ impl<'ctx, Query> Sort<'ctx, Query> {
) -> Result<Self> {
let fields_ids_map = index.fields_ids_map(rtxn)?;
let field_id = fields_ids_map.id(&field_name);
let must_redact = Self::must_redact(index, rtxn, &field_name)?;
Ok(Self { field_name, field_id, is_ascending, original_query: None, iter: None })
Ok(Self {
field_name,
field_id,
is_ascending,
original_query: None,
iter: None,
must_redact,
})
}
fn must_redact(index: &Index, rtxn: &'ctx heed::RoTxn, field_name: &str) -> Result<bool> {
let Some(displayed_fields) = index.displayed_fields(rtxn)?
else { return Ok(false); };
Ok(!displayed_fields.iter().any(|&field| field == field_name))
}
}
@@ -145,6 +161,7 @@ impl<'ctx, Query: RankingRuleQueryTrait> RankingRule<'ctx, Query> for Sort<'ctx,
let query_graph = parent_query.clone();
let ascending = self.is_ascending;
let field_name = self.field_name.clone();
let must_redact = self.must_redact;
RankingRuleOutputIterWrapper::new(Box::new(number_iter.chain(string_iter).map(
move |r| {
let (docids, value) = r?;
@@ -154,6 +171,7 @@ impl<'ctx, Query: RankingRuleQueryTrait> RankingRule<'ctx, Query> for Sort<'ctx,
score: ScoreDetails::Sort(score_details::Sort {
field_name: field_name.clone(),
ascending,
redacted: must_redact,
value,
}),
})
@@ -189,6 +207,7 @@ impl<'ctx, Query: RankingRuleQueryTrait> RankingRule<'ctx, Query> for Sort<'ctx,
score: ScoreDetails::Sort(score_details::Sort {
field_name: self.field_name.clone(),
ascending: self.is_ascending,
redacted: self.must_redact,
value: serde_json::Value::Null,
}),
}))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,54 @@
---
source: milli/src/search/new/tests/words_tms.rs
expression: "format!(\"{document_scores:#?}\")"
---
[
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
],
[
Words(
Words {
matching_words: 9,
max_matching_words: 9,
},
),
],
[
Words(
Words {
matching_words: 8,
max_matching_words: 9,
},
),
],
[
Words(
Words {
matching_words: 5,
max_matching_words: 9,
},
),
],
[
Words(
Words {
matching_words: 5,
max_matching_words: 9,
},
),
],
]

View File

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

View File

@@ -16,7 +16,9 @@ use maplit::hashset;
use crate::index::tests::TempIndex;
use crate::search::new::tests::collect_field_values;
use crate::{AscDesc, Criterion, Member, Search, SearchResult, TermsMatchingStrategy};
use crate::{
score_details, AscDesc, Criterion, Member, Search, SearchResult, TermsMatchingStrategy,
};
fn create_index() -> TempIndex {
let index = TempIndex::new();
@@ -183,10 +185,12 @@ fn test_sort() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.sort_criteria(vec![AscDesc::Desc(Member::Field(S("letter")))]);
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[21, 22, 23, 20, 18, 19, 15, 16, 17, 9, 10, 11, 12, 13, 14, 8, 5, 6, 7, 2]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let letter_values = collect_field_values(&index, &txn, "letter", &documents_ids);
insta::assert_debug_snapshot!(letter_values, @r###"
@@ -216,10 +220,12 @@ fn test_sort() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.sort_criteria(vec![AscDesc::Desc(Member::Field(S("rank")))]);
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[14, 13, 12, 4, 7, 11, 17, 23, 1, 3, 6, 10, 16, 19, 22, 0, 2, 5, 8, 9]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let rank_values = collect_field_values(&index, &txn, "rank", &documents_ids);
insta::assert_debug_snapshot!(rank_values, @r###"
@@ -249,10 +255,12 @@ fn test_sort() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.sort_criteria(vec![AscDesc::Asc(Member::Field(S("vague")))]);
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[0, 2, 4, 5, 22, 23, 13, 1, 3, 12, 21, 11, 20, 6, 7, 8, 9, 10, 14, 15]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let vague_values = collect_field_values(&index, &txn, "vague", &documents_ids);
insta::assert_debug_snapshot!(vague_values, @r###"
@@ -282,10 +290,12 @@ fn test_sort() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.sort_criteria(vec![AscDesc::Desc(Member::Field(S("vague")))]);
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[4, 13, 23, 22, 2, 5, 0, 11, 20, 12, 21, 3, 1, 6, 7, 8, 9, 10, 14, 15]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let vague_values = collect_field_values(&index, &txn, "vague", &documents_ids);
insta::assert_debug_snapshot!(vague_values, @r###"
@@ -313,3 +323,33 @@ fn test_sort() {
]
"###);
}
#[test]
fn test_redacted() {
let index = create_index();
index
.update_settings(|s| {
s.set_displayed_fields(vec!["text".to_owned(), "vague".to_owned()]);
s.set_sortable_fields(hashset! { S("rank"), S("vague"), S("letter") });
s.set_criteria(vec![Criterion::Sort]);
})
.unwrap();
let txn = index.read_txn().unwrap();
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.sort_criteria(vec![
AscDesc::Asc(Member::Field(S("vague"))),
AscDesc::Asc(Member::Field(S("letter"))),
]);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
let document_scores_json: Vec<_> = document_scores
.iter()
.map(|scores| score_details::ScoreDetails::to_json_map(scores.iter()))
.collect();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[0, 2, 4, 5, 22, 23, 13, 1, 3, 12, 21, 11, 20, 6, 7, 8, 9, 10, 14, 15]");
insta::assert_json_snapshot!(document_scores_json);
}

View File

@@ -81,28 +81,212 @@ fn test_ignore_stop_words() {
let mut s = Search::new(&txn, &index);
s.query("xyz to the");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
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:?}"), @"[6]");
insta::assert_snapshot!(format!("{document_scores:#?}"), @r###"
[
[
Words(
Words {
matching_words: 1,
max_matching_words: 1,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 1,
},
),
Proximity(
Rank {
rank: 1,
max_rank: 1,
},
),
Fid(
Rank {
rank: 1,
max_rank: 1,
},
),
Position(
Rank {
rank: 9,
max_rank: 11,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
]
"###);
// `xyz` is treated as a prefix here, so it's not ignored
let mut s = Search::new(&txn, &index);
s.query("to the xyz");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
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:?}"), @"[6]");
insta::assert_snapshot!(format!("{document_scores:#?}"), @r###"
[
[
Words(
Words {
matching_words: 1,
max_matching_words: 2,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 1,
},
),
Proximity(
Rank {
rank: 1,
max_rank: 1,
},
),
Fid(
Rank {
rank: 1,
max_rank: 1,
},
),
Position(
Rank {
rank: 9,
max_rank: 11,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
]
"###);
// `xyz` is not treated as a prefix anymore because of the trailing space, so it's ignored
let mut s = Search::new(&txn, &index);
s.query("to the xyz ");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
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:?}"), @"[6]");
insta::assert_snapshot!(format!("{document_scores:#?}"), @r###"
[
[
Words(
Words {
matching_words: 1,
max_matching_words: 1,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 1,
},
),
Proximity(
Rank {
rank: 1,
max_rank: 1,
},
),
Fid(
Rank {
rank: 1,
max_rank: 1,
},
),
Position(
Rank {
rank: 9,
max_rank: 11,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
]
"###);
let mut s = Search::new(&txn, &index);
s.query("to the dragon xyz");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
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:?}"), @"[6]");
insta::assert_snapshot!(format!("{document_scores:#?}"), @r###"
[
[
Words(
Words {
matching_words: 2,
max_matching_words: 3,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 2,
},
),
Proximity(
Rank {
rank: 7,
max_rank: 8,
},
),
Fid(
Rank {
rank: 1,
max_rank: 1,
},
),
Position(
Rank {
rank: 17,
max_rank: 21,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 3,
max_rank: 3,
},
),
],
]
"###);
}
#[test]
@@ -114,24 +298,163 @@ fn test_stop_words_in_phrase() {
let mut s = Search::new(&txn, &index);
s.query("\"how to train your dragon\"");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
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:?}"), @"[3, 6]");
insta::assert_snapshot!(format!("{document_scores:#?}"), @r###"
[
[
Words(
Words {
matching_words: 4,
max_matching_words: 4,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 0,
},
),
Proximity(
Rank {
rank: 1,
max_rank: 1,
},
),
Fid(
Rank {
rank: 1,
max_rank: 1,
},
),
Position(
Rank {
rank: 11,
max_rank: 11,
},
),
ExactAttribute(
MatchesStart,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
[
Words(
Words {
matching_words: 4,
max_matching_words: 4,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 0,
},
),
Proximity(
Rank {
rank: 1,
max_rank: 1,
},
),
Fid(
Rank {
rank: 1,
max_rank: 1,
},
),
Position(
Rank {
rank: 11,
max_rank: 11,
},
),
ExactAttribute(
MatchesStart,
),
Exactness(
Rank {
rank: 2,
max_rank: 2,
},
),
],
]
"###);
let mut s = Search::new(&txn, &index);
s.query("how \"to\" train \"the");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
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:?}"), @"[6]");
insta::assert_snapshot!(format!("{document_scores:#?}"), @r###"
[
[
Words(
Words {
matching_words: 3,
max_matching_words: 3,
},
),
Typo(
Typo {
typo_count: 0,
max_typo_count: 2,
},
),
Proximity(
Rank {
rank: 6,
max_rank: 8,
},
),
Fid(
Rank {
rank: 1,
max_rank: 1,
},
),
Position(
Rank {
rank: 29,
max_rank: 31,
},
),
ExactAttribute(
NoExactMatch,
),
Exactness(
Rank {
rank: 4,
max_rank: 4,
},
),
],
]
"###);
let mut s = Search::new(&txn, &index);
s.query("how \"to\" train \"The dragon");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
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:?}"), @"[3, 6, 5]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let mut s = Search::new(&txn, &index);
s.query("\"to\"");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
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, 2, 3, 4, 5, 6]");
// The search is handled as a placeholder search because it doesn't have any non-stop words in it.
// As a result the scores are empty lists
insta::assert_snapshot!(format!("{document_scores:#?}"));
}

View File

@@ -160,8 +160,9 @@ fn test_no_typo() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[0]");
insta::assert_snapshot!(format!("{document_scores:?}"), @"[[]]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -184,8 +185,14 @@ fn test_default_typo() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[0, 23]");
insta::assert_snapshot!(format!("{document_scores:#?}"), @r###"
[
[],
[],
]
"###);
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -198,8 +205,9 @@ fn test_default_typo() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("the quack brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[0]");
insta::assert_snapshot!(format!("{document_scores:?}"), @"[[]]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -211,8 +219,9 @@ fn test_default_typo() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("the quicest brownest fox jummps over the laziest dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[3]");
insta::assert_snapshot!(format!("{document_scores:?}"), @"[[]]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -229,8 +238,9 @@ fn test_phrase_no_typo_allowed() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("the \"quick brewn\" fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[]");
insta::assert_snapshot!(format!("{document_scores:?}"), @"[]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @"[]");
}
@@ -258,8 +268,9 @@ fn test_typo_exact_word() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[0]");
insta::assert_snapshot!(format!("{document_scores:?}"), @"[[]]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -271,15 +282,17 @@ fn test_typo_exact_word() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("the quack brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[]");
insta::assert_snapshot!(format!("{document_scores:?}"), @"[]");
// words not in exact_words (quicest, jummps) have normal typo handling
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("the quicest brownest fox jummps over the laziest dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[3]");
insta::assert_snapshot!(format!("{document_scores:?}"), @"[[]]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -290,9 +303,11 @@ fn test_typo_exact_word() {
// exact words do not disable prefix (sunflowering OK, but no sunflowar)
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("network interconnection sunflower");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[16, 17, 18]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -327,9 +342,11 @@ fn test_typo_exact_attribute() {
// Exact match returns both exact attributes and tolerant ones.
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[0, 24, 25]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -350,9 +367,16 @@ fn test_typo_exact_attribute() {
// 1 typo only returns the tolerant attribute
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("the quidk brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[24, 25]");
insta::assert_snapshot!(format!("{document_scores:#?}"), @r###"
[
[],
[],
]
"###);
let texts = collect_field_values(&index, &txn, "tolerant_text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -364,9 +388,16 @@ fn test_typo_exact_attribute() {
// combine with exact words
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("the quivk brown fox jumps over the lazy dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[23, 25]");
insta::assert_snapshot!(format!("{document_scores:#?}"), @r###"
[
[],
[],
]
"###);
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -385,9 +416,11 @@ fn test_typo_exact_attribute() {
// No result in tolerant attribute
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("the quicest brownest fox jummps over the laziest dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[]");
insta::assert_snapshot!(format!("{document_scores:?}"), @"[]");
}
#[test]
@@ -397,9 +430,11 @@ fn test_ngram_typos() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("the extra lagant fox skyrocketed over the languorous dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[6]");
insta::assert_snapshot!(format!("{document_scores:?}"), @"[[]]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -409,9 +444,11 @@ fn test_ngram_typos() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("the ex tra lagant fox skyrocketed over the languorous dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[]");
insta::assert_snapshot!(format!("{document_scores:#?}"), @"[]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @"[]");
}
@@ -428,9 +465,11 @@ fn test_typo_ranking_rule_not_preceded_by_words_ranking_rule() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids: ids_1, .. } = s.execute().unwrap();
let SearchResult { documents_ids: ids_1, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{ids_1:?}"), @"[0, 23, 7, 8, 9, 22, 10, 11, 1, 2, 12, 13, 4, 3, 5, 6, 21]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &ids_1);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -462,9 +501,11 @@ fn test_typo_ranking_rule_not_preceded_by_words_ranking_rule() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::Last);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("the quick brown fox jumps over the lazy dog");
let SearchResult { documents_ids: ids_2, .. } = s.execute().unwrap();
let SearchResult { documents_ids: ids_2, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{ids_2:?}"), @"[0, 23, 7, 8, 9, 22, 10, 11, 1, 2, 12, 13, 4, 3, 5, 6, 21]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
assert_eq!(ids_1, ids_2);
}
@@ -478,9 +519,11 @@ fn test_typo_bucketing() {
// First do the search with just the Words ranking rule
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("network interconnection sunflower");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[14, 15, 16, 17, 18, 20]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -504,9 +547,11 @@ fn test_typo_bucketing() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("network interconnection sunflower");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[16, 18, 17, 20, 15, 14]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -521,9 +566,11 @@ fn test_typo_bucketing() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("network interconnection sun flower");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[17, 19, 16, 18, 20, 15]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -555,9 +602,11 @@ fn test_typo_synonyms() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("the quick brown fox jumps over the lackadaisical dog");
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[0, 22, 23]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -569,12 +618,14 @@ fn test_typo_synonyms() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
s.query("the fast brownish fox jumps over the lackadaisical dog");
// TODO: is this correct? interaction of ngrams + synonyms means that the
// multi-word synonyms end up having a typo cost. This is probably not what we want.
let SearchResult { documents_ids, .. } = s.execute().unwrap();
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[21, 0, 22]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[

View File

@@ -90,8 +90,10 @@ fn test_trap_basic_and_complex1() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("beautiful summer");
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:?}"), @"[1, 0, 3, 2]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -111,8 +113,10 @@ fn test_trap_complex2() {
let mut s = Search::new(&txn, &index);
s.terms_matching_strategy(TermsMatchingStrategy::All);
s.query("delicious sweet dessert");
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:?}"), @"[5, 4]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[

View File

@@ -134,10 +134,12 @@ fn test_words_tms_last_simple() {
let mut s = Search::new(&txn, &index);
s.query("the quick brown fox jumps over the lazy dog");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
// 6 and 7 have the same score because "the" appears twice
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 10, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 8, 6, 7, 5, 4, 11, 12, 3]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -167,8 +169,10 @@ fn test_words_tms_last_simple() {
let mut s = Search::new(&txn, &index);
s.query("extravagant the quick brown fox jumps over the lazy dog");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
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:?}"), @"[]");
insta::assert_snapshot!(format!("{document_scores:?}"), @"[]");
}
#[test]
@@ -179,10 +183,12 @@ fn test_words_tms_last_phrase() {
let mut s = Search::new(&txn, &index);
s.query("\"the quick brown fox\" jumps over the lazy dog");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
// "The quick brown fox" is a phrase, not deleted by this term matching strategy
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 17, 21, 8, 6, 7, 5, 4, 11, 12]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -202,11 +208,13 @@ fn test_words_tms_last_phrase() {
let mut s = Search::new(&txn, &index);
s.query("\"the quick brown fox\" jumps over the \"lazy\" dog");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
// "lazy" is a phrase, not deleted by this term matching strategy
// but words before it can be deleted
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 17, 21, 8, 11, 12]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -222,10 +230,12 @@ fn test_words_tms_last_phrase() {
let mut s = Search::new(&txn, &index);
s.query("\"the quick brown fox jumps over the lazy dog\"");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
// The whole query is a phrase, no terms are removed
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9]");
insta::assert_snapshot!(format!("{document_scores:?}"), @"[[Words(Words { matching_words: 9, max_matching_words: 9 })]]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -236,10 +246,12 @@ fn test_words_tms_last_phrase() {
let mut s = Search::new(&txn, &index);
s.query("\"the quick brown fox jumps over the lazy dog");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
// The whole query is still a phrase, even without closing quotes, so no terms are removed
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9]");
insta::assert_snapshot!(format!("{document_scores:?}"), @"[[Words(Words { matching_words: 9, max_matching_words: 9 })]]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -261,10 +273,12 @@ fn test_words_proximity_tms_last_simple() {
let mut s = Search::new(&txn, &index);
s.query("the quick brown fox jumps over the lazy dog");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
// 7 is better than 6 because of the proximity between "the" and its surrounding terms
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 21, 14, 17, 13, 10, 18, 19, 20, 16, 15, 22, 8, 7, 6, 5, 4, 11, 12, 3]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -294,10 +308,12 @@ fn test_words_proximity_tms_last_simple() {
let mut s = Search::new(&txn, &index);
s.query("the brown quick fox jumps over the lazy dog");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
// 10 is better than 9 because of the proximity between "quick" and "brown"
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[10, 18, 19, 9, 20, 21, 14, 17, 13, 16, 15, 22, 8, 7, 6, 5, 4, 11, 12, 3]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -338,11 +354,13 @@ fn test_words_proximity_tms_last_phrase() {
let mut s = Search::new(&txn, &index);
s.query("the \"quick brown\" fox jumps over the lazy dog");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
// "quick brown" is a phrase. The proximity of its first and last words
// to their adjacent query words should be taken into account
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 21, 14, 17, 13, 16, 15, 8, 7, 6, 5, 4, 11, 12, 3]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -367,12 +385,14 @@ fn test_words_proximity_tms_last_phrase() {
let mut s = Search::new(&txn, &index);
s.query("the \"quick brown\" \"fox jumps\" over the lazy dog");
s.terms_matching_strategy(TermsMatchingStrategy::Last);
let SearchResult { documents_ids, .. } = s.execute().unwrap();
s.scoring_strategy(crate::score_details::ScoringStrategy::Detailed);
let SearchResult { documents_ids, document_scores, .. } = s.execute().unwrap();
// "quick brown" is a phrase. The proximity of its first and last words
// to their adjacent query words should be taken into account.
// The same applies to `fox jumps`.
insta::assert_snapshot!(format!("{documents_ids:?}"), @"[9, 21, 14, 17, 13, 16, 15, 8, 7, 6, 5]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -404,9 +424,11 @@ fn test_words_tms_all() {
let mut s = Search::new(&txn, &index);
s.query("the quick brown fox jumps over the lazy dog");
s.terms_matching_strategy(TermsMatchingStrategy::All);
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:?}"), @"[9, 21, 14, 17, 13, 10, 18, 19, 20, 16, 15, 22]");
insta::assert_snapshot!(format!("{document_scores:#?}"));
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @r###"
[
@@ -428,9 +450,11 @@ fn test_words_tms_all() {
let mut s = Search::new(&txn, &index);
s.query("extravagant");
s.terms_matching_strategy(TermsMatchingStrategy::All);
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:?}"), @"[]");
insta::assert_snapshot!(format!("{document_scores:?}"), @"[]");
let texts = collect_field_values(&index, &txn, "text", &documents_ids);
insta::assert_debug_snapshot!(texts, @"[]");
}

View File

@@ -318,7 +318,7 @@ pub fn snap_field_distributions(index: &Index) -> String {
let rtxn = index.read_txn().unwrap();
let mut snap = String::new();
for (field, count) in index.field_distribution(&rtxn).unwrap() {
writeln!(&mut snap, "{field:<16} {count:<6}").unwrap();
writeln!(&mut snap, "{field:<16} {count:<6} |").unwrap();
}
snap
}
@@ -328,7 +328,7 @@ pub fn snap_fields_ids_map(index: &Index) -> String {
let mut snap = String::new();
for field_id in fields_ids_map.ids() {
let name = fields_ids_map.name(field_id).unwrap();
writeln!(&mut snap, "{field_id:<3} {name:<16}").unwrap();
writeln!(&mut snap, "{field_id:<3} {name:<16} |").unwrap();
}
snap
}

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