module QuickSearch
( buildTokenPartitions
, buildQuickSearch
, rawBuildQuickSearch
, matchesWithThreshold
, topNMatches
, batch
, batchTopNMatches
, batchMatchesWithThreshold
, Token
, Score
, Scorer
, Entry(..)
, entryName
, entryUID
, Match(..)
, QuickSearch(..)
, damerauLevenshteinNorm
, jaro
, jaroWinkler
) where
import Data.Hashable ( Hashable )
import qualified Data.Text as T
import Data.Text.Metrics ( damerauLevenshteinNorm
, jaro
, jaroWinkler
)
import QuickSearch.Internal.Filter ( Entry(..)
, Token
, buildTokenPartitions
, entryName
, entryUID
)
import QuickSearch.Internal.Matcher ( Match(..)
, QuickSearch(..)
, Score
, Scorer
, matchScore
, scoreMatches
)
rawBuildQuickSearch
:: (Hashable uid, Eq uid)
=> [Entry T.Text uid]
-> QuickSearch uid
rawBuildQuickSearch :: [Entry Text uid] -> QuickSearch uid
rawBuildQuickSearch [Entry Text uid]
entries = (([Entry Text uid], HashMap Text (HashSet uid)) -> QuickSearch uid)
-> [Entry Text uid]
-> HashMap Text (HashSet uid)
-> QuickSearch uid
forall a b c. ((a, b) -> c) -> a -> b -> c
curry ([Entry Text uid], HashMap Text (HashSet uid)) -> QuickSearch uid
forall uid.
([Entry Text uid], HashMap Text (HashSet uid)) -> QuickSearch uid
QuickSearch [Entry Text uid]
entries (HashMap Text (HashSet uid) -> QuickSearch uid)
-> HashMap Text (HashSet uid) -> QuickSearch uid
forall a b. (a -> b) -> a -> b
$ [Entry Text uid] -> HashMap Text (HashSet uid)
forall uid.
(Hashable uid, Eq uid) =>
[Entry Text uid] -> HashMap Text (HashSet uid)
buildTokenPartitions [Entry Text uid]
entries
buildQuickSearch
:: (Hashable uid, Eq uid)
=> [(T.Text, uid)]
-> QuickSearch uid
buildQuickSearch :: [(Text, uid)] -> QuickSearch uid
buildQuickSearch = [Entry Text uid] -> QuickSearch uid
forall uid.
(Hashable uid, Eq uid) =>
[Entry Text uid] -> QuickSearch uid
rawBuildQuickSearch ([Entry Text uid] -> QuickSearch uid)
-> ([(Text, uid)] -> [Entry Text uid])
-> [(Text, uid)]
-> QuickSearch uid
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Text, uid) -> Entry Text uid)
-> [(Text, uid)] -> [Entry Text uid]
forall a b. (a -> b) -> [a] -> [b]
map (Text, uid) -> Entry Text uid
forall name uid. (name, uid) -> Entry name uid
Entry
topNMatches
:: (Hashable uid, Eq uid)
=> QuickSearch uid
-> Int
-> Scorer
-> T.Text
-> [Match Score (Entry T.Text uid)]
topNMatches :: QuickSearch uid
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid)]
topNMatches QuickSearch uid
qs Int
n Scorer
scorer Text
entry = Int -> [Match Int (Entry Text uid)] -> [Match Int (Entry Text uid)]
forall a. Int -> [a] -> [a]
take Int
n (Text -> QuickSearch uid -> Scorer -> [Match Int (Entry Text uid)]
forall uid.
(Hashable uid, Eq uid) =>
Text -> QuickSearch uid -> Scorer -> [Match Int (Entry Text uid)]
scoreMatches Text
entry QuickSearch uid
qs Scorer
scorer)
matchesWithThreshold
:: (Hashable uid, Eq uid)
=> QuickSearch uid
-> Int
-> Scorer
-> T.Text
-> [Match Score (Entry T.Text uid)]
matchesWithThreshold :: QuickSearch uid
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid)]
matchesWithThreshold QuickSearch uid
qs Int
cutoff Scorer
scorer Text
entry = (Match Int (Entry Text uid) -> Bool)
-> [Match Int (Entry Text uid)] -> [Match Int (Entry Text uid)]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile ((Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
cutoff) (Int -> Bool)
-> (Match Int (Entry Text uid) -> Int)
-> Match Int (Entry Text uid)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Match Int (Entry Text uid) -> Int
forall name uid. Match Int (Entry name uid) -> Int
matchScore)
[Match Int (Entry Text uid)]
results
where results :: [Match Int (Entry Text uid)]
results = Text -> QuickSearch uid -> Scorer -> [Match Int (Entry Text uid)]
forall uid.
(Hashable uid, Eq uid) =>
Text -> QuickSearch uid -> Scorer -> [Match Int (Entry Text uid)]
scoreMatches Text
entry QuickSearch uid
qs Scorer
scorer
batch
:: (Hashable uid1, Eq uid1, Hashable uid2, Eq uid2)
=> ( QuickSearch uid2
-> Int
-> Scorer
-> T.Text
-> [Match Score (Entry T.Text uid2)]
)
-> QuickSearch uid2
-> Int
-> Scorer
-> [(T.Text, uid1)]
-> [(Entry T.Text uid1, [Match Score (Entry T.Text uid2)])]
batch :: (QuickSearch uid2
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)])
-> QuickSearch uid2
-> Int
-> Scorer
-> [(Text, uid1)]
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
batch QuickSearch uid2
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)]
f QuickSearch uid2
qs Int
n Scorer
scorer [(Text, uid1)]
entries =
let entries' :: [Entry Text uid1]
entries' = ((Text, uid1) -> Entry Text uid1)
-> [(Text, uid1)] -> [Entry Text uid1]
forall a b. (a -> b) -> [a] -> [b]
map (Text, uid1) -> Entry Text uid1
forall name uid. (name, uid) -> Entry name uid
Entry [(Text, uid1)]
entries
results :: [[Match Int (Entry Text uid2)]]
results = (Entry Text uid1 -> [Match Int (Entry Text uid2)])
-> [Entry Text uid1] -> [[Match Int (Entry Text uid2)]]
forall a b. (a -> b) -> [a] -> [b]
map (QuickSearch uid2
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)]
f QuickSearch uid2
qs Int
n Scorer
scorer (Text -> [Match Int (Entry Text uid2)])
-> (Entry Text uid1 -> Text)
-> Entry Text uid1
-> [Match Int (Entry Text uid2)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Entry Text uid1 -> Text
forall name uid. Entry name uid -> name
entryName) [Entry Text uid1]
entries'
in [Entry Text uid1]
-> [[Match Int (Entry Text uid2)]]
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
forall a b. [a] -> [b] -> [(a, b)]
zip [Entry Text uid1]
entries' [[Match Int (Entry Text uid2)]]
results
batchTopNMatches
:: (Hashable uid1, Eq uid1, Hashable uid2, Eq uid2)
=> QuickSearch uid2
-> Int
-> Scorer
-> [(T.Text, uid1)]
-> [(Entry T.Text uid1, [Match Score (Entry T.Text uid2)])]
batchTopNMatches :: QuickSearch uid2
-> Int
-> Scorer
-> [(Text, uid1)]
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
batchTopNMatches = (QuickSearch uid2
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)])
-> QuickSearch uid2
-> Int
-> Scorer
-> [(Text, uid1)]
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
forall uid1 uid2.
(Hashable uid1, Eq uid1, Hashable uid2, Eq uid2) =>
(QuickSearch uid2
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)])
-> QuickSearch uid2
-> Int
-> Scorer
-> [(Text, uid1)]
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
batch QuickSearch uid2
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)]
forall uid.
(Hashable uid, Eq uid) =>
QuickSearch uid
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid)]
topNMatches
batchMatchesWithThreshold
:: (Hashable uid1, Eq uid1, Hashable uid2, Eq uid2)
=> QuickSearch uid2
-> Int
-> Scorer
-> [(T.Text, uid1)]
-> [(Entry T.Text uid1, [Match Score (Entry T.Text uid2)])]
batchMatchesWithThreshold :: QuickSearch uid2
-> Int
-> Scorer
-> [(Text, uid1)]
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
batchMatchesWithThreshold = (QuickSearch uid2
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)])
-> QuickSearch uid2
-> Int
-> Scorer
-> [(Text, uid1)]
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
forall uid1 uid2.
(Hashable uid1, Eq uid1, Hashable uid2, Eq uid2) =>
(QuickSearch uid2
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)])
-> QuickSearch uid2
-> Int
-> Scorer
-> [(Text, uid1)]
-> [(Entry Text uid1, [Match Int (Entry Text uid2)])]
batch QuickSearch uid2
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid2)]
forall uid.
(Hashable uid, Eq uid) =>
QuickSearch uid
-> Int -> Scorer -> Text -> [Match Int (Entry Text uid)]
matchesWithThreshold