@@ -414,7 +414,6 @@ module Database.V5.Bloodhound.Types
414414
415415import Bloodhound.Import
416416
417−import qualified Data.Traversable as DT
418417import qualified Data.HashMap.Strict as HM
419418import qualified Data.Map.Strict as M
420419import qualified Data.Text as T
@@ -424,7 +423,6 @@ import Database.V5.Bloodhound.Internal.Analysis
424423import Database.V5.Bloodhound.Internal.Client
425424import Database.V5.Bloodhound.Internal.Newtypes
426425import Database.V5.Bloodhound.Internal.Query
427−import Database.V5.Bloodhound.Internal.StringlyTyped
428426
429427{-| 'Sort' is a synonym for a list of 'SortSpec's. Sort behavior is order
430428 dependent with later sorts acting as tie-breakers for earlier sorts.
@@ -438,8 +436,26 @@ type Sort = [SortSpec]
438436
439437<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
440438-}
441−data SortSpec = DefaultSortSpec DefaultSort
442− | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit deriving (Eq, Show)
439+data SortSpec =
440+ DefaultSortSpec DefaultSort
441+ | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit
442+ deriving (Eq, Show)
443+
444+instance ToJSON SortSpec where
445+ toJSON (DefaultSortSpec
446+ (DefaultSort (FieldName dsSortFieldName) dsSortOrder dsIgnoreUnmapped
447+ dsSortMode dsMissingSort dsNestedFilter)) =
448+ object [dsSortFieldName .= omitNulls base] where
449+ base = [ "order" .= dsSortOrder
450+ , "unmapped_type" .= dsIgnoreUnmapped
451+ , "mode" .= dsSortMode
452+ , "missing" .= dsMissingSort
453+ , "nested_filter" .= dsNestedFilter ]
454+
455+ toJSON (GeoDistanceSortSpec gdsSortOrder (GeoPoint (FieldName field) gdsLatLon) units) =
456+ object [ "unit" .= units
457+ , field .= gdsLatLon
458+ , "order" .= gdsSortOrder ]
443459
444460{-| 'DefaultSort' is usually the kind of 'SortSpec' you'll want. There's a
445461 'mkSort' convenience function for when you want to specify only the most
@@ -466,6 +482,10 @@ data DefaultSort =
466482data SortOrder = Ascending
467483 | Descending deriving (Eq, Show)
468484
485+instance ToJSON SortOrder where
486+ toJSON Ascending = String "asc"
487+ toJSON Descending = String "desc"
488+
469489{-| 'Missing' prescribes how to handle missing fields. A missing field can be
470490 sorted last, first, or using a custom value as a substitute.
471491
@@ -475,6 +495,11 @@ data Missing = LastMissing
475495 | FirstMissing
476496 | CustomMissing Text deriving (Eq, Show)
477497
498+instance ToJSON Missing where
499+ toJSON LastMissing = String "_last"
500+ toJSON FirstMissing = String "_first"
501+ toJSON (CustomMissing txt) = String txt
502+
478503{-| 'SortMode' prescribes how to handle sorting array/multi-valued fields.
479504
480505http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_sort_mode_option
@@ -484,6 +509,12 @@ data SortMode = SortMin
484509 | SortSum
485510 | SortAvg deriving (Eq, Show)
486511
512+instance ToJSON SortMode where
513+ toJSON SortMin = String "min"
514+ toJSON SortMax = String "max"
515+ toJSON SortSum = String "sum"
516+ toJSON SortAvg = String "avg"
517+
487518{-| 'mkSort' defaults everything but the 'FieldName' and the 'SortOrder' so
488519 that you can concisely describe the usual kind of 'SortSpec's you want.
489520-}
@@ -590,6 +621,10 @@ data HighlightEncoder = DefaultEncoder
590621 | HTMLEncoder
591622 deriving (Eq, Show)
592623
624+instance ToJSON HighlightEncoder where
625+ toJSON DefaultEncoder = String "default"
626+ toJSON HTMLEncoder = String "html"
627+
593628-- NOTE: Should the tags use some kind of HTML type, rather than Text?
594629data HighlightTag =
595630 TagSchema Text
@@ -609,6 +644,18 @@ data SearchResult a =
609644 }
610645 deriving (Eq, Show)
611646
647+
648+instance (FromJSON a) => FromJSON (SearchResult a) where
649+ parseJSON (Object v) = SearchResult <$>
650+ v .: "took" <*>
651+ v .: "timed_out" <*>
652+ v .: "_shards" <*>
653+ v .: "hits" <*>
654+ v .:? "aggregations" <*>
655+ v .:? "_scroll_id" <*>
656+ v .:? "suggest"
657+ parseJSON _ = empty
658+
612659newtype ScrollId =
613660 ScrollId Text
614661 deriving (Eq, Show, Ord, ToJSON, FromJSON)
@@ -618,6 +665,14 @@ data SearchHits a =
618665 , maxScore :: Score
619666 , hits :: [Hit a] } deriving (Eq, Show)
620667
668+
669+instance (FromJSON a) => FromJSON (SearchHits a) where
670+ parseJSON (Object v) = SearchHits <$>
671+ v .: "total" <*>
672+ v .: "max_score" <*>
673+ v .: "hits"
674+ parseJSON _ = empty
675+
621676instance Semigroup (SearchHits a) where
622677 (SearchHits ta ma ha) <> (SearchHits tb mb hb) = SearchHits (ta + tb) (max ma mb) (ha <> hb)
623678
@@ -634,12 +689,26 @@ data Hit a =
634689 , hitFields :: Maybe HitFields
635690 , hitHighlight :: Maybe HitHighlight } deriving (Eq, Show)
636691
692+instance (FromJSON a) => FromJSON (Hit a) where
693+ parseJSON (Object v) = Hit <$>
694+ v .: "_index" <*>
695+ v .: "_type" <*>
696+ v .: "_id" <*>
697+ v .: "_score" <*>
698+ v .:? "_source" <*>
699+ v .:? "fields" <*>
700+ v .:? "highlight"
701+ parseJSON _ = empty
702+
637703newtype HitFields =
638704 HitFields (M.Map Text [Value])
639705 deriving (Eq, Show)
640706
641−type HitHighlight = M.Map Text [Text]
707+instance FromJSON HitFields where
708+ parseJSON x
709+ = HitFields <$> parseJSON x
642710
711+type HitHighlight = M.Map Text [Text]
643712
644713type Aggregations = M.Map Text Aggregation
645714
@@ -649,21 +718,43 @@ emptyAggregations = M.empty
649718mkAggregations :: Text -> Aggregation -> Aggregations
650719mkAggregations name aggregation = M.insert name aggregation emptyAggregations
651720
652−data TermOrder = TermOrder{ termSortField :: Text
653− , termSortOrder :: SortOrder } deriving (Eq, Show)
721+data TermOrder = TermOrder
722+ { termSortField :: Text
723+ , termSortOrder :: SortOrder } deriving (Eq, Show)
724+
725+instance ToJSON TermOrder where
726+ toJSON (TermOrder termSortField termSortOrder) =
727+ object [termSortField .= termSortOrder]
654728
655729data TermInclusion = TermInclusion Text
656730 | TermPattern Text Text deriving (Eq, Show)
657731
732+instance ToJSON TermInclusion where
733+ toJSON (TermInclusion x) = toJSON x
734+ toJSON (TermPattern pattern flags) =
735+ omitNulls [ "pattern" .= pattern
736+ , "flags" .= flags]
737+
658738data CollectionMode = BreadthFirst
659739 | DepthFirst deriving (Eq, Show)
660740
741+instance ToJSON CollectionMode where
742+ toJSON BreadthFirst = "breadth_first"
743+ toJSON DepthFirst = "depth_first"
744+
661745data ExecutionHint = Ordinals
662746 | GlobalOrdinals
663747 | GlobalOrdinalsHash
664748 | GlobalOrdinalsLowCardinality
665749 | Map deriving (Eq, Show)
666750
751+instance ToJSON ExecutionHint where
752+ toJSON Ordinals = "ordinals"
753+ toJSON GlobalOrdinals = "global_ordinals"
754+ toJSON GlobalOrdinalsHash = "global_ordinals_hash"
755+ toJSON GlobalOrdinalsLowCardinality = "global_ordinals_low_cardinality"
756+ toJSON Map = "map"
757+
667758data Aggregation = TermsAgg TermsAggregation
668759 | CardinalityAgg CardinalityAggregation
669760 | DateHistogramAgg DateHistogramAggregation
@@ -675,6 +766,67 @@ data Aggregation = TermsAgg TermsAggregation
675766 | StatsAgg StatisticsAggregation
676767 deriving (Eq, Show)
677768
769+instance ToJSON Aggregation where
770+ toJSON (TermsAgg (TermsAggregation term include exclude order minDocCount size shardSize collectMode executionHint termAggs)) =
771+ omitNulls ["terms" .= omitNulls [ toJSON' term,
772+ "include" .= include,
773+ "exclude" .= exclude,
774+ "order" .= order,
775+ "min_doc_count" .= minDocCount,
776+ "size" .= size,
777+ "shard_size" .= shardSize,
778+ "collect_mode" .= collectMode,
779+ "execution_hint" .= executionHint
780+ ],
781+ "aggs" .= termAggs ]
782+ where
783+ toJSON' x = case x of { Left y -> "field" .= y; Right y -> "script" .= y }
784+
785+ toJSON (CardinalityAgg (CardinalityAggregation field precisionThreshold)) =
786+ object ["cardinality" .= omitNulls [ "field" .= field,
787+ "precisionThreshold" .= precisionThreshold
788+ ]
789+ ]
790+
791+ toJSON (DateHistogramAgg
792+ (DateHistogramAggregation field interval format
793+ preZone postZone preOffset postOffset dateHistoAggs)) =
794+ omitNulls ["date_histogram" .= omitNulls [ "field" .= field,
795+ "interval" .= interval,
796+ "format" .= format,
797+ "pre_zone" .= preZone,
798+ "post_zone" .= postZone,
799+ "pre_offset" .= preOffset,
800+ "post_offset" .= postOffset
801+ ],
802+ "aggs" .= dateHistoAggs ]
803+ toJSON (ValueCountAgg a) = object ["value_count" .= v]
804+ where v = case a of
805+ (FieldValueCount (FieldName n)) ->
806+ object ["field" .= n]
807+ (ScriptValueCount s) ->
808+ object ["script" .= s]
809+ toJSON (FilterAgg (FilterAggregation filt ags)) =
810+ omitNulls [ "filter" .= filt
811+ , "aggs" .= ags]
812+ toJSON (DateRangeAgg a) = object [ "date_range" .= a
813+ ]
814+ toJSON (MissingAgg (MissingAggregation{..})) =
815+ object ["missing" .= object ["field" .= maField]]
816+
817+ toJSON (TopHitsAgg (TopHitsAggregation mfrom msize msort)) =
818+ omitNulls ["top_hits" .= omitNulls [ "size" .= msize
819+ , "from" .= mfrom
820+ , "sort" .= msort
821+ ]
822+ ]
823+
824+ toJSON (StatsAgg (StatisticsAggregation typ field)) =
825+ object [stType .= omitNulls [ "field" .= field ]]
826+ where
827+ stType | typ == Basic = "stats"
828+ | otherwise = "extended_stats"
829+
678830data TopHitsAggregation = TopHitsAggregation
679831 { taFrom :: Maybe From
680832 , taSize :: Maybe Size
@@ -685,17 +837,18 @@ data MissingAggregation = MissingAggregation
685837 { maField :: Text
686838 } deriving (Eq, Show)
687839
688−data TermsAggregation = TermsAggregation { term :: Either Text Text
689− , termInclude :: Maybe TermInclusion
690− , termExclude :: Maybe TermInclusion
691− , termOrder :: Maybe TermOrder
692− , termMinDocCount :: Maybe Int
693− , termSize :: Maybe Int
694− , termShardSize :: Maybe Int
695− , termCollectMode :: Maybe CollectionMode
696− , termExecutionHint :: Maybe ExecutionHint
697− , termAggs :: Maybe Aggregations
698− } deriving (Eq, Show)
840+data TermsAggregation = TermsAggregation
841+ { term :: Either Text Text
842+ , termInclude :: Maybe TermInclusion
843+ , termExclude :: Maybe TermInclusion
844+ , termOrder :: Maybe TermOrder
845+ , termMinDocCount :: Maybe Int
846+ , termSize :: Maybe Int
847+ , termShardSize :: Maybe Int
848+ , termCollectMode :: Maybe CollectionMode
849+ , termExecutionHint :: Maybe ExecutionHint
850+ , termAggs :: Maybe Aggregations
851+ } deriving (Eq, Show)
699852
700853data CardinalityAggregation = CardinalityAggregation
701854 { cardinalityField :: FieldName,
@@ -720,17 +873,43 @@ data DateRangeAggregation = DateRangeAggregation
720873 , draRanges :: NonEmpty DateRangeAggRange
721874 } deriving (Eq, Show)
722875
876+instance ToJSON DateRangeAggregation where
877+ toJSON DateRangeAggregation {..} =
878+ omitNulls [ "field" .= draField
879+ , "format" .= draFormat
880+ , "ranges" .= toList draRanges
881+ ]
882+
723883data DateRangeAggRange =
724884 DateRangeFrom DateMathExpr
725885 | DateRangeTo DateMathExpr
726886 | DateRangeFromAndTo DateMathExpr DateMathExpr
727887 deriving (Eq, Show)
728888
889+instance ToJSON DateRangeAggRange where
890+ toJSON (DateRangeFrom e) = object [ "from" .= e ]
891+ toJSON (DateRangeTo e) = object [ "to" .= e ]
892+ toJSON (DateRangeFromAndTo f t) = object [ "from" .= f, "to" .= t ]
893+
729894-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math> for more information.
730895data DateMathExpr =
731896 DateMathExpr DateMathAnchor [DateMathModifier]
732897 deriving (Eq, Show)
733898
899+instance ToJSON DateMathExpr where
900+ toJSON (DateMathExpr a mods) = String (fmtA a <> mconcat (fmtMod <$> mods))
901+ where fmtA DMNow = "now"
902+ fmtA (DMDate date) = (T.pack $ showGregorian date) <> "||"
903+ fmtMod (AddTime n u) = "+" <> showText n <> fmtU u
904+ fmtMod (SubtractTime n u) = "-" <> showText n <> fmtU u
905+ fmtMod (RoundDownTo u) = "/" <> fmtU u
906+ fmtU DMYear = "y"
907+ fmtU DMMonth = "M"
908+ fmtU DMWeek = "w"
909+ fmtU DMDay = "d"
910+ fmtU DMHour = "h"
911+ fmtU DMMinute = "m"
912+ fmtU DMSecond = "s"
734913
735914-- | Starting point for a date range. This along with the 'DateMathModifiers' gets you the date ES will start from.
736915data DateMathAnchor =
@@ -796,124 +975,6 @@ mkStatsAggregation = StatisticsAggregation Basic
796975mkExtendedStatsAggregation :: FieldName -> StatisticsAggregation
797976mkExtendedStatsAggregation = StatisticsAggregation Extended
798977
799−instance ToJSON TermOrder where
800− toJSON (TermOrder termSortField termSortOrder) = object [termSortField .= termSortOrder]
801−
802−instance ToJSON TermInclusion where
803− toJSON (TermInclusion x) = toJSON x
804− toJSON (TermPattern pattern flags) = omitNulls [ "pattern" .= pattern,
805− "flags" .= flags]
806−
807−instance ToJSON CollectionMode where
808− toJSON BreadthFirst = "breadth_first"
809− toJSON DepthFirst = "depth_first"
810−
811−instance ToJSON ExecutionHint where
812− toJSON Ordinals = "ordinals"
813− toJSON GlobalOrdinals = "global_ordinals"
814− toJSON GlobalOrdinalsHash = "global_ordinals_hash"
815− toJSON GlobalOrdinalsLowCardinality = "global_ordinals_low_cardinality"
816− toJSON Map = "map"
817−
818−instance ToJSON Interval where
819− toJSON Year = "year"
820− toJSON Quarter = "quarter"
821− toJSON Month = "month"
822− toJSON Week = "week"
823− toJSON Day = "day"
824− toJSON Hour = "hour"
825− toJSON Minute = "minute"
826− toJSON Second = "second"
827−
828−instance ToJSON Aggregation where
829− toJSON (TermsAgg (TermsAggregation term include exclude order minDocCount size shardSize collectMode executionHint termAggs)) =
830− omitNulls ["terms" .= omitNulls [ toJSON' term,
831− "include" .= include,
832− "exclude" .= exclude,
833− "order" .= order,
834− "min_doc_count" .= minDocCount,
835− "size" .= size,
836− "shard_size" .= shardSize,
837− "collect_mode" .= collectMode,
838− "execution_hint" .= executionHint
839− ],
840− "aggs" .= termAggs ]
841− where
842− toJSON' x = case x of { Left y -> "field" .= y; Right y -> "script" .= y }
843−
844− toJSON (CardinalityAgg (CardinalityAggregation field precisionThreshold)) =
845− object ["cardinality" .= omitNulls [ "field" .= field,
846− "precisionThreshold" .= precisionThreshold
847− ]
848− ]
849−
850− toJSON (DateHistogramAgg
851− (DateHistogramAggregation field interval format
852− preZone postZone preOffset postOffset dateHistoAggs)) =
853− omitNulls ["date_histogram" .= omitNulls [ "field" .= field,
854− "interval" .= interval,
855− "format" .= format,
856− "pre_zone" .= preZone,
857− "post_zone" .= postZone,
858− "pre_offset" .= preOffset,
859− "post_offset" .= postOffset
860− ],
861− "aggs" .= dateHistoAggs ]
862− toJSON (ValueCountAgg a) = object ["value_count" .= v]
863− where v = case a of
864− (FieldValueCount (FieldName n)) ->
865− object ["field" .= n]
866− (ScriptValueCount s) ->
867− object ["script" .= s]
868− toJSON (FilterAgg (FilterAggregation filt ags)) =
869− omitNulls [ "filter" .= filt
870− , "aggs" .= ags]
871− toJSON (DateRangeAgg a) = object [ "date_range" .= a
872− ]
873− toJSON (MissingAgg (MissingAggregation{..})) =
874− object ["missing" .= object ["field" .= maField]]
875−
876− toJSON (TopHitsAgg (TopHitsAggregation mfrom msize msort)) =
877− omitNulls ["top_hits" .= omitNulls [ "size" .= msize
878− , "from" .= mfrom
879− , "sort" .= msort
880− ]
881− ]
882−
883− toJSON (StatsAgg (StatisticsAggregation typ field)) =
884− object [stType .= omitNulls [ "field" .= field ]]
885− where
886− stType | typ == Basic = "stats"
887− | otherwise = "extended_stats"
888−
889−instance ToJSON DateRangeAggregation where
890− toJSON DateRangeAggregation {..} =
891− omitNulls [ "field" .= draField
892− , "format" .= draFormat
893− , "ranges" .= toList draRanges
894− ]
895−
896−instance ToJSON DateRangeAggRange where
897− toJSON (DateRangeFrom e) = object [ "from" .= e ]
898− toJSON (DateRangeTo e) = object [ "to" .= e ]
899− toJSON (DateRangeFromAndTo f t) = object [ "from" .= f, "to" .= t ]
900−
901−instance ToJSON DateMathExpr where
902− toJSON (DateMathExpr a mods) = String (fmtA a <> mconcat (fmtMod <$> mods))
903− where fmtA DMNow = "now"
904− fmtA (DMDate date) = (T.pack $ showGregorian date) <> "||"
905− fmtMod (AddTime n u) = "+" <> showText n <> fmtU u
906− fmtMod (SubtractTime n u) = "-" <> showText n <> fmtU u
907− fmtMod (RoundDownTo u) = "/" <> fmtU u
908− fmtU DMYear = "y"
909− fmtU DMMonth = "M"
910− fmtU DMWeek = "w"
911− fmtU DMDay = "d"
912− fmtU DMHour = "h"
913− fmtU DMMinute = "m"
914− fmtU DMSecond = "s"
915−
916−
917978type AggregationResults = M.Map Text Value
918979
919980class BucketAggregation a where
@@ -921,83 +982,48 @@ class BucketAggregation a where
921982 docCount :: a -> Int
922983 aggs :: a -> Maybe AggregationResults
923984
924−
925−data Bucket a = Bucket { buckets :: [a]} deriving (Read, Show)
926−
927−data BucketValue = TextValue Text
928− | ScientificValue Scientific
929− | BoolValue Bool deriving (Read, Show)
930−
931−data MissingResult = MissingResult { missingDocCount :: Int } deriving (Show)
932−
933−data TopHitResult a = TopHitResult { tarHits :: (SearchHits a)
934− } deriving Show
935−
936−data TermsResult = TermsResult { termKey :: BucketValue
937− , termsDocCount :: Int
938− , termsAggs :: Maybe AggregationResults } deriving (Read, Show)
939−
940−data DateHistogramResult = DateHistogramResult { dateKey :: Int
941− , dateKeyStr :: Maybe Text
942− , dateDocCount :: Int
943− , dateHistogramAggs :: Maybe AggregationResults } deriving (Read, Show)
944−
945−data DateRangeResult =
946− DateRangeResult { dateRangeKey :: Text
947− , dateRangeFrom :: Maybe UTCTime
948− , dateRangeFromAsString :: Maybe Text
949− , dateRangeTo :: Maybe UTCTime
950− , dateRangeToAsString :: Maybe Text
951− , dateRangeDocCount :: Int
952− , dateRangeAggs :: Maybe AggregationResults }
953− deriving (Eq, Show)
954−
955−toTerms :: Text -> AggregationResults -> Maybe (Bucket TermsResult)
956−toTerms = toAggResult
957−
958−toDateHistogram :: Text -> AggregationResults -> Maybe (Bucket DateHistogramResult)
959−toDateHistogram = toAggResult
960−
961−toMissing :: Text -> AggregationResults -> Maybe MissingResult
962−toMissing = toAggResult
963−
964−toTopHits :: (FromJSON a) => Text -> AggregationResults -> Maybe (TopHitResult a)
965−toTopHits = toAggResult
966−
967−toAggResult :: (FromJSON a) => Text -> AggregationResults -> Maybe a
968−toAggResult t a = M.lookup t a >>= deserialize
969− where deserialize = parseMaybe parseJSON
970−
971−instance BucketAggregation TermsResult where
972− key = termKey
973− docCount = termsDocCount
974− aggs = termsAggs
975−
976−instance BucketAggregation DateHistogramResult where
977− key = TextValue . showText . dateKey
978− docCount = dateDocCount
979− aggs = dateHistogramAggs
980−
981−instance BucketAggregation DateRangeResult where
982− key = TextValue . dateRangeKey
983− docCount = dateRangeDocCount
984− aggs = dateRangeAggs
985+data Bucket a = Bucket
986+ { buckets :: [a]
987+ } deriving (Read, Show)
985988
986989instance (FromJSON a) => FromJSON (Bucket a) where
987990 parseJSON (Object v) = Bucket <$>
988991 v .: "buckets"
989992 parseJSON _ = mempty
990993
994+data BucketValue = TextValue Text
995+ | ScientificValue Scientific
996+ | BoolValue Bool deriving (Read, Show)
997+
991998instance FromJSON BucketValue where
992999 parseJSON (String t) = return $ TextValue t
9931000 parseJSON (Number s) = return $ ScientificValue s
9941001 parseJSON (Bool b) = return $ BoolValue b
9951002 parseJSON _ = mempty
9961003
1004+data MissingResult = MissingResult
1005+ { missingDocCount :: Int
1006+ } deriving (Show)
1007+
9971008instance FromJSON MissingResult where
9981009 parseJSON = withObject "MissingResult" parse
9991010 where parse v = MissingResult <$> v .: "doc_count"
10001011
1012+data TopHitResult a = TopHitResult
1013+ { tarHits :: (SearchHits a)
1014+ } deriving Show
1015+
1016+instance (FromJSON a) => FromJSON (TopHitResult a) where
1017+ parseJSON (Object v) = TopHitResult <$>
1018+ v .: "hits"
1019+ parseJSON _ = fail "Failure in FromJSON (TopHitResult a)"
1020+
1021+data TermsResult = TermsResult
1022+ { termKey :: BucketValue
1023+ , termsDocCount :: Int
1024+ , termsAggs :: Maybe AggregationResults
1025+ } deriving (Read, Show)
1026+
10011027instance FromJSON TermsResult where
10021028 parseJSON (Object v) = TermsResult <$>
10031029 v .: "key" <*>
@@ -1005,6 +1031,18 @@ instance FromJSON TermsResult where
10051031 (pure $ getNamedSubAgg v ["key", "doc_count"])
10061032 parseJSON _ = mempty
10071033
1034+instance BucketAggregation TermsResult where
1035+ key = termKey
1036+ docCount = termsDocCount
1037+ aggs = termsAggs
1038+
1039+data DateHistogramResult = DateHistogramResult
1040+ { dateKey :: Int
1041+ , dateKeyStr :: Maybe Text
1042+ , dateDocCount :: Int
1043+ , dateHistogramAggs :: Maybe AggregationResults
1044+ } deriving (Show)
1045+
10081046instance FromJSON DateHistogramResult where
10091047 parseJSON (Object v) = DateHistogramResult <$>
10101048 v .: "key" <*>
@@ -1017,6 +1055,21 @@ instance FromJSON DateHistogramResult where
10171055 )
10181056 parseJSON _ = mempty
10191057
1058+instance BucketAggregation DateHistogramResult where
1059+ key = TextValue . showText . dateKey
1060+ docCount = dateDocCount
1061+ aggs = dateHistogramAggs
1062+
1063+data DateRangeResult = DateRangeResult
1064+ { dateRangeKey :: Text
1065+ , dateRangeFrom :: Maybe UTCTime
1066+ , dateRangeFromAsString :: Maybe Text
1067+ , dateRangeTo :: Maybe UTCTime
1068+ , dateRangeToAsString :: Maybe Text
1069+ , dateRangeDocCount :: Int
1070+ , dateRangeAggs :: Maybe AggregationResults
1071+ } deriving (Eq, Show)
1072+
10201073instance FromJSON DateRangeResult where
10211074 parseJSON = withObject "DateRangeResult" parse
10221075 where parse v = DateRangeResult <$>
@@ -1035,10 +1088,26 @@ instance FromJSON DateRangeResult where
10351088 ]
10361089 )
10371090
1038−instance (FromJSON a) => FromJSON (TopHitResult a) where
1039− parseJSON (Object v) = TopHitResult <$>
1040− v .: "hits"
1041− parseJSON _ = fail "Failure in FromJSON (TopHitResult a)"
1091+instance BucketAggregation DateRangeResult where
1092+ key = TextValue . dateRangeKey
1093+ docCount = dateRangeDocCount
1094+ aggs = dateRangeAggs
1095+
1096+toTerms :: Text -> AggregationResults -> Maybe (Bucket TermsResult)
1097+toTerms = toAggResult
1098+
1099+toDateHistogram :: Text -> AggregationResults -> Maybe (Bucket DateHistogramResult)
1100+toDateHistogram = toAggResult
1101+
1102+toMissing :: Text -> AggregationResults -> Maybe MissingResult
1103+toMissing = toAggResult
1104+
1105+toTopHits :: (FromJSON a) => Text -> AggregationResults -> Maybe (TopHitResult a)
1106+toTopHits = toAggResult
1107+
1108+toAggResult :: (FromJSON a) => Text -> AggregationResults -> Maybe a
1109+toAggResult t a = M.lookup t a >>= deserialize
1110+ where deserialize = parseMaybe parseJSON
10421111
10431112-- Try to get an AggregationResults when we don't know the
10441113-- field name. We filter out the known keys to try to minimize the noise.
@@ -1049,339 +1118,6 @@ getNamedSubAgg o knownKeys = maggRes
10491118 | HM.null unknownKeys = Nothing
10501119 | otherwise = Just . M.fromList $ HM.toList unknownKeys
10511120
1052−instance ToJSON GeoPoint where
1053− toJSON (GeoPoint (FieldName geoPointField) geoPointLatLon) =
1054− object [ geoPointField .= geoPointLatLon ]
1055−
1056−instance FromJSON Status where
1057− parseJSON (Object v) = Status <$>
1058− v .: "name" <*>
1059− v .: "cluster_name" <*>
1060− v .: "cluster_uuid" <*>
1061− v .: "version" <*>
1062− v .: "tagline"
1063− parseJSON _ = empty
1064−
1065−instance ToJSON IndexSettings where
1066− toJSON (IndexSettings s r) = object ["settings" .=
1067− object ["index" .=
1068− object ["number_of_shards" .= s, "number_of_replicas" .= r]
1069− ]
1070− ]
1071−
1072−instance FromJSON IndexSettings where
1073− parseJSON = withObject "IndexSettings" parse
1074− where parse o = do s <- o .: "settings"
1075− i <- s .: "index"
1076− IndexSettings <$> i .: "number_of_shards"
1077− <*> i .: "number_of_replicas"
1078−
1079−instance ToJSON UpdatableIndexSetting where
1080− toJSON (NumberOfReplicas x) = oPath ("index" :| ["number_of_replicas"]) x
1081− toJSON (AutoExpandReplicas x) = oPath ("index" :| ["auto_expand_replicas"]) x
1082− toJSON (RefreshInterval x) = oPath ("index" :| ["refresh_interval"]) (NominalDiffTimeJSON x)
1083− toJSON (IndexConcurrency x) = oPath ("index" :| ["concurrency"]) x
1084− toJSON (FailOnMergeFailure x) = oPath ("index" :| ["fail_on_merge_failure"]) x
1085− toJSON (TranslogFlushThresholdOps x) = oPath ("index" :| ["translog", "flush_threshold_ops"]) x
1086− toJSON (TranslogFlushThresholdSize x) = oPath ("index" :| ["translog", "flush_threshold_size"]) x
1087− toJSON (TranslogFlushThresholdPeriod x) = oPath ("index" :| ["translog", "flush_threshold_period"]) (NominalDiffTimeJSON x)
1088− toJSON (TranslogDisableFlush x) = oPath ("index" :| ["translog", "disable_flush"]) x
1089− toJSON (CacheFilterMaxSize x) = oPath ("index" :| ["cache", "filter", "max_size"]) x
1090− toJSON (CacheFilterExpire x) = oPath ("index" :| ["cache", "filter", "expire"]) (NominalDiffTimeJSON <$> x)
1091− toJSON (GatewaySnapshotInterval x) = oPath ("index" :| ["gateway", "snapshot_interval"]) (NominalDiffTimeJSON x)
1092− toJSON (RoutingAllocationInclude fs) = oPath ("index" :| ["routing", "allocation", "include"]) (attrFilterJSON fs)
1093− toJSON (RoutingAllocationExclude fs) = oPath ("index" :| ["routing", "allocation", "exclude"]) (attrFilterJSON fs)
1094− toJSON (RoutingAllocationRequire fs) = oPath ("index" :| ["routing", "allocation", "require"]) (attrFilterJSON fs)
1095− toJSON (RoutingAllocationEnable x) = oPath ("index" :| ["routing", "allocation", "enable"]) x
1096− toJSON (RoutingAllocationShardsPerNode x) = oPath ("index" :| ["routing", "allocation", "total_shards_per_node"]) x
1097− toJSON (RecoveryInitialShards x) = oPath ("index" :| ["recovery", "initial_shards"]) x
1098− toJSON (GCDeletes x) = oPath ("index" :| ["gc_deletes"]) (NominalDiffTimeJSON x)
1099− toJSON (TTLDisablePurge x) = oPath ("index" :| ["ttl", "disable_purge"]) x
1100− toJSON (TranslogFSType x) = oPath ("index" :| ["translog", "fs", "type"]) x
1101− toJSON (CompressionSetting x) = oPath ("index" :| ["codec"]) x
1102− toJSON (IndexCompoundFormat x) = oPath ("index" :| ["compound_format"]) x
1103− toJSON (IndexCompoundOnFlush x) = oPath ("index" :| ["compound_on_flush"]) x
1104− toJSON (WarmerEnabled x) = oPath ("index" :| ["warmer", "enabled"]) x
1105− toJSON (BlocksReadOnly x) = oPath ("blocks" :| ["read_only"]) x
1106− toJSON (BlocksRead x) = oPath ("blocks" :| ["read"]) x
1107− toJSON (BlocksWrite x) = oPath ("blocks" :| ["write"]) x
1108− toJSON (BlocksMetaData x) = oPath ("blocks" :| ["metadata"]) x
1109− toJSON (MappingTotalFieldsLimit x) = oPath ("index" :| ["mapping","total_fields","limit"]) x
1110− toJSON (AnalysisSetting x) = oPath ("index" :| ["analysis"]) x
1111−
1112−instance FromJSON UpdatableIndexSetting where
1113− parseJSON = withObject "UpdatableIndexSetting" parse
1114− where parse o = numberOfReplicas `taggedAt` ["index", "number_of_replicas"]
1115− <|> autoExpandReplicas `taggedAt` ["index", "auto_expand_replicas"]
1116− <|> refreshInterval `taggedAt` ["index", "refresh_interval"]
1117− <|> indexConcurrency `taggedAt` ["index", "concurrency"]
1118− <|> failOnMergeFailure `taggedAt` ["index", "fail_on_merge_failure"]
1119− <|> translogFlushThresholdOps `taggedAt` ["index", "translog", "flush_threshold_ops"]
1120− <|> translogFlushThresholdSize `taggedAt` ["index", "translog", "flush_threshold_size"]
1121− <|> translogFlushThresholdPeriod `taggedAt` ["index", "translog", "flush_threshold_period"]
1122− <|> translogDisableFlush `taggedAt` ["index", "translog", "disable_flush"]
1123− <|> cacheFilterMaxSize `taggedAt` ["index", "cache", "filter", "max_size"]
1124− <|> cacheFilterExpire `taggedAt` ["index", "cache", "filter", "expire"]
1125− <|> gatewaySnapshotInterval `taggedAt` ["index", "gateway", "snapshot_interval"]
1126− <|> routingAllocationInclude `taggedAt` ["index", "routing", "allocation", "include"]
1127− <|> routingAllocationExclude `taggedAt` ["index", "routing", "allocation", "exclude"]
1128− <|> routingAllocationRequire `taggedAt` ["index", "routing", "allocation", "require"]
1129− <|> routingAllocationEnable `taggedAt` ["index", "routing", "allocation", "enable"]
1130− <|> routingAllocationShardsPerNode `taggedAt` ["index", "routing", "allocation", "total_shards_per_node"]
1131− <|> recoveryInitialShards `taggedAt` ["index", "recovery", "initial_shards"]
1132− <|> gcDeletes `taggedAt` ["index", "gc_deletes"]
1133− <|> ttlDisablePurge `taggedAt` ["index", "ttl", "disable_purge"]
1134− <|> translogFSType `taggedAt` ["index", "translog", "fs", "type"]
1135− <|> compressionSetting `taggedAt` ["index", "codec"]
1136− <|> compoundFormat `taggedAt` ["index", "compound_format"]
1137− <|> compoundOnFlush `taggedAt` ["index", "compound_on_flush"]
1138− <|> warmerEnabled `taggedAt` ["index", "warmer", "enabled"]
1139− <|> blocksReadOnly `taggedAt` ["blocks", "read_only"]
1140− <|> blocksRead `taggedAt` ["blocks", "read"]
1141− <|> blocksWrite `taggedAt` ["blocks", "write"]
1142− <|> blocksMetaData `taggedAt` ["blocks", "metadata"]
1143− <|> mappingTotalFieldsLimit `taggedAt` ["index", "mapping", "total_fields", "limit"]
1144− <|> analysisSetting `taggedAt` ["index", "analysis"]
1145− where taggedAt f ks = taggedAt' f (Object o) ks
1146− taggedAt' f v [] = f =<< (parseJSON v <|> (parseJSON (unStringlyTypeJSON v)))
1147− taggedAt' f v (k:ks) = withObject "Object" (\o -> do v' <- o .: k
1148− taggedAt' f v' ks) v
1149− numberOfReplicas = pure . NumberOfReplicas
1150− autoExpandReplicas = pure . AutoExpandReplicas
1151− refreshInterval = pure . RefreshInterval . ndtJSON
1152− indexConcurrency = pure . IndexConcurrency
1153− failOnMergeFailure = pure . FailOnMergeFailure
1154− translogFlushThresholdOps = pure . TranslogFlushThresholdOps
1155− translogFlushThresholdSize = pure . TranslogFlushThresholdSize
1156− translogFlushThresholdPeriod = pure . TranslogFlushThresholdPeriod . ndtJSON
1157− translogDisableFlush = pure . TranslogDisableFlush
1158− cacheFilterMaxSize = pure . CacheFilterMaxSize
1159− cacheFilterExpire = pure . CacheFilterExpire . fmap ndtJSON
1160− gatewaySnapshotInterval = pure . GatewaySnapshotInterval . ndtJSON
1161− routingAllocationInclude = fmap RoutingAllocationInclude . parseAttrFilter
1162− routingAllocationExclude = fmap RoutingAllocationExclude . parseAttrFilter
1163− routingAllocationRequire = fmap RoutingAllocationRequire . parseAttrFilter
1164− routingAllocationEnable = pure . RoutingAllocationEnable
1165− routingAllocationShardsPerNode = pure . RoutingAllocationShardsPerNode
1166− recoveryInitialShards = pure . RecoveryInitialShards
1167− gcDeletes = pure . GCDeletes . ndtJSON
1168− ttlDisablePurge = pure . TTLDisablePurge
1169− translogFSType = pure . TranslogFSType
1170− compressionSetting = pure . CompressionSetting
1171− compoundFormat = pure . IndexCompoundFormat
1172− compoundOnFlush = pure . IndexCompoundOnFlush
1173− warmerEnabled = pure . WarmerEnabled
1174− blocksReadOnly = pure . BlocksReadOnly
1175− blocksRead = pure . BlocksRead
1176− blocksWrite = pure . BlocksWrite
1177− blocksMetaData = pure . BlocksMetaData
1178− mappingTotalFieldsLimit = pure . MappingTotalFieldsLimit
1179− analysisSetting = pure . AnalysisSetting
1180−
1181−instance FromJSON IndexSettingsSummary where
1182− parseJSON = withObject "IndexSettingsSummary" parse
1183− where parse o = case HM.toList o of
1184− [(ixn, v@(Object o'))] -> IndexSettingsSummary (IndexName ixn)
1185− <$> parseJSON v
1186− <*> (fmap (filter (not . redundant)) . parseSettings =<< o' .: "settings")
1187− _ -> fail "Expected single-key object with index name"
1188− redundant (NumberOfReplicas _) = True
1189− redundant _ = False
1190−
1191−
1192−parseSettings :: Object -> Parser [UpdatableIndexSetting]
1193−parseSettings o = do
1194− o' <- o .: "index"
1195− -- slice the index object into singleton hashmaps and try to parse each
1196− parses <- forM (HM.toList o') $ \(k, v) -> do
1197− -- blocks are now nested into the "index" key, which is not how they're serialized
1198− let atRoot = Object (HM.singleton k v)
1199− let atIndex = Object (HM.singleton "index" atRoot)
1200− optional (parseJSON atRoot <|> parseJSON atIndex)
1201− return (catMaybes parses)
1202−
1203−oPath :: ToJSON a => NonEmpty Text -> a -> Value
1204−oPath (k :| []) v = object [k .= v]
1205−oPath (k:| (h:t)) v = object [k .= oPath (h :| t) v]
1206−
1207−attrFilterJSON :: NonEmpty NodeAttrFilter -> Value
1208−attrFilterJSON fs = object [ n .= T.intercalate "," (toList vs)
1209− | NodeAttrFilter (NodeAttrName n) vs <- toList fs]
1210−
1211−parseAttrFilter :: Value -> Parser (NonEmpty NodeAttrFilter)
1212−parseAttrFilter = withObject "NonEmpty NodeAttrFilter" parse
1213− where parse o = case HM.toList o of
1214− [] -> fail "Expected non-empty list of NodeAttrFilters"
1215− x:xs -> DT.mapM (uncurry parse') (x :| xs)
1216− parse' n = withText "Text" $ \t ->
1217− case T.splitOn "," t of
1218− fv:fvs -> return (NodeAttrFilter (NodeAttrName n) (fv :| fvs))
1219− [] -> fail "Expected non-empty list of filter values"
1220−
1221−instance ToJSON ReplicaBounds where
1222− toJSON (ReplicasBounded a b) = String (showText a <> "-" <> showText b)
1223− toJSON (ReplicasLowerBounded a) = String (showText a <> "-all")
1224− toJSON ReplicasUnbounded = Bool False
1225−
1226−instance FromJSON ReplicaBounds where
1227− parseJSON v = withText "ReplicaBounds" parseText v
1228− <|> withBool "ReplicaBounds" parseBool v
1229− where parseText t = case T.splitOn "-" t of
1230− [a, "all"] -> ReplicasLowerBounded <$> parseReadText a
1231− [a, b] -> ReplicasBounded <$> parseReadText a
1232− <*> parseReadText b
1233− _ -> fail ("Could not parse ReplicaBounds: " <> show t)
1234− parseBool False = pure ReplicasUnbounded
1235− parseBool _ = fail "ReplicasUnbounded cannot be represented with True"
1236−
1237−instance ToJSON AllocationPolicy where
1238− toJSON AllocAll = String "all"
1239− toJSON AllocPrimaries = String "primaries"
1240− toJSON AllocNewPrimaries = String "new_primaries"
1241− toJSON AllocNone = String "none"
1242−
1243−instance FromJSON AllocationPolicy where
1244− parseJSON = withText "AllocationPolicy" parse
1245− where parse "all" = pure AllocAll
1246− parse "primaries" = pure AllocPrimaries
1247− parse "new_primaries" = pure AllocNewPrimaries
1248− parse "none" = pure AllocNone
1249− parse t = fail ("Invlaid AllocationPolicy: " <> show t)
1250−
1251−instance ToJSON InitialShardCount where
1252− toJSON QuorumShards = String "quorum"
1253− toJSON QuorumMinus1Shards = String "quorum-1"
1254− toJSON FullShards = String "full"
1255− toJSON FullMinus1Shards = String "full-1"
1256− toJSON (ExplicitShards x) = toJSON x
1257−
1258−instance FromJSON InitialShardCount where
1259− parseJSON v = withText "InitialShardCount" parseText v
1260− <|> ExplicitShards <$> parseJSON v
1261− where parseText "quorum" = pure QuorumShards
1262− parseText "quorum-1" = pure QuorumMinus1Shards
1263− parseText "full" = pure FullShards
1264− parseText "full-1" = pure FullMinus1Shards
1265− parseText _ = mzero
1266−
1267−instance ToJSON FSType where
1268− toJSON FSSimple = "simple"
1269− toJSON FSBuffered = "buffered"
1270−
1271−instance FromJSON FSType where
1272− parseJSON = withText "FSType" parse
1273− where parse "simple" = pure FSSimple
1274− parse "buffered" = pure FSBuffered
1275− parse t = fail ("Invalid FSType: " <> show t)
1276−
1277−instance ToJSON CompoundFormat where
1278− toJSON (CompoundFileFormat x) = Bool x
1279− toJSON (MergeSegmentVsTotalIndex x) = toJSON x
1280−
1281−instance FromJSON CompoundFormat where
1282− parseJSON v = CompoundFileFormat <$> parseJSON v
1283− <|> MergeSegmentVsTotalIndex <$> parseJSON v
1284−
1285−instance ToJSON NominalDiffTimeJSON where
1286− toJSON (NominalDiffTimeJSON t) = String (showText (round t :: Integer) <> "s")
1287−
1288−instance FromJSON NominalDiffTimeJSON where
1289− parseJSON = withText "NominalDiffTime" parse
1290− where parse t = case T.takeEnd 1 t of
1291− "s" -> NominalDiffTimeJSON . fromInteger <$> parseReadText (T.dropEnd 1 t)
1292− _ -> fail "Invalid or missing NominalDiffTime unit (expected s)"
1293−
1294−instance ToJSON IndexTemplate where
1295− toJSON (IndexTemplate p s m) = merge
1296− (object [ "template" .= p
1297− , "mappings" .= foldl' merge (object []) m
1298− ])
1299− (toJSON s)
1300− where
1301− merge (Object o1) (Object o2) = toJSON $ HM.union o1 o2
1302− merge o Null = o
1303− merge _ _ = undefined
1304−
1305−instance (FromJSON a) => FromJSON (EsResult a) where
1306− parseJSON jsonVal@(Object v) = do
1307− found <- v .:? "found" .!= False
1308− fr <- if found
1309− then parseJSON jsonVal
1310− else return Nothing
1311− EsResult <$> v .: "_index" <*>
1312− v .: "_type" <*>
1313− v .: "_id" <*>
1314− pure fr
1315− parseJSON _ = empty
1316−
1317−instance (FromJSON a) => FromJSON (EsResultFound a) where
1318− parseJSON (Object v) = EsResultFound <$>
1319− v .: "_version" <*>
1320− v .: "_source"
1321− parseJSON _ = empty
1322−
1323−instance FromJSON EsError where
1324− parseJSON (Object v) = EsError <$>
1325− v .: "status" <*>
1326− (v .: "error" <|> (v .: "error" >>= (.: "reason")))
1327− parseJSON _ = empty
1328−
1329−instance FromJSON IndexAliasesSummary where
1330− parseJSON = withObject "IndexAliasesSummary" parse
1331− where parse o = IndexAliasesSummary . mconcat <$> mapM (uncurry go) (HM.toList o)
1332− go ixn = withObject "index aliases" $ \ia -> do
1333− aliases <- ia .:? "aliases" .!= mempty
1334− forM (HM.toList aliases) $ \(aName, v) -> do
1335− let indexAlias = IndexAlias (IndexName ixn) (IndexAliasName (IndexName aName))
1336− IndexAliasSummary indexAlias <$> parseJSON v
1337−
1338−
1339−instance ToJSON IndexAliasAction where
1340− toJSON (AddAlias ia opts) = object ["add" .= (iaObj <> optsObj)]
1341− where Object iaObj = toJSON ia
1342− Object optsObj = toJSON opts
1343− toJSON (RemoveAlias ia) = object ["remove" .= iaObj]
1344− where Object iaObj = toJSON ia
1345−
1346−instance ToJSON IndexAlias where
1347− toJSON IndexAlias {..} = object ["index" .= srcIndex
1348− , "alias" .= indexAlias
1349− ]
1350−
1351−instance ToJSON IndexAliasCreate where
1352− toJSON IndexAliasCreate {..} = Object (filterObj <> routingObj)
1353− where filterObj = maybe mempty (HM.singleton "filter" . toJSON) aliasCreateFilter
1354− Object routingObj = maybe (Object mempty) toJSON aliasCreateRouting
1355−
1356−instance ToJSON AliasRouting where
1357− toJSON (AllAliasRouting v) = object ["routing" .= v]
1358− toJSON (GranularAliasRouting srch idx) = object (catMaybes prs)
1359− where prs = [("search_routing" .=) <$> srch
1360− ,("index_routing" .=) <$> idx]
1361−
1362−instance FromJSON AliasRouting where
1363− parseJSON = withObject "AliasRouting" parse
1364− where parse o = parseAll o <|> parseGranular o
1365− parseAll o = AllAliasRouting <$> o .: "routing"
1366− parseGranular o = do
1367− sr <- o .:? "search_routing"
1368− ir <- o .:? "index_routing"
1369− if isNothing sr && isNothing ir
1370− then fail "Both search_routing and index_routing can't be blank"
1371− else return (GranularAliasRouting sr ir)
1372−
1373−instance FromJSON IndexAliasCreate where
1374− parseJSON v = withObject "IndexAliasCreate" parse v
1375− where parse o = IndexAliasCreate <$> optional (parseJSON v)
1376− <*> o .:? "filter"
1377−
1378−instance ToJSON SearchAliasRouting where
1379− toJSON (SearchAliasRouting rvs) = toJSON (T.intercalate "," (routingValue <$> toList rvs))
1380−
1381−instance FromJSON SearchAliasRouting where
1382− parseJSON = withText "SearchAliasRouting" parse
1383− where parse t = SearchAliasRouting <$> parseNEJSON (String <$> T.splitOn "," t)
1384−
13851121instance ToJSON Search where
13861122 toJSON (Search mquery sFilter sort searchAggs
13871123 highlight sTrackSortScores sFrom sSize _ sFields
@@ -1494,91 +1230,12 @@ nonPostingsToPairs (Just (NonPostings npFragSize npNumOfFrags)) =
14941230 [ "fragment_size" .= npFragSize
14951231 , "number_of_fragments" .= npNumOfFrags]
14961232
1497−
1498−instance ToJSON HighlightEncoder where
1499− toJSON DefaultEncoder = String "default"
1500− toJSON HTMLEncoder = String "html"
1501−
15021233highlightTagToPairs :: Maybe HighlightTag -> [Pair]
15031234highlightTagToPairs (Just (TagSchema _)) = [ "scheme" .= String "default"]
15041235highlightTagToPairs (Just (CustomTags (pre, post))) = [ "pre_tags" .= pre
15051236 , "post_tags" .= post]
15061237highlightTagToPairs Nothing = []
15071238
1508−instance ToJSON SortSpec where
1509− toJSON (DefaultSortSpec
1510− (DefaultSort (FieldName dsSortFieldName) dsSortOrder dsIgnoreUnmapped
1511− dsSortMode dsMissingSort dsNestedFilter)) =
1512− object [dsSortFieldName .= omitNulls base] where
1513− base = [ "order" .= dsSortOrder
1514− , "unmapped_type" .= dsIgnoreUnmapped
1515− , "mode" .= dsSortMode
1516− , "missing" .= dsMissingSort
1517− , "nested_filter" .= dsNestedFilter ]
1518−
1519− toJSON (GeoDistanceSortSpec gdsSortOrder (GeoPoint (FieldName field) gdsLatLon) units) =
1520− object [ "unit" .= units
1521− , field .= gdsLatLon
1522− , "order" .= gdsSortOrder ]
1523−
1524−
1525−instance ToJSON SortOrder where
1526− toJSON Ascending = String "asc"
1527− toJSON Descending = String "desc"
1528−
1529−
1530−instance ToJSON SortMode where
1531− toJSON SortMin = String "min"
1532− toJSON SortMax = String "max"
1533− toJSON SortSum = String "sum"
1534− toJSON SortAvg = String "avg"
1535−
1536−
1537−instance ToJSON Missing where
1538− toJSON LastMissing = String "_last"
1539− toJSON FirstMissing = String "_first"
1540− toJSON (CustomMissing txt) = String txt
1541−
1542−
1543−
1544−instance (FromJSON a) => FromJSON (SearchResult a) where
1545− parseJSON (Object v) = SearchResult <$>
1546− v .: "took" <*>
1547− v .: "timed_out" <*>
1548− v .: "_shards" <*>
1549− v .: "hits" <*>
1550− v .:? "aggregations" <*>
1551− v .:? "_scroll_id" <*>
1552− v .:? "suggest"
1553− parseJSON _ = empty
1554−
1555−instance (FromJSON a) => FromJSON (SearchHits a) where
1556− parseJSON (Object v) = SearchHits <$>
1557− v .: "total" <*>
1558− v .: "max_score" <*>
1559− v .: "hits"
1560− parseJSON _ = empty
1561−
1562−instance (FromJSON a) => FromJSON (Hit a) where
1563− parseJSON (Object v) = Hit <$>
1564− v .: "_index" <*>
1565− v .: "_type" <*>
1566− v .: "_id" <*>
1567− v .: "_score" <*>
1568− v .:? "_source" <*>
1569− v .:? "fields" <*>
1570− v .:? "highlight"
1571− parseJSON _ = empty
1572−
1573−instance FromJSON HitFields where
1574− parseJSON x
1575− = HitFields <$> parseJSON x
1576−
1577−instance FromJSON DocVersion where
1578− parseJSON v = do
1579− i <- parseJSON v
1580− maybe (fail "DocVersion out of range") return $ mkDocVersion i
1581−
15821239data Suggest = Suggest { suggestText :: Text
15831240 , suggestName :: Text
15841241 , suggestType :: SuggestType
@@ -1613,36 +1270,38 @@ instance FromJSON SuggestType where
16131270 where taggedWith parser k = parser =<< o .: k
16141271 phraseSuggester = pure . SuggestTypePhraseSuggester
16151272
1616−data PhraseSuggester =
1617− PhraseSuggester { phraseSuggesterField :: FieldName
1618− , phraseSuggesterGramSize :: Maybe Int
1619− , phraseSuggesterRealWordErrorLikelihood :: Maybe Int
1620− , phraseSuggesterConfidence :: Maybe Int
1621− , phraseSuggesterMaxErrors :: Maybe Int
1622− , phraseSuggesterSeparator :: Maybe Text
1623− , phraseSuggesterSize :: Maybe Size
1624− , phraseSuggesterAnalyzer :: Maybe Analyzer
1625− , phraseSuggesterShardSize :: Maybe Int
1626− , phraseSuggesterHighlight :: Maybe PhraseSuggesterHighlighter
1627− , phraseSuggesterCollate :: Maybe PhraseSuggesterCollate
1628− , phraseSuggesterCandidateGenerators :: [DirectGenerators]
1629− }
1630− deriving (Eq, Show)
1273+data PhraseSuggester = PhraseSuggester
1274+ { phraseSuggesterField :: FieldName
1275+ , phraseSuggesterGramSize :: Maybe Int
1276+ , phraseSuggesterRealWordErrorLikelihood :: Maybe Int
1277+ , phraseSuggesterConfidence :: Maybe Int
1278+ , phraseSuggesterMaxErrors :: Maybe Int
1279+ , phraseSuggesterSeparator :: Maybe Text
1280+ , phraseSuggesterSize :: Maybe Size
1281+ , phraseSuggesterAnalyzer :: Maybe Analyzer
1282+ , phraseSuggesterShardSize :: Maybe Int
1283+ , phraseSuggesterHighlight :: Maybe PhraseSuggesterHighlighter
1284+ , phraseSuggesterCollate :: Maybe PhraseSuggesterCollate
1285+ , phraseSuggesterCandidateGenerators :: [DirectGenerators]
1286+ } deriving (Eq, Show)
16311287
16321288instance ToJSON PhraseSuggester where
1633− toJSON PhraseSuggester{..} = omitNulls [ "field" .= phraseSuggesterField
1634− , "gram_size" .= phraseSuggesterGramSize
1635− , "real_word_error_likelihood" .= phraseSuggesterRealWordErrorLikelihood
1636− , "confidence" .= phraseSuggesterConfidence
1637− , "max_errors" .= phraseSuggesterMaxErrors
1638− , "separator" .= phraseSuggesterSeparator
1639− , "size" .= phraseSuggesterSize
1640− , "analyzer" .= phraseSuggesterAnalyzer
1641− , "shard_size" .= phraseSuggesterShardSize
1642− , "highlight" .= phraseSuggesterHighlight
1643− , "collate" .= phraseSuggesterCollate
1644− , "direct_generator" .= phraseSuggesterCandidateGenerators
1645− ]
1289+ toJSON PhraseSuggester{..} =
1290+ omitNulls [ "field" .= phraseSuggesterField
1291+ , "gram_size" .= phraseSuggesterGramSize
1292+ , "real_word_error_likelihood" .=
1293+ phraseSuggesterRealWordErrorLikelihood
1294+ , "confidence" .= phraseSuggesterConfidence
1295+ , "max_errors" .= phraseSuggesterMaxErrors
1296+ , "separator" .= phraseSuggesterSeparator
1297+ , "size" .= phraseSuggesterSize
1298+ , "analyzer" .= phraseSuggesterAnalyzer
1299+ , "shard_size" .= phraseSuggesterShardSize
1300+ , "highlight" .= phraseSuggesterHighlight
1301+ , "collate" .= phraseSuggesterCollate
1302+ , "direct_generator" .=
1303+ phraseSuggesterCandidateGenerators
1304+ ]
16461305
16471306instance FromJSON PhraseSuggester where
16481307 parseJSON = withObject "PhraseSuggester" parse
@@ -1683,19 +1342,19 @@ instance FromJSON PhraseSuggesterHighlighter where
16831342 <$> o .: "pre_tag"
16841343 <*> o .: "post_tag"
16851344
1686−data PhraseSuggesterCollate =
1687− PhraseSuggesterCollate { phraseSuggesterCollateTemplateQuery :: TemplateQueryInline
1688− , phraseSuggesterCollatePrune :: Bool
1689− }
1690− deriving (Eq, Show)
1345+data PhraseSuggesterCollate = PhraseSuggesterCollate
1346+ { phraseSuggesterCollateTemplateQuery :: TemplateQueryInline
1347+ , phraseSuggesterCollatePrune :: Bool
1348+ } deriving (Eq, Show)
16911349
16921350instance ToJSON PhraseSuggesterCollate where
1693− toJSON PhraseSuggesterCollate{..} = object [ "query" .= object
1694− [ "inline" .= (inline phraseSuggesterCollateTemplateQuery)
1695− ]
1696− , "params" .= (params phraseSuggesterCollateTemplateQuery)
1697− , "prune" .= phraseSuggesterCollatePrune
1698− ]
1351+ toJSON PhraseSuggesterCollate{..} =
1352+ object [ "query" .= object
1353+ [ "inline" .= (inline phraseSuggesterCollateTemplateQuery)
1354+ ]
1355+ , "params" .= (params phraseSuggesterCollateTemplateQuery)
1356+ , "prune" .= phraseSuggesterCollatePrune
1357+ ]
16991358
17001359instance FromJSON PhraseSuggesterCollate where
17011360 parseJSON (Object o) = do
@@ -1703,7 +1362,8 @@ instance FromJSON PhraseSuggesterCollate where
17031362 inline' <- query' .: "inline"
17041363 params' <- o .: "params"
17051364 prune' <- o .:? "prune" .!= False
1706− return $ PhraseSuggesterCollate (TemplateQueryInline inline' params') prune'
1365+ return $ PhraseSuggesterCollate
1366+ (TemplateQueryInline inline' params') prune'
17071367 parseJSON x = typeMismatch "PhraseSuggesterCollate" x
17081368
17091369data SuggestOptions =
@@ -1738,11 +1398,10 @@ instance FromJSON SuggestResponse where
17381398 <*> o .: "length"
17391399 <*> o .: "options"
17401400
1741−data NamedSuggestionResponse =
1742− NamedSuggestionResponse { nsrName :: Text
1743− , nsrResponses :: [SuggestResponse]
1744− }
1745− deriving (Eq, Read, Show)
1401+data NamedSuggestionResponse = NamedSuggestionResponse
1402+ { nsrName :: Text
1403+ , nsrResponses :: [SuggestResponse]
1404+ } deriving (Eq, Read, Show)
17461405
17471406instance FromJSON NamedSuggestionResponse where
17481407 parseJSON (Object o) = do
@@ -1786,7 +1445,6 @@ data DirectGenerators = DirectGenerators
17861445 }
17871446 deriving (Eq, Show)
17881447
1789−
17901448instance ToJSON DirectGenerators where
17911449 toJSON DirectGenerators{..} = omitNulls [ "field" .= directGeneratorsField
17921450 , "size" .= directGeneratorsSize