module Holumbus.Query.Ranking
(
RankConfig (..)
, DocRanking
, WordRanking
, rank
, docRankByCount
, docRankWeightedByCount
, wordRankByCount
, wordRankWeightedByCount
)
where
import Prelude hiding (foldr)
import Data.Function
import Data.Foldable
import qualified Data.List as L
import qualified Data.Map as M
import Holumbus.Query.Result
import Holumbus.Index.Common
data RankConfig a = RankConfig
{ docRanking :: DocRanking a
, wordRanking :: WordRanking
}
type DocRanking a = DocId -> DocInfo a -> DocContextHits -> Score
type WordRanking = Word -> WordInfo -> WordContextHits -> Score
rank :: RankConfig a -> Result a -> Result a
rank (RankConfig fd fw ) r
= Result scoredDocHits scoredWordHits
where
scoredDocHits = mapWithKeyDocIdMap (\k (di, dch) -> (setDocScore (fd k di dch) di, dch)) $
docHits r
scoredWordHits = M.mapWithKey (\k (wi, wch) -> (setWordScore (fw k wi wch) wi, wch)) $
wordHits r
docRankByCount :: DocId -> DocInfo a -> DocContextHits -> Score
docRankByCount _ _ h = fromIntegral $
M.fold (\h1 r1 -> M.fold (\h2 r2 -> sizePos h2 + r2) r1 h1) 0 h
wordRankByCount :: Word -> WordInfo -> WordContextHits -> Score
wordRankByCount _ _ h = fromIntegral $ M.fold (\h1 r1 -> foldDocIdMap ((+) . sizePos) r1 h1) 0 h
docRankWeightedByCount :: [(Context, Score)] -> DocId -> DocInfo a -> DocContextHits -> Score
docRankWeightedByCount ws _ _ h
= M.foldrWithKey (calcWeightedScore ws) 0.0 h
wordRankWeightedByCount :: [(Context, Score)] -> Word -> WordInfo -> WordContextHits -> Score
wordRankWeightedByCount ws _ _ h
= M.foldrWithKey (calcWeightedScore ws) 0.0 h
calcWeightedScore :: (Foldable f) =>
[(Context, Score)] -> Context -> (f Positions) -> Score -> Score
calcWeightedScore ws c h r
= maybe r (\w -> r + ((w / mw) * count)) $
lookupWeight c ws
where
count = fromIntegral $
foldl' (flip $ (+) . sizePos) 0 h
mw = snd $
L.maximumBy (compare `on` snd) ws
lookupWeight :: Context -> [(Context, Score)] -> Maybe Score
lookupWeight _ [] = Nothing
lookupWeight c (x:xs) = if fst x == c
then if snd x /= 0.0
then Just (snd x)
else Nothing
else lookupWeight c xs