Skip to content

Commit

Permalink
Fix for contextual fuzzy matching in Live searches.
Browse files Browse the repository at this point in the history
  • Loading branch information
leontoeides committed Nov 18, 2023
1 parent d480754 commit 36bafd2
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 37 deletions.
3 changes: 1 addition & 2 deletions src/simple/autocomplete/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ mod keyword;
// -----------------------------------------------------------------------------

use crate::simple::{AutocompleteType, SearchIndex};
use std::cmp::Ord;
use std::hash::Hash;
use std::{cmp::Ord, hash::Hash};

// -----------------------------------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion src/simple/internal/fuzzy_top_scores/results.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ impl<'a, K: Hash + Ord, S: PartialOrd> FuzzyTopScores<'a, K, S> {
.into_iter()
.map(|(keyword, (keys, _score))| (keyword, keys))

} // if keywords
} // fn results

} // impl FuzzyTopScores
2 changes: 1 addition & 1 deletion src/simple/internal/search_top_scores/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use std::{cmp::Ord, hash::Hash};
/// Tracks the top scoring keys. This is intended to track the best _n_ matches
/// for returning search results.
#[derive(Default)]
#[derive(Debug, Default)]
pub(crate) struct SearchTopScores<'a, K: Hash + Ord> {
/// Tracks the top _n_ scores.
pub(crate) top: HashMap<&'a K, usize>,
Expand Down
66 changes: 34 additions & 32 deletions src/simple/search/live.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,17 +178,17 @@ impl<K: Hash + Ord> SearchIndex<K> {
search_results = self.eddie_context_autocomplete(
&search_results,
&last_keyword,
) // strsim_context_autocomplete
) // eddie_context_autocomplete
.into_iter()
// Only return `maximum_search_results` number of
// keys:
.take(*maximum_search_results)
// `strsim_autocomplete` returns both the keyword
// and keys. We're searching for the last (partial)
// keyword, so discard the keywords. Flatten the
// `BTreeSet<K>` from each search result into our
// collection:
.flat_map(|(_keyword, keys)| keys)
// Only return `maximum_search_results` number of
// keys:
.take(*maximum_search_results)
// Collect all keyword autocompletions into a
// `BTreeSet`:
.collect()
Expand All @@ -206,15 +206,15 @@ impl<K: Hash + Ord> SearchIndex<K> {
&last_keyword,
) // strsim_context_autocomplete
.into_iter()
// Only return `maximum_search_results` number of
// keys:
.take(*maximum_search_results)
// `strsim_autocomplete` returns both the keyword
// and keys. We're searching for the last (partial)
// keyword, so discard the keywords. Flatten the
// `BTreeSet<K>` from each search result into our
// collection:
.flat_map(|(_keyword, keys)| keys)
// Only return `maximum_search_results` number of
// keys:
.take(*maximum_search_results)
// Collect all keyword autocompletions into a
// `BTreeSet`:
.collect()
Expand Down Expand Up @@ -285,26 +285,27 @@ impl<K: Hash + Ord> SearchIndex<K> {
last_results = self.eddie_context_autocomplete(
&search_results,
&last_keyword,
) // strsim_context_autocomplete
) // eddie_context_autocomplete
.into_iter()
// Only keep this result if hasn't already been used
// as a keyword:
.filter(|(keyword, _keys)| !keywords.contains(keyword))
// Only keep this autocompletion if it contains a
// key that the search results contain:
.filter(|(_keyword, keys)|
last_results.is_empty() ||
keys.iter().any(|key| last_results.contains(key))
) // filter
// Only return `maximum_search_results` number of
// keys:
.take(*maximum_search_results)
// `strsim_autocomplete` returns both the keyword
// and keys. We're searching for the last (partial)
// keyword, so discard the keywords. Flatten the
// Intersect the key results from the autocomplete
// options (produced from this iterator) with the
// search results produced at the top:
.map(|(keyword, keys)| (
keyword,
keys.iter().filter(|key| search_results.contains(key)).collect::<BTreeSet<_>>(),
)) // map
// Autocomplete returns both the keyword and keys.
// We're searching for the last (partial) keyword,
// so discard the keywords. Flatten the
// `BTreeSet<K>` from each search result into our
// collection:
.flat_map(|(_keyword, keys)| keys)
// Only return `maximum_search_results` number of
// keys:
.take(*maximum_search_results)
// Collect all keyword autocompletions into a
// `BTreeSet`:
.collect()
Expand All @@ -325,21 +326,22 @@ impl<K: Hash + Ord> SearchIndex<K> {
// Only keep this result if hasn't already been used
// as a keyword:
.filter(|(keyword, _keys)| !keywords.contains(keyword))
// Only keep this autocompletion if it contains a
// key that the search results contain:
.filter(|(_keyword, keys)|
last_results.is_empty() ||
keys.iter().any(|key| last_results.contains(key))
) // filter
// Only return `maximum_search_results` number of
// keys:
.take(*maximum_search_results)
// `strsim_autocomplete` returns both the keyword
// and keys. We're searching for the last (partial)
// keyword, so discard the keywords. Flatten the
// Intersect the key results from the autocomplete
// options (produced from this iterator) with the
// search results produced at the top:
.map(|(keyword, keys)| (
keyword,
keys.iter().filter(|key| search_results.contains(key)).collect::<BTreeSet<_>>(),
)) // map
// Autocomplete returns both the keyword and keys.
// We're searching for the last (partial) keyword,
// so discard the keywords. Flatten the
// `BTreeSet<K>` from each search result into our
// collection:
.flat_map(|(_keyword, keys)| keys)
// Only return `maximum_search_results` number of
// keys:
.take(*maximum_search_results)
// Collect all keyword autocompletions into a
// `BTreeSet`:
.collect()
Expand Down
2 changes: 1 addition & 1 deletion src/simple/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ fn simple() {

// Fuzzy matching:
#[cfg(any(feature = "eddie", feature = "strsim"))]
let search_results = search_index.search_type(&SearchType::Live, "peet of Annan");
let search_results = search_index.search_type(&SearchType::Live, "peat of Annan");
#[cfg(any(feature = "eddie", feature = "strsim"))]
assert_eq!(search_results, vec![&3]);

Expand Down

0 comments on commit 36bafd2

Please sign in to comment.