@@ -180,6 +180,23 @@ module Database.V5.Bloodhound.Types
180180 , BoolQuery(..)
181181 , BoostingQuery(..)
182182 , CommonTermsQuery(..)
183+ , FunctionScoreQuery(..)
184+ , BoostMode(..)
185+ , ScoreMode(..)
186+ , FunctionScoreFunctions(..)
187+ , ComponentFunctionScoreFunction(..)
188+ , FunctionScoreFunction(..)
189+ , FunctionScoreScript(..)
190+ , FunctionScoreScriptInline(..)
191+ , FunctionScoreScriptParams(..)
192+ , FunctionScoreScriptParamName
193+ , FunctionScoreScriptParamValue
194+ , Weight(..)
195+ , Seed(..)
196+ , FieldValueFactor(..)
197+ , Factor(..)
198+ , FactorModifier(..)
199+ , FactorMissingFieldValue(..)
183200 , DisMaxQuery(..)
184201 , FuzzyLikeThisQuery(..)
185202 , FuzzyLikeFieldQuery(..)
@@ -1206,6 +1223,7 @@ data Query =
12061223 | QueryBoostingQuery BoostingQuery
12071224 | QueryCommonTermsQuery CommonTermsQuery
12081225 | ConstantScoreQuery Query Boost
1226+ | QueryFunctionScoreQuery FunctionScoreQuery
12091227 | QueryDisMaxQuery DisMaxQuery
12101228 | QueryFuzzyLikeThisQuery FuzzyLikeThisQuery
12111229 | QueryFuzzyLikeFieldQuery FuzzyLikeFieldQuery
@@ -1419,6 +1437,94 @@ data FuzzyLikeThisQuery =
14191437 , fuzzyLikeAnalyzer :: Maybe Analyzer
14201438 } deriving (Eq, Read, Show, Generic, Typeable)
14211439
1440+data FunctionScoreQuery =
1441+ FunctionScoreQuery { functionScoreQuery :: Maybe Query
1442+ , functionScoreBoost :: Maybe Boost
1443+ , functionScoreFunctions :: FunctionScoreFunctions
1444+ , functionScoreMaxBoost :: Maybe Boost
1445+ , functionScoreBoostMode :: Maybe BoostMode
1446+ , functionScoreMinScore :: Score
1447+ , functionScoreScoreMode :: Maybe ScoreMode
1448+ } deriving (Eq, Read, Show, Generic, Typeable)
1449+
1450+data BoostMode =
1451+ BoostModeMultiply
1452+ | BoostModeReplace
1453+ | BoostModeSum
1454+ | BoostModeAvg
1455+ | BoostModeMax
1456+ | BoostModeMin deriving (Eq, Read, Show, Generic, Typeable)
1457+
1458+data ScoreMode =
1459+ ScoreModeMultiply
1460+ | ScoreModeSum
1461+ | ScoreModeAvg
1462+ | ScoreModeFirst
1463+ | ScoreModeMax
1464+ | ScoreModeMin deriving (Eq, Read, Show, Generic, Typeable)
1465+
1466+data FunctionScoreFunctions =
1467+ FunctionScoreSingle FunctionScoreFunction
1468+ | FunctionScoreMultiple (NonEmpty ComponentFunctionScoreFunction) deriving (Eq, Read, Show, Generic, Typeable)
1469+
1470+data ComponentFunctionScoreFunction =
1471+ ComponentFunctionScoreFunction { componentScoreFunctionFilter :: Maybe Filter
1472+ , componentScoreFunction :: FunctionScoreFunction
1473+ , componentScoreFunctionWeight :: Maybe Weight
1474+ } deriving (Eq, Read, Show, Generic, Typeable)
1475+
1476+data FunctionScoreFunction =
1477+ FunctionScoreFunctionScript FunctionScoreScript
1478+ | FunctionScoreFunctionRandom Seed
1479+ | FunctionScoreFunctionFieldValueFactor FieldValueFactor
1480+ deriving (Eq, Read, Show, Generic, Typeable)
1481+
1482+data FunctionScoreScript =
1483+ FunctionScoreScript { functionScoreScriptInline :: FunctionScoreScriptInline
1484+ , functionScoreScriptParams :: Maybe FunctionScoreScriptParams
1485+ } deriving (Eq, Read, Show, Generic, Typeable)
1486+
1487+newtype FunctionScoreScriptInline =
1488+ FunctionScoreScriptInline Text deriving (Eq, Read, Show, Generic, Typeable, ToJSON, FromJSON)
1489+
1490+newtype FunctionScoreScriptParams =
1491+ FunctionScoreScriptParams (HM.HashMap FunctionScoreScriptParamName FunctionScoreScriptParamValue)
1492+ deriving (Eq, Read, Show, Generic, Typeable)
1493+
1494+type FunctionScoreScriptParamName = Text
1495+type FunctionScoreScriptParamValue = Value
1496+
1497+newtype Weight =
1498+ Weight Float deriving (Eq, Read, Show, Generic, Typeable, ToJSON, FromJSON)
1499+
1500+newtype Seed =
1501+ Seed Float deriving (Eq, Read, Show, Generic, Typeable, ToJSON, FromJSON)
1502+
1503+data FieldValueFactor =
1504+ FieldValueFactor { fieldValueFactorField :: FieldName
1505+ , fieldValueFactor :: Maybe Factor
1506+ , fieldValueFactorModifier :: Maybe FactorModifier
1507+ , fieldValueFactorMissing :: Maybe FactorMissingFieldValue
1508+ } deriving (Eq, Read, Show, Generic, Typeable)
1509+
1510+newtype Factor =
1511+ Factor Float deriving (Eq, Read, Show, Generic, Typeable, ToJSON, FromJSON)
1512+
1513+data FactorModifier =
1514+ FactorModifierNone
1515+ | FactorModifierLog
1516+ | FactorModifierLog1p
1517+ | FactorModifierLog2p
1518+ | FactorModifierLn
1519+ | FactorModifierLn1p
1520+ | FactorModifierLn2p
1521+ | FactorModifierSquare
1522+ | FactorModifierSqrt
1523+ | FactorModifierReciprocal deriving (Eq, Read, Show, Generic, Typeable)
1524+
1525+newtype FactorMissingFieldValue =
1526+ FactorMissingFieldValue Float deriving (Eq, Read, Show, Generic, Typeable, ToJSON, FromJSON)
1527+
14221528data DisMaxQuery =
14231529 DisMaxQuery { disMaxQueries :: [Query]
14241530 -- default 0.0
@@ -2219,6 +2325,9 @@ instance ToJSON Query where
22192325 object ["constant_score" .= object ["query" .= query
22202326 , "boost" .= boost]]
22212327
2328+ toJSON (QueryFunctionScoreQuery functionScoreQuery) =
2329+ object [ "function_score" .= functionScoreQuery ]
2330+
22222331 toJSON (QueryDisMaxQuery disMaxQuery) =
22232332 object [ "dis_max" .= disMaxQuery ]
22242333
@@ -2286,6 +2395,7 @@ instance FromJSON Query where
22862395 <|> queryBoostingQuery `taggedWith` "boosting"
22872396 <|> queryCommonTermsQuery `taggedWith` "common"
22882397 <|> constantScoreQuery `taggedWith` "constant_score"
2398+ <|> queryFunctionScoreQuery `taggedWith` "function_score"
22892399 <|> queryDisMaxQuery `taggedWith` "dis_max"
22902400 <|> queryFuzzyLikeThisQuery `taggedWith` "fuzzy_like_this"
22912401 <|> queryFuzzyLikeFieldQuery `taggedWith` "fuzzy_like_this_field"
@@ -2323,6 +2433,7 @@ instance FromJSON Query where
23232433 Just x -> ConstantScoreQuery <$> parseJSON x
23242434 <*> o .: "boost"
23252435 _ -> fail "Does not appear to be a ConstantScoreQuery"
2436+ queryFunctionScoreQuery = pure . QueryFunctionScoreQuery
23262437 queryDisMaxQuery = pure . QueryDisMaxQuery
23272438 queryFuzzyLikeThisQuery = pure . QueryFuzzyLikeThisQuery
23282439 queryFuzzyLikeFieldQuery = pure . QueryFuzzyLikeFieldQuery
@@ -2736,6 +2847,171 @@ instance FromJSON FuzzyLikeThisQuery where
27362847 <*> o .: "boost"
27372848 <*> o .:? "analyzer"
27382849
2850+instance ToJSON FunctionScoreQuery where
2851+ toJSON (FunctionScoreQuery query boost fns maxBoost boostMode minScore scoreMode) =
2852+ omitNulls base
2853+ where base = functionScoreFunctionsPair fns :
2854+ [ "query" .= query
2855+ , "boost" .= boost
2856+ , "max_boost" .= maxBoost
2857+ , "boost_mode" .= boostMode
2858+ , "min_score" .= minScore
2859+ , "score_mode" .= scoreMode ]
2860+
2861+functionScoreFunctionsPair :: FunctionScoreFunctions -> (Text, Value)
2862+functionScoreFunctionsPair (FunctionScoreSingle fn)
2863+ = functionScoreFunctionPair fn
2864+
2865+functionScoreFunctionsPair (FunctionScoreMultiple componentFns) =
2866+ ("functions", toJSON componentFns)
2867+
2868+instance FromJSON FunctionScoreQuery where
2869+ parseJSON = withObject "FunctionScoreQuery" parse
2870+ where parse o = FunctionScoreQuery
2871+ <$> o .:? "query"
2872+ <*> o .:? "boost"
2873+ <*> (singleFunction o
2874+ <|> multipleFunctions `taggedWith` "functions")
2875+ <*> o .:? "max_boost"
2876+ <*> o .:? "boost_mode"
2877+ <*> o .:? "min_score"
2878+ <*> o .:? "score_mode"
2879+ where taggedWith parser k = parser =<< o .: k
2880+ singleFunction = fmap FunctionScoreSingle . parseFunctionScoreFunction
2881+ multipleFunctions = pure . FunctionScoreMultiple
2882+
2883+instance ToJSON BoostMode where
2884+ toJSON BoostModeMultiply = "multiply"
2885+ toJSON BoostModeReplace = "replace"
2886+ toJSON BoostModeSum = "sum"
2887+ toJSON BoostModeAvg = "avg"
2888+ toJSON BoostModeMax = "max"
2889+ toJSON BoostModeMin = "min"
2890+
2891+instance FromJSON BoostMode where
2892+ parseJSON = withText "BoostMode" parse
2893+ where parse "multiply" = pure BoostModeMultiply
2894+ parse "replace" = pure BoostModeReplace
2895+ parse "sum" = pure BoostModeSum
2896+ parse "avg" = pure BoostModeAvg
2897+ parse "max" = pure BoostModeMax
2898+ parse "min" = pure BoostModeMin
2899+ parse bm = fail ("Unexpected BoostMode: " <> show bm)
2900+
2901+instance ToJSON ScoreMode where
2902+ toJSON ScoreModeMultiply = "multiply"
2903+ toJSON ScoreModeSum = "sum"
2904+ toJSON ScoreModeFirst = "first"
2905+ toJSON ScoreModeAvg = "avg"
2906+ toJSON ScoreModeMax = "max"
2907+ toJSON ScoreModeMin = "min"
2908+
2909+instance FromJSON ScoreMode where
2910+ parseJSON = withText "ScoreMode" parse
2911+ where parse "multiply" = pure ScoreModeMultiply
2912+ parse "sum" = pure ScoreModeSum
2913+ parse "first" = pure ScoreModeFirst
2914+ parse "avg" = pure ScoreModeAvg
2915+ parse "max" = pure ScoreModeMax
2916+ parse "min" = pure ScoreModeMin
2917+ parse sm = fail ("Unexpected ScoreMode: " <> show sm)
2918+
2919+instance ToJSON ComponentFunctionScoreFunction where
2920+ toJSON (ComponentFunctionScoreFunction filter fn weight) =
2921+ omitNulls base
2922+ where base = functionScoreFunctionPair fn :
2923+ [ "filter" .= filter
2924+ , "weight" .= weight ]
2925+
2926+instance FromJSON ComponentFunctionScoreFunction where
2927+ parseJSON = withObject "ComponentFunctionScoreFunction" parse
2928+ where parse o = ComponentFunctionScoreFunction
2929+ <$> o .:? "filter"
2930+ <*> parseFunctionScoreFunction o
2931+ <*> o .:? "weight"
2932+
2933+functionScoreFunctionPair :: FunctionScoreFunction -> (Text, Value)
2934+functionScoreFunctionPair (FunctionScoreFunctionScript functionScoreScript) =
2935+ ("script_score", toJSON functionScoreScript)
2936+
2937+functionScoreFunctionPair (FunctionScoreFunctionRandom seed) =
2938+ ("random_score", omitNulls [ "seed" .= seed ])
2939+
2940+functionScoreFunctionPair (FunctionScoreFunctionFieldValueFactor fieldValueFactor) =
2941+ ("field_value_factor", toJSON fieldValueFactor)
2942+
2943+parseFunctionScoreFunction :: Object -> Parser FunctionScoreFunction
2944+parseFunctionScoreFunction o =
2945+ singleScript `taggedWith` "script_score"
2946+ <|> singleRandom `taggedWith` "random_score"
2947+ <|> singleFieldValueFactor `taggedWith` "field_value_factor"
2948+ where taggedWith parser k = parser =<< o .: k
2949+ singleScript = pure . FunctionScoreFunctionScript
2950+ singleRandom o' = FunctionScoreFunctionRandom <$> o' .: "seed"
2951+ singleFieldValueFactor = pure . FunctionScoreFunctionFieldValueFactor
2952+
2953+instance ToJSON FunctionScoreScript where
2954+ toJSON (FunctionScoreScript inline params) =
2955+ object [ "script" .= omitNulls base ]
2956+ where base = [ "inline" .= inline
2957+ , "params" .= params ]
2958+
2959+instance FromJSON FunctionScoreScript where
2960+ parseJSON = withObject "FunctionScoreScript" parse
2961+ where parse o = o .: "script" >>= \o' ->
2962+ FunctionScoreScript
2963+ <$> o' .: "inline"
2964+ <*> o' .:? "params"
2965+
2966+instance ToJSON FunctionScoreScriptParams where
2967+ toJSON (FunctionScoreScriptParams x) = Object x
2968+
2969+instance FromJSON FunctionScoreScriptParams where
2970+ parseJSON (Object o) = pure (FunctionScoreScriptParams o)
2971+ parseJSON _ = fail "error parsing FunctionScoreScriptParams"
2972+
2973+instance ToJSON FieldValueFactor where
2974+ toJSON (FieldValueFactor field factor modifier missing) =
2975+ omitNulls base
2976+ where base = [ "field" .= field
2977+ , "factor" .= factor
2978+ , "modifier" .= modifier
2979+ , "missing" .= missing ]
2980+
2981+instance FromJSON FieldValueFactor where
2982+ parseJSON = withObject "FieldValueFactor" parse
2983+ where parse o = FieldValueFactor
2984+ <$> o .: "field"
2985+ <*> o .:? "factor"
2986+ <*> o .:? "modifier"
2987+ <*> o .:? "missing"
2988+
2989+instance ToJSON FactorModifier where
2990+ toJSON FactorModifierNone = "none"
2991+ toJSON FactorModifierLog = "log"
2992+ toJSON FactorModifierLog1p = "log1p"
2993+ toJSON FactorModifierLog2p = "log2p"
2994+ toJSON FactorModifierLn = "ln"
2995+ toJSON FactorModifierLn1p = "ln1p"
2996+ toJSON FactorModifierLn2p = "ln2p"
2997+ toJSON FactorModifierSquare = "square"
2998+ toJSON FactorModifierSqrt = "sqrt"
2999+ toJSON FactorModifierReciprocal = "reciprocal"
3000+
3001+instance FromJSON FactorModifier where
3002+ parseJSON = withText "FactorModifier" parse
3003+ where parse "none" = pure FactorModifierNone
3004+ parse "log" = pure FactorModifierLog
3005+ parse "log1p" = pure FactorModifierLog1p
3006+ parse "log2p" = pure FactorModifierLog2p
3007+ parse "ln" = pure FactorModifierLn
3008+ parse "ln1p" = pure FactorModifierLn1p
3009+ parse "ln2p" = pure FactorModifierLn2p
3010+ parse "square" = pure FactorModifierSquare
3011+ parse "sqrt" = pure FactorModifierSqrt
3012+ parse "reciprocal" = pure FactorModifierReciprocal
3013+ parse fm = fail ("Unexpected FactorModifier: " <> show fm)
3014+
27393015instance ToJSON DisMaxQuery where
27403016 toJSON (DisMaxQuery queries tiebreaker boost) =
27413017 omitNulls base