@@ -1,4 +1,5 @@
11{-# LANGUAGE DeriveGeneric #-}
2+{-# LANGUAGE RecordWildCards #-}
23
34{-| Data types for describing actions and data structures performed to interact
45 with Elasticsearch. The two main buckets your queries against Elasticsearch
@@ -150,7 +151,6 @@ import Data.Aeson
150151import qualified Data.ByteString.Lazy.Char8 as L
151152import Data.List (nub)
152153import Data.List.NonEmpty (NonEmpty(..))
153−import Data.Maybe (catMaybes)
154154import Data.Monoid
155155import Data.Text (Text)
156156import qualified Data.Text as T
@@ -158,7 +158,6 @@ import Data.Time.Clock (UTCTime)
158158import GHC.Generics (Generic)
159159import Network.HTTP.Client
160160import qualified Network.HTTP.Types.Method as NHTM
161−import Prelude hiding (filter)
162161
163162import Database.Bloodhound.Types.Class
164163
@@ -968,9 +967,9 @@ instance ToJSON Filter where
968967 object ["or" .= fmap toJSON filters
969968 , "_cache" .= cache]
970969
971− toJSON (NotFilter filter cache) =
970+ toJSON (NotFilter notFilter cache) =
972971 object ["not" .=
973− object ["filter" .= toJSON filter
972+ object ["filter" .= toJSON notFilter
974973 , "_cache" .= cache]]
975974
976975 toJSON (IdentityFilter) =
@@ -1104,8 +1103,8 @@ instance ToJSON Query where
11041103 toJSON (QueryCommonTermsQuery commonTermsQuery) =
11051104 object [ "common" .= toJSON commonTermsQuery ]
11061105
1107− toJSON (ConstantScoreFilter filter boost) =
1108− object [ "constant_score" .= toJSON filter
1106+ toJSON (ConstantScoreFilter csFilter boost) =
1107+ object [ "constant_score" .= toJSON csFilter
11091108 , "boost" .= toJSON boost]
11101109
11111110 toJSON (ConstantScoreQuery query boost) =
@@ -1137,8 +1136,7 @@ instance ToJSON Query where
11371136 object [ "indices" .= toJSON qIndicesQuery ]
11381137
11391138 toJSON (MatchAllQuery boost) =
1140− object [ "match_all" .= object maybeAdd ]
1141− where maybeAdd = catMaybes [ mField "boost" boost ]
1139+ object [ "match_all" .= omitNulls [ "boost" .= boost ] ]
11421140
11431141 toJSON (QueryMoreLikeThisQuery query) =
11441142 object [ "more_like_this" .= toJSON query ]
@@ -1162,23 +1160,23 @@ instance ToJSON Query where
11621160 object [ "simple_query_string" .= toJSON query ]
11631161
11641162
1165−mField :: (ToJSON a, Functor f) => T.Text -> f a -> f (T.Text, Value)
1166−mField field = fmap ((field .=) . toJSON)
1163+omitNulls :: [(Text, Value)] -> Value
1164+omitNulls = object . filter notNull where
1165+ notNull (_, Null) = False
1166+ notNull _ = True
1167+
11671168
11681169instance ToJSON SimpleQueryStringQuery where
1169− toJSON (SimpleQueryStringQuery sqsQueryString
1170− sqsFields sqsBoolean sqsAnalyzer
1171− sqsFlags sqsLowercaseExpanded sqsLocale) =
1172− object conjoined
1173− where base = [ "query" .= toJSON sqsQueryString ]
1174− maybeAdd =
1175− catMaybes [ mField "fields" sqsFields
1176− , mField "default_operator" sqsBoolean
1177− , mField "analyzer" sqsAnalyzer
1178− , mField "flags" sqsFlags
1179− , mField "lowercase_expanded_terms" sqsLowercaseExpanded
1180− , mField "locale" sqsLocale ]
1181− conjoined = base ++ maybeAdd
1170+ toJSON SimpleQueryStringQuery {..} =
1171+ omitNulls (base ++ maybeAdd)
1172+ where base = [ "query" .= toJSON simpleQueryStringQuery ]
1173+ maybeAdd = [ "fields" .= simpleQueryStringField
1174+ , "default_operator" .= simpleQueryStringOperator
1175+ , "analyzer" .= simpleQueryStringAnalyzer
1176+ , "flags" .= simpleQueryStringFlags
1177+ , "lowercase_expanded_terms" .= simpleQueryStringLowercaseExpanded
1178+ , "locale" .= simpleQueryStringLocale ]
1179+
11821180
11831181instance ToJSON FieldOrFields where
11841182 toJSON (FofField fieldName) =
@@ -1200,15 +1198,16 @@ instance ToJSON SimpleQueryFlag where
12001198 toJSON SimpleQueryNear = "NEAR"
12011199 toJSON SimpleQuerySlop = "SLOP"
12021200
1201+
12031202instance ToJSON RegexpQuery where
12041203 toJSON (RegexpQuery (FieldName rqQueryField)
12051204 (Regexp regexpQueryQuery) rqQueryFlags
12061205 rqQueryBoost) =
1207− object [ rqQueryField .= object conjoined ]
1206+ object [ rqQueryField .= omitNulls base ]
12081207 where base = [ "value" .= regexpQueryQuery
1209− , "flags" .= toJSON rqQueryFlags ]
1210− maybeAdd = catMaybes [ mField "boost" rqQueryBoost ]
1211− conjoined = base ++ maybeAdd
1208+ , "flags" .= toJSON rqQueryFlags
1209+ , "boost" .= rqQueryBoost ]
1210+
12121211
12131212instance ToJSON QueryStringQuery where
12141213 toJSON (QueryStringQuery qsQueryString
@@ -1220,27 +1219,26 @@ instance ToJSON QueryStringQuery where
12201219 qsBoost qsAnalyzeWildcard
12211220 qsGeneratePhraseQueries qsMinimumShouldMatch
12221221 qsLenient qsLocale) =
1223− object conjoined
1222+ omitNulls base
12241223 where
1225− base = [ "query" .= toJSON qsQueryString ]
1226− maybeAdd =
1227− catMaybes [ mField "default_field" qsDefaultField
1228− , mField "default_operator" qsOperator
1229− , mField "analyzer" qsAnalyzer
1230− , mField "allow_leading_wildcard" qsAllowWildcard
1231− , mField "lowercase_expanded_terms" qsLowercaseExpanded
1232− , mField "enable_position_increments" qsEnablePositionIncrements
1233− , mField "fuzzy_max_expansions" qsFuzzyMaxExpansions
1234− , mField "fuzziness" qsFuzziness
1235− , mField "fuzzy_prefix_length" qsFuzzyPrefixLength
1236− , mField "phrase_slop" qsPhraseSlop
1237− , mField "boost" qsBoost
1238− , mField "analyze_wildcard" qsAnalyzeWildcard
1239− , mField "auto_generate_phrase_queries" qsGeneratePhraseQueries
1240− , mField "minimum_should_match" qsMinimumShouldMatch
1241− , mField "lenient" qsLenient
1242− , mField "locale" qsLocale ]
1243− conjoined = base ++ maybeAdd
1224+ base = [ "query" .= toJSON qsQueryString
1225+ , "default_field" .= qsDefaultField
1226+ , "default_operator" .= qsOperator
1227+ , "analyzer" .= qsAnalyzer
1228+ , "allow_leading_wildcard" .= qsAllowWildcard
1229+ , "lowercase_expanded_terms" .= qsLowercaseExpanded
1230+ , "enable_position_increments" .= qsEnablePositionIncrements
1231+ , "fuzzy_max_expansions" .= qsFuzzyMaxExpansions
1232+ , "fuzziness" .= qsFuzziness
1233+ , "fuzzy_prefix_length" .= qsFuzzyPrefixLength
1234+ , "phrase_slop" .= qsPhraseSlop
1235+ , "boost" .= qsBoost
1236+ , "analyze_wildcard" .= qsAnalyzeWildcard
1237+ , "auto_generate_phrase_queries" .= qsGeneratePhraseQueries
1238+ , "minimum_should_match" .= qsMinimumShouldMatch
1239+ , "lenient" .= qsLenient
1240+ , "locale" .= qsLocale ]
1241+
12441242
12451243instance ToJSON RangeQuery where
12461244 toJSON (RangeQuery (FieldName fieldName) (Right range) boost) =
@@ -1256,12 +1254,12 @@ instance ToJSON RangeQuery where
12561254 , key .= val ]
12571255 (key, val) = halfRangeToKV halfRange
12581256
1257+
12591258instance ToJSON PrefixQuery where
12601259 toJSON (PrefixQuery (FieldName fieldName) queryValue boost) =
1261− object [ fieldName .= object conjoined ]
1262− where base = [ "value" .= toJSON queryValue ]
1263− maybeAdd = catMaybes [ mField "boost" boost ]
1264− conjoined = base ++ maybeAdd
1260+ object [ fieldName .= omitNulls base ]
1261+ where base = [ "value" .= toJSON queryValue
1262+ , "boost" .= boost ]
12651263
12661264
12671265instance ToJSON NestedQuery where
@@ -1275,135 +1273,128 @@ instance ToJSON MoreLikeThisFieldQuery where
12751273 toJSON (MoreLikeThisFieldQuery text (FieldName fieldName)
12761274 percent mtf mqt stopwords mindf maxdf
12771275 minwl maxwl boostTerms boost analyzer) =
1278− object [ fieldName .= object conjoined ]
1279− where base = [ "like_text" .= toJSON text ]
1280− maybeAdd = catMaybes [ mField "percent_terms_to_match" percent
1281− , mField "min_term_freq" mtf
1282− , mField "max_query_terms" mqt
1283− , mField "stop_words" stopwords
1284− , mField "min_doc_freq" mindf
1285− , mField "max_doc_freq" maxdf
1286− , mField "min_word_length" minwl
1287− , mField "max_word_length" maxwl
1288− , mField "boost_terms" boostTerms
1289− , mField "boost" boost
1290− , mField "analyzer" analyzer ]
1291− conjoined = base ++ maybeAdd
1276+ object [ fieldName .= omitNulls base ]
1277+ where base = [ "like_text" .= toJSON text
1278+ , "percent_terms_to_match" .= percent
1279+ , "min_term_freq" .= mtf
1280+ , "max_query_terms" .= mqt
1281+ , "stop_words" .= stopwords
1282+ , "min_doc_freq" .= mindf
1283+ , "max_doc_freq" .= maxdf
1284+ , "min_word_length" .= minwl
1285+ , "max_word_length" .= maxwl
1286+ , "boost_terms" .= boostTerms
1287+ , "boost" .= boost
1288+ , "analyzer" .= analyzer ]
12921289
12931290
12941291instance ToJSON MoreLikeThisQuery where
12951292 toJSON (MoreLikeThisQuery text fields percent
12961293 mtf mqt stopwords mindf maxdf
12971294 minwl maxwl boostTerms boost analyzer) =
1298− object conjoined
1299− where base = [ "like_text" .= toJSON text ]
1300− maybeAdd = catMaybes [ mField "fields" fields
1301− , mField "percent_terms_to_match" percent
1302− , mField "min_term_freq" mtf
1303− , mField "max_query_terms" mqt
1304− , mField "stop_words" stopwords
1305− , mField "min_doc_freq" mindf
1306− , mField "max_doc_freq" maxdf
1307− , mField "min_word_length" minwl
1308− , mField "max_word_length" maxwl
1309− , mField "boost_terms" boostTerms
1310− , mField "boost" boost
1311− , mField "analyzer" analyzer ]
1312− conjoined = base ++ maybeAdd
1295+ omitNulls base
1296+ where base = [ "like_text" .= toJSON text
1297+ , "fields" .= fields
1298+ , "percent_terms_to_match" .= percent
1299+ , "min_term_freq" .= mtf
1300+ , "max_query_terms" .= mqt
1301+ , "stop_words" .= stopwords
1302+ , "min_doc_freq" .= mindf
1303+ , "max_doc_freq" .= maxdf
1304+ , "min_word_length" .= minwl
1305+ , "max_word_length" .= maxwl
1306+ , "boost_terms" .= boostTerms
1307+ , "boost" .= boost
1308+ , "analyzer" .= analyzer ]
13131309
13141310
13151311instance ToJSON IndicesQuery where
13161312 toJSON (IndicesQuery indices query noMatch) =
1317− object $ [ "indices" .= toJSON indices
1318− , "query" .= toJSON query ] ++ maybeAdd
1319− where maybeAdd = catMaybes [ mField "no_match_query" noMatch ]
1313+ omitNulls [ "indices" .= toJSON indices
1314+ , "no_match_query" .= toJSON noMatch
1315+ , "query" .= toJSON query ]
13201316
13211317
13221318instance ToJSON HasParentQuery where
13231319 toJSON (HasParentQuery queryType query scoreType) =
1324− object $ [ "parent_type" .= toJSON queryType
1325− , "query" .= toJSON query ] ++ maybeAdd
1326− where maybeAdd = catMaybes [ mField "score_type" scoreType ]
1320+ omitNulls [ "parent_type" .= toJSON queryType
1321+ , "score_type" .= toJSON scoreType
1322+ , "query" .= toJSON query ]
13271323
13281324
13291325instance ToJSON HasChildQuery where
13301326 toJSON (HasChildQuery queryType query scoreType) =
1331− object $ [ "query" .= toJSON query
1332− , "type" .= toJSON queryType ] ++ maybeAdd
1333− where maybeAdd = catMaybes [ mField "score_type" scoreType ]
1327+ omitNulls [ "query" .= toJSON query
1328+ , "score_type" .= toJSON scoreType
1329+ , "type" .= toJSON queryType ]
13341330
13351331
13361332instance ToJSON FuzzyQuery where
13371333 toJSON (FuzzyQuery (FieldName fieldName) queryText
13381334 prefixLength maxEx fuzziness boost) =
1339− object [ fieldName .= object conjoined ]
1335+ object [ fieldName .= omitNulls base ]
13401336 where base = [ "value" .= toJSON queryText
13411337 , "fuzziness" .= toJSON fuzziness
13421338 , "prefix_length" .= toJSON prefixLength
1339+ , "boost" .= toJSON boost
13431340 , "max_expansions" .= toJSON maxEx ]
1344− maybeAdd = catMaybes [ mField "boost" boost ]
1345− conjoined = base ++ maybeAdd
13461341
13471342
13481343instance ToJSON FuzzyLikeFieldQuery where
13491344 toJSON (FuzzyLikeFieldQuery (FieldName fieldName)
13501345 fieldText maxTerms ignoreFreq fuzziness prefixLength
13511346 boost analyzer) =
1352− object $ [ fieldName .=
1353− object [ "like_text" .= toJSON fieldText
1354− , "max_query_terms" .= toJSON maxTerms
1355− , "ignore_tf" .= toJSON ignoreFreq
1356− , "fuzziness" .= toJSON fuzziness
1357− , "prefix_length" .= toJSON prefixLength
1358− , "boost" .= toJSON boost ]] ++ maybeAdd
1359− where maybeAdd = catMaybes [ mField "analyzer" analyzer ]
1347+ object [ fieldName .=
1348+ omitNulls [ "like_text" .= toJSON fieldText
1349+ , "max_query_terms" .= toJSON maxTerms
1350+ , "ignore_tf" .= toJSON ignoreFreq
1351+ , "fuzziness" .= toJSON fuzziness
1352+ , "prefix_length" .= toJSON prefixLength
1353+ , "analyzer" .= toJSON analyzer
1354+ , "boost" .= toJSON boost ]]
13601355
13611356
13621357instance ToJSON FuzzyLikeThisQuery where
13631358 toJSON (FuzzyLikeThisQuery fields text maxTerms
13641359 ignoreFreq fuzziness prefixLength boost analyzer) =
1365− object conjoined
1360+ omitNulls base
13661361 where base = [ "fields" .= toJSON fields
13671362 , "like_text" .= toJSON text
13681363 , "max_query_terms" .= toJSON maxTerms
13691364 , "ignore_tf" .= toJSON ignoreFreq
13701365 , "fuzziness" .= toJSON fuzziness
13711366 , "prefix_length" .= toJSON prefixLength
1367+ , "analyzer" .= toJSON analyzer
13721368 , "boost" .= toJSON boost ]
1373− maybeAdd = catMaybes [ mField "analyzer" analyzer ]
1374− conjoined = base ++ maybeAdd
13751369
13761370
13771371instance ToJSON FilteredQuery where
1378− toJSON (FilteredQuery query filter) =
1372+ toJSON (FilteredQuery query fFilter) =
13791373 object [ "query" .= toJSON query
1380− , "filter" .= toJSON filter ]
1374+ , "filter" .= toJSON fFilter ]
13811375
13821376
13831377instance ToJSON DisMaxQuery where
13841378 toJSON (DisMaxQuery queries tiebreaker boost) =
1385− object conjoined
1386− where maybeAdd = catMaybes [mField "boost" boost]
1387− base = [ "queries" .= toJSON queries
1379+ omitNulls base
1380+ where base = [ "queries" .= toJSON queries
1381+ , "boost" .= toJSON boost
13881382 , "tie_breaker" .= toJSON tiebreaker ]
1389− conjoined = base ++ maybeAdd
13901383
13911384
13921385instance ToJSON CommonTermsQuery where
13931386 toJSON (CommonTermsQuery (FieldName fieldName)
13941387 (QueryString query) cf lfo hfo msm
13951388 boost analyzer disableCoord) =
1396− object [fieldName .= object conjoined]
1397− where base = [ "query" .= query
1389+ object [fieldName .= omitNulls base ]
1390+ where base = [ "query" .= toJSON query
13981391 , "cutoff_frequency" .= toJSON cf
13991392 , "low_freq_operator" .= toJSON lfo
1393+ , "minimum_should_match" .= toJSON msm
1394+ , "boost" .= toJSON boost
1395+ , "analyzer" .= toJSON analyzer
1396+ , "disable_coord" .= toJSON disableCoord
14001397 , "high_freq_operator" .= toJSON hfo ]
1401− extension = catMaybes
1402− [ mField "minimum_should_match" msm
1403− , mField "boost" boost
1404− , mField "analyzer" analyzer
1405− , mField "disable_coord" disableCoord ]
1406− conjoined = base ++ extension
14071398
14081399
14091400instance ToJSON CommonMinimumMatch where
@@ -1421,14 +1412,13 @@ instance ToJSON BoostingQuery where
14211412
14221413instance ToJSON BoolQuery where
14231414 toJSON (BoolQuery mustM notM shouldM bqMin boost disableCoord) =
1424− object filtered
1425− where filtered = catMaybes
1426− [ mField "must" mustM
1427− , mField "must_not" notM
1428− , mField "should" shouldM
1429− , mField "minimum_should_match" bqMin
1430− , mField "boost" boost
1431− , mField "disable_coord" disableCoord ]
1415+ omitNulls base
1416+ where base = [ "must" .= toJSON mustM
1417+ , "must_not" .= toJSON notM
1418+ , "should" .= toJSON shouldM
1419+ , "minimum_should_match" .= toJSON bqMin
1420+ , "boost" .= toJSON boost
1421+ , "disable_coord" .= toJSON disableCoord ]
14321422
14331423
14341424instance ToJSON MatchQuery where
@@ -1436,33 +1426,31 @@ instance ToJSON MatchQuery where
14361426 (QueryString mqQueryString) booleanOperator
14371427 zeroTermsQuery cutoffFrequency matchQueryType
14381428 analyzer maxExpansions lenient) =
1439− object [ fieldName .= object conjoined ]
1440− where conjoined = [ "query" .= mqQueryString
1441− , "operator" .= toJSON booleanOperator
1442− , "zero_terms_query" .= toJSON zeroTermsQuery]
1443− ++ maybeAdd
1444− maybeAdd = catMaybes [ mField "cutoff_frequency" cutoffFrequency
1445− , mField "type" matchQueryType
1446− , mField "analyzer" analyzer
1447− , mField "max_expansions" maxExpansions
1448− , mField "lenient" lenient ]
1429+ object [ fieldName .= omitNulls base ]
1430+ where base = [ "query" .= mqQueryString
1431+ , "operator" .= toJSON booleanOperator
1432+ , "zero_terms_query" .= toJSON zeroTermsQuery
1433+ , "cutoff_frequency" .= toJSON cutoffFrequency
1434+ , "type" .= toJSON matchQueryType
1435+ , "analyzer" .= toJSON analyzer
1436+ , "max_expansions" .= toJSON maxExpansions
1437+ , "lenient" .= toJSON lenient ]
14491438
14501439
14511440instance ToJSON MultiMatchQuery where
14521441 toJSON (MultiMatchQuery fields (QueryString query) boolOp
14531442 ztQ tb mmqt cf analyzer maxEx lenient) =
1454− object ["multi_match" .= object conjoined]
1455− where baseQuery = [ "fields" .= fmap toJSON fields
1456− , "query" .= query
1457− , "operator" .= toJSON boolOp
1458− , "zero_terms_query" .= toJSON ztQ ]
1459− maybeAdd = catMaybes [ mField "tiebreaker" tb
1460− , mField "type" mmqt
1461− , mField "cutoff_frequency" cf
1462− , mField "analyzer" analyzer
1463− , mField "max_expansions" maxEx
1464− , mField "lenient" lenient ]
1465− conjoined = baseQuery ++ maybeAdd
1443+ object ["multi_match" .= omitNulls base]
1444+ where base = [ "fields" .= fmap toJSON fields
1445+ , "query" .= query
1446+ , "operator" .= toJSON boolOp
1447+ , "zero_terms_query" .= toJSON ztQ
1448+ , "tiebreaker" .= toJSON tb
1449+ , "type" .= toJSON mmqt
1450+ , "cutoff_frequency" .= toJSON cf
1451+ , "analyzer" .= toJSON analyzer
1452+ , "max_expansions" .= toJSON maxEx
1453+ , "lenient" .= toJSON lenient ]
14661454
14671455
14681456instance ToJSON MultiMatchQueryType where
@@ -1555,10 +1543,10 @@ instance (FromJSON a) => FromJSON (EsResult a) where
15551543
15561544
15571545instance ToJSON Search where
1558− toJSON (Search query filter sort sTrackSortScores sFrom sSize) =
1546+ toJSON (Search query sFilter sort sTrackSortScores sFrom sSize) =
15591547 object merged where
15601548 lQuery = maybeJson "query" query
1561− lFilter = maybeJson "filter" filter
1549+ lFilter = maybeJson "filter" sFilter
15621550 lSort = maybeJsonF "sort" sort
15631551 merged = mconcat [[ "from" .= sFrom
15641552 , "size" .= sSize