diff --git a/milli/src/search/new/matches/mod.rs b/milli/src/search/new/matches/mod.rs
index 72e155b3e..5d61de0f4 100644
--- a/milli/src/search/new/matches/mod.rs
+++ b/milli/src/search/new/matches/mod.rs
@@ -418,19 +418,11 @@ impl<'t> Matcher<'t, '_> {
} else {
match &self.matches {
Some((tokens, matches)) => {
- // If the text has to be cropped,
- // compute the best interval to crop around.
- let matches = match format_options.crop {
- Some(crop_size) if crop_size > 0 => {
- self.find_best_match_interval(matches, crop_size)
- }
- _ => matches,
- };
-
// If the text has to be cropped,
// crop around the best interval.
let (byte_start, byte_end) = match format_options.crop {
Some(crop_size) if crop_size > 0 => {
+ let matches = self.find_best_match_interval(matches, crop_size);
self.crop_bounds(tokens, matches, crop_size)
}
_ => (0, self.text.len()),
@@ -450,6 +442,11 @@ impl<'t> Matcher<'t, '_> {
for m in matches {
let token = &tokens[m.token_position];
+ // skip matches out of the crop window.
+ if token.byte_start < byte_start || token.byte_end > byte_end {
+ continue;
+ }
+
if byte_index < token.byte_start {
formatted.push(&self.text[byte_index..token.byte_start]);
}
@@ -800,6 +797,37 @@ mod tests {
);
}
+ #[test]
+ fn format_highlight_crop_phrase_query() {
+ //! testing: https://github.com/meilisearch/meilisearch/issues/3975
+ let temp_index = TempIndex::new();
+ temp_index
+ .add_documents(documents!([
+ { "id": 1, "text": "The groundbreaking invention had the power to split the world between those who embraced progress and those who resisted change!" }
+ ]))
+ .unwrap();
+ let rtxn = temp_index.read_txn().unwrap();
+
+ let format_options = FormatOptions { highlight: true, crop: Some(10) };
+ let text = "The groundbreaking invention had the power to split the world between those who embraced progress and those who resisted change!";
+
+ let builder = MatcherBuilder::new_test(&rtxn, &temp_index, "\"the world\"");
+ let mut matcher = builder.build(text);
+ // should return 10 words with a marker at the start as well the end, and the highlighted matches.
+ insta::assert_snapshot!(
+ matcher.format(format_options),
+ @"…had the power to split the world between those who…"
+ );
+
+ let builder = MatcherBuilder::new_test(&rtxn, &temp_index, "those \"and those\"");
+ let mut matcher = builder.build(text);
+ // should highlight "those" and the phrase "and those".
+ insta::assert_snapshot!(
+ matcher.format(format_options),
+ @"…world between those who embraced progress and those who resisted…"
+ );
+ }
+
#[test]
fn smaller_crop_size() {
//! testing: https://github.com/meilisearch/specifications/pull/120#discussion_r836536295