bloodhound-0.20.0.0: src/Database/Bloodhound/Internal/Suggest.hs
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Database.Bloodhound.Internal.Suggest where
import Bloodhound.Import
import qualified Data.Aeson.KeyMap as X
import Database.Bloodhound.Internal.Newtypes
import Database.Bloodhound.Internal.Query (Query, TemplateQueryKeyValuePairs)
import GHC.Generics
data Suggest = Suggest
{ suggestText :: Text,
suggestName :: Text,
suggestType :: SuggestType
}
deriving (Eq, Show, Generic)
instance ToJSON Suggest where
toJSON Suggest {..} =
object
[ "text" .= suggestText,
fromText suggestName .= suggestType
]
instance FromJSON Suggest where
parseJSON (Object o) = do
suggestText' <- o .: "text"
let dropTextList =
X.toList $
X.filterWithKey (\x _ -> x /= "text") o
suggestName' <-
case dropTextList of
[(x, _)] -> return x
_ -> fail "error parsing Suggest field name"
suggestType' <- o .: suggestName'
return $ Suggest suggestText' (toText suggestName') suggestType'
parseJSON x = typeMismatch "Suggest" x
data SuggestType
= SuggestTypePhraseSuggester PhraseSuggester
deriving (Eq, Show, Generic)
instance ToJSON SuggestType where
toJSON (SuggestTypePhraseSuggester x) =
object ["phrase" .= x]
instance FromJSON SuggestType where
parseJSON = withObject "SuggestType" parse
where
parse o = phraseSuggester `taggedWith` "phrase"
where
taggedWith parser k = parser =<< o .: k
phraseSuggester = pure . SuggestTypePhraseSuggester
data PhraseSuggester = PhraseSuggester
{ phraseSuggesterField :: FieldName,
phraseSuggesterGramSize :: Maybe Int,
phraseSuggesterRealWordErrorLikelihood :: Maybe Int,
phraseSuggesterConfidence :: Maybe Int,
phraseSuggesterMaxErrors :: Maybe Int,
phraseSuggesterSeparator :: Maybe Text,
phraseSuggesterSize :: Maybe Size,
phraseSuggesterAnalyzer :: Maybe Analyzer,
phraseSuggesterShardSize :: Maybe Int,
phraseSuggesterHighlight :: Maybe PhraseSuggesterHighlighter,
phraseSuggesterCollate :: Maybe PhraseSuggesterCollate,
phraseSuggesterCandidateGenerators :: [DirectGenerators]
}
deriving (Eq, Show, Generic)
instance ToJSON PhraseSuggester where
toJSON PhraseSuggester {..} =
omitNulls
[ "field" .= phraseSuggesterField,
"gram_size" .= phraseSuggesterGramSize,
"real_word_error_likelihood"
.= phraseSuggesterRealWordErrorLikelihood,
"confidence" .= phraseSuggesterConfidence,
"max_errors" .= phraseSuggesterMaxErrors,
"separator" .= phraseSuggesterSeparator,
"size" .= phraseSuggesterSize,
"analyzer" .= phraseSuggesterAnalyzer,
"shard_size" .= phraseSuggesterShardSize,
"highlight" .= phraseSuggesterHighlight,
"collate" .= phraseSuggesterCollate,
"direct_generator"
.= phraseSuggesterCandidateGenerators
]
instance FromJSON PhraseSuggester where
parseJSON = withObject "PhraseSuggester" parse
where
parse o =
PhraseSuggester
<$> o .: "field"
<*> o .:? "gram_size"
<*> o .:? "real_word_error_likelihood"
<*> o .:? "confidence"
<*> o .:? "max_errors"
<*> o .:? "separator"
<*> o .:? "size"
<*> o .:? "analyzer"
<*> o .:? "shard_size"
<*> o .:? "highlight"
<*> o .:? "collate"
<*> o .:? "direct_generator" .!= []
mkPhraseSuggester :: FieldName -> PhraseSuggester
mkPhraseSuggester fName =
PhraseSuggester
fName
Nothing
Nothing
Nothing
Nothing
Nothing
Nothing
Nothing
Nothing
Nothing
Nothing
[]
data PhraseSuggesterHighlighter = PhraseSuggesterHighlighter
{ phraseSuggesterHighlighterPreTag :: Text,
phraseSuggesterHighlighterPostTag :: Text
}
deriving (Eq, Show, Generic)
instance ToJSON PhraseSuggesterHighlighter where
toJSON PhraseSuggesterHighlighter {..} =
object
[ "pre_tag" .= phraseSuggesterHighlighterPreTag,
"post_tag" .= phraseSuggesterHighlighterPostTag
]
instance FromJSON PhraseSuggesterHighlighter where
parseJSON = withObject "PhraseSuggesterHighlighter" parse
where
parse o =
PhraseSuggesterHighlighter
<$> o .: "pre_tag"
<*> o .: "post_tag"
data PhraseSuggesterCollate = PhraseSuggesterCollate
{ phraseSuggesterCollateTemplateQuery :: Query,
phraseSuggesterCollateParams :: TemplateQueryKeyValuePairs,
phraseSuggesterCollatePrune :: Bool
}
deriving (Eq, Show, Generic)
instance ToJSON PhraseSuggesterCollate where
toJSON PhraseSuggesterCollate {..} =
object
[ "query"
.= object
[ "source" .= phraseSuggesterCollateTemplateQuery
],
"params" .= phraseSuggesterCollateParams,
"prune" .= phraseSuggesterCollatePrune
]
instance FromJSON PhraseSuggesterCollate where
parseJSON (Object o) = do
query' <- o .: "query"
inline' <- query' .: "source"
params' <- o .: "params"
prune' <- o .:? "prune" .!= False
return $ PhraseSuggesterCollate inline' params' prune'
parseJSON x = typeMismatch "PhraseSuggesterCollate" x
data SuggestOptions = SuggestOptions
{ suggestOptionsText :: Text,
suggestOptionsScore :: Double,
suggestOptionsFreq :: Maybe Int,
suggestOptionsHighlighted :: Maybe Text
}
deriving (Eq, Read, Show)
instance FromJSON SuggestOptions where
parseJSON = withObject "SuggestOptions" parse
where
parse o =
SuggestOptions
<$> o .: "text"
<*> o .: "score"
<*> o .:? "freq"
<*> o .:? "highlighted"
data SuggestResponse = SuggestResponse
{ suggestResponseText :: Text,
suggestResponseOffset :: Int,
suggestResponseLength :: Int,
suggestResponseOptions :: [SuggestOptions]
}
deriving (Eq, Read, Show)
instance FromJSON SuggestResponse where
parseJSON = withObject "SuggestResponse" parse
where
parse o =
SuggestResponse
<$> o .: "text"
<*> o .: "offset"
<*> o .: "length"
<*> o .: "options"
data NamedSuggestionResponse = NamedSuggestionResponse
{ nsrName :: Text,
nsrResponses :: [SuggestResponse]
}
deriving (Eq, Read, Show)
instance FromJSON NamedSuggestionResponse where
parseJSON (Object o) = do
suggestionName' <- case X.toList o of
[(x, _)] -> return x
_ -> fail "error parsing NamedSuggestionResponse name"
suggestionResponses' <- o .: suggestionName'
return $ NamedSuggestionResponse (toText suggestionName') suggestionResponses'
parseJSON x = typeMismatch "NamedSuggestionResponse" x
data DirectGeneratorSuggestModeTypes
= DirectGeneratorSuggestModeMissing
| DirectGeneratorSuggestModePopular
| DirectGeneratorSuggestModeAlways
deriving (Eq, Show, Generic)
instance ToJSON DirectGeneratorSuggestModeTypes where
toJSON DirectGeneratorSuggestModeMissing = "missing"
toJSON DirectGeneratorSuggestModePopular = "popular"
toJSON DirectGeneratorSuggestModeAlways = "always"
instance FromJSON DirectGeneratorSuggestModeTypes where
parseJSON = withText "DirectGeneratorSuggestModeTypes" parse
where
parse "missing" =
pure DirectGeneratorSuggestModeMissing
parse "popular" =
pure DirectGeneratorSuggestModePopular
parse "always" =
pure DirectGeneratorSuggestModeAlways
parse f =
fail ("Unexpected DirectGeneratorSuggestModeTypes: " <> show f)
data DirectGenerators = DirectGenerators
{ directGeneratorsField :: FieldName,
directGeneratorsSize :: Maybe Int,
directGeneratorSuggestMode :: DirectGeneratorSuggestModeTypes,
directGeneratorMaxEdits :: Maybe Double,
directGeneratorPrefixLength :: Maybe Int,
directGeneratorMinWordLength :: Maybe Int,
directGeneratorMaxInspections :: Maybe Int,
directGeneratorMinDocFreq :: Maybe Double,
directGeneratorMaxTermFreq :: Maybe Double,
directGeneratorPreFilter :: Maybe Text,
directGeneratorPostFilter :: Maybe Text
}
deriving (Eq, Show, Generic)
instance ToJSON DirectGenerators where
toJSON DirectGenerators {..} =
omitNulls
[ "field" .= directGeneratorsField,
"size" .= directGeneratorsSize,
"suggest_mode" .= directGeneratorSuggestMode,
"max_edits" .= directGeneratorMaxEdits,
"prefix_length" .= directGeneratorPrefixLength,
"min_word_length" .= directGeneratorMinWordLength,
"max_inspections" .= directGeneratorMaxInspections,
"min_doc_freq" .= directGeneratorMinDocFreq,
"max_term_freq" .= directGeneratorMaxTermFreq,
"pre_filter" .= directGeneratorPreFilter,
"post_filter" .= directGeneratorPostFilter
]
instance FromJSON DirectGenerators where
parseJSON = withObject "DirectGenerators" parse
where
parse o =
DirectGenerators
<$> o .: "field"
<*> o .:? "size"
<*> o .: "suggest_mode"
<*> o .:? "max_edits"
<*> o .:? "prefix_length"
<*> o .:? "min_word_length"
<*> o .:? "max_inspections"
<*> o .:? "min_doc_freq"
<*> o .:? "max_term_freq"
<*> o .:? "pre_filter"
<*> o .:? "post_filter"
mkDirectGenerators :: FieldName -> DirectGenerators
mkDirectGenerators fn =
DirectGenerators
fn
Nothing
DirectGeneratorSuggestModeMissing
Nothing
Nothing
Nothing
Nothing
Nothing
Nothing
Nothing
Nothing