git.iko.soy/typeable/bloodhound
on master help sign in
Restructuring modules, ripping out Generic
9d9ba1dChris Allen
@@ -1,3 +1,5 @@
1+stack = STACK_YAML='stack.yaml' stack
2+
1build:
3build:
2 stack build
4 stack build
3
5
@@ -10,6 +12,9 @@ echo-warn:
10test: echo-warn
12test: echo-warn
11 stack test
13 stack test
12
14
15+ghcid:
16+ ghcid -c "$(stack) ghci bloodhound:lib --test --ghci-options='-fobject-code -fno-warn-unused-do-bind' --main-is bloodhound:test:bloodhound-tests"
17+
137.8-build:
187.8-build:
14 STACK_YAML="stack-7.8.yaml" stack build
19 STACK_YAML="stack-7.8.yaml" stack build
15
20
bloodhound.cabal+11−7
@@ -31,18 +31,22 @@ Flag ES5
31 Description: Run the test suite against an Elasticsearch 5.x server
31 Description: Run the test suite against an Elasticsearch 5.x server
32 Default: True
32 Default: True
33
33
34+-- Database.V1.Bloodhound
35+-- Database.V1.Bloodhound.Client
36+-- Database.V1.Bloodhound.Types
37+-- Database.V1.Bloodhound.Types.Class
38+-- Database.V1.Bloodhound.Types.Internal
39+
34library
40library
35 ghc-options: -Wall
41 ghc-options: -Wall
36− exposed-modules: Database.V1.Bloodhound
42+ exposed-modules: Database.V5.Bloodhound
37− Database.V1.Bloodhound.Client
38− Database.V1.Bloodhound.Types
39− Database.V1.Bloodhound.Types.Class
40− Database.V1.Bloodhound.Types.Internal
41− Database.V5.Bloodhound
42 Database.V5.Bloodhound.Client
43 Database.V5.Bloodhound.Client
43 Database.V5.Bloodhound.Types
44 Database.V5.Bloodhound.Types
44 Database.V5.Bloodhound.Types.Class
45 Database.V5.Bloodhound.Types.Class
45 Database.V5.Bloodhound.Types.Internal
46 Database.V5.Bloodhound.Types.Internal
47+ Database.V5.Bloodhound.Types.Internal.Analysis
48+ Database.V5.Bloodhound.Types.Internal.Client
49+ Database.V5.Bloodhound.Types.Internal.Query
46 hs-source-dirs: src
50 hs-source-dirs: src
47 build-depends: base >= 4.3 && <5,
51 build-depends: base >= 4.3 && <5,
48 bytestring >= 0.10.0 && <0.11,
52 bytestring >= 0.10.0 && <0.11,
@@ -66,7 +70,7 @@ library
66 hashable
70 hashable
67 default-language: Haskell2010
71 default-language: Haskell2010
68
72
69−test-suite tests
73+test-suite bloodhound-tests
70 ghc-options: -Wall -fno-warn-orphans
74 ghc-options: -Wall -fno-warn-orphans
71 type: exitcode-stdio-1.0
75 type: exitcode-stdio-1.0
72 main-is: tests.hs
76 main-is: tests.hs
src/Bloodhound/Import.hsnew file+81
@@ -0,0 +1,81 @@
1+module Bloodhound.Import
2+ ( module X
3+ , LByteString
4+ , Method
5+ , parseReadText
6+ , readMay
7+ , showText
8+ ) where
9+
10+import Control.Applicative as X (Alternative(..), optional)
11+import Control.Exception as X (Exception)
12+import Control.Monad as X ( MonadPlus(..)
13+ , (<=<)
14+ , forM
15+ )
16+import Control.Monad.Fix as X (MonadFix)
17+import Control.Monad.IO.Class as X (MonadIO(..))
18+import Control.Monad.Catch as X ( MonadCatch
19+ , MonadMask
20+ , MonadThrow
21+ )
22+import Control.Monad.Error as X (MonadError)
23+import Control.Monad.Reader as X ( MonadReader (..)
24+ , MonadTrans (..)
25+ , ReaderT (..)
26+ )
27+import Control.Monad.State as X (MonadState)
28+import Control.Monad.Writer as X (MonadWriter)
29+import Data.Aeson as X
30+import Data.Aeson.Types as X ( Pair
31+ , Parser
32+ , emptyObject
33+ , parseEither
34+ , parseMaybe
35+ , typeMismatch
36+ )
37+import Data.Bifunctor as X (first)
38+import qualified Data.ByteString as X (ByteString)
39+import Data.Char as X (isNumber)
40+import Data.Hashable as X (Hashable)
41+import Data.List as X ( foldl'
42+ , intercalate
43+ , nub
44+ )
45+import Data.List.NonEmpty as X ( NonEmpty (..)
46+ , toList
47+ )
48+import Data.Maybe as X ( catMaybes
49+ , fromMaybe
50+ , isNothing
51+ , maybeToList
52+ )
53+import Data.Scientific as X (Scientific)
54+import Data.Semigroup as X (Semigroup(..))
55+import Data.Text as X (Text)
56+import Data.Time.Calendar as X ( Day(..)
57+ , showGregorian
58+ )
59+import Data.Time.Clock as X ( NominalDiffTime
60+ , UTCTime
61+ )
62+import Data.Time.Clock.POSIX as X
63+
64+import qualified Data.ByteString.Lazy as BL
65+import qualified Data.Text as T
66+import qualified Network.HTTP.Types.Method as NHTM
67+
68+type LByteString = BL.ByteString
69+
70+type Method = NHTM.Method
71+
72+readMay :: Read a => String -> Maybe a
73+readMay s = case reads s of
74+ (a, ""):_ -> Just a
75+ _ -> Nothing
76+
77+parseReadText :: Read a => Text -> Parser a
78+parseReadText = maybe mzero return . readMay . T.unpack
79+
80+showText :: Show a => a -> Text
81+showText = T.pack . show
src/Database/V5/Bloodhound/Types.hs+186−3852
@@ -4,7 +4,6 @@
4{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5{-# LANGUAGE GeneralizedNewtypeDeriving #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
7−-- {-# LANGUAGE NoMonomorphismRestriction #-}
8{-# LANGUAGE NamedFieldPuns #-}
7{-# LANGUAGE NamedFieldPuns #-}
9{-# LANGUAGE OverloadedStrings #-}
8{-# LANGUAGE OverloadedStrings #-}
10{-# LANGUAGE RecordWildCards #-}
9{-# LANGUAGE RecordWildCards #-}
@@ -386,580 +385,57 @@ module Database.V5.Bloodhound.Types
386 , TokenChar(..)
385 , TokenChar(..)
387 ) where
386 ) where
388
387
389−import Control.Applicative as A
388+-- import Control.Applicative as A
390−import Control.Arrow (first)
389+-- import Control.Arrow (first)
391−import Control.Monad.Catch
390+-- import Control.Monad.Catch
392−import Control.Monad.Except
391+-- import Control.Monad.Except
393−import Control.Monad.Reader (MonadReader (..),
394− ReaderT (..))
395−import Control.Monad.State (MonadState)
392+-- import Control.Monad.State (MonadState)
396−import Control.Monad.Writer (MonadWriter)
393+-- import Control.Monad.Writer (MonadWriter)
397−import Data.Aeson
394+-- import Data.Aeson
398−import Data.Aeson.Types (Pair, Parser,
395+-- import Data.Aeson.Types (Pair, Parser,
399− emptyObject,
396+-- emptyObject,
400− parseEither, parseMaybe,
397+-- parseEither, parseMaybe,
401− typeMismatch)
398+-- typeMismatch)
402−import qualified Data.ByteString.Lazy.Char8 as L
399+-- import qualified Data.ByteString.Lazy.Char8 as L
403−import Data.Char
400+-- import Data.Char
404−import Data.Hashable (Hashable)
401+-- import Data.Hashable (Hashable)
402+-- import qualified Data.HashMap.Strict as HM
403+-- import Data.List (foldl', intercalate,
404+-- nub)
405+-- import Data.List.NonEmpty (NonEmpty (..), toList)
406+-- import Data.Maybe
407+-- import Data.Scientific (Scientific)
408+-- import Data.Semigroup
409+-- import Data.Text (Text)
410+-- import qualified Data.Text as T
411+-- import Data.Time.Calendar
412+-- import Data.Time.Clock (NominalDiffTime,
413+-- UTCTime)
414+-- import Data.Time.Clock.POSIX
415+-- import qualified Data.Traversable as DT
416+-- import Data.Typeable (Typeable)
417+-- import qualified Data.Vector as V
418+-- import qualified Data.Version as Vers
419+-- import GHC.Enum
420+-- import GHC.Generics (Generic)
421+-- import Network.HTTP.Client
422+-- import qualified Network.HTTP.Types.Method as NHTM
423+-- import qualified Text.ParserCombinators.ReadP as RP
424+-- import qualified Text.Read as TR
425+
426+import Bloodhound.Import
427+
428+import qualified Data.Traversable as DT
405import qualified Data.HashMap.Strict as HM
429import qualified Data.HashMap.Strict as HM
406−import Data.List (foldl', intercalate,
407− nub)
408−import Data.List.NonEmpty (NonEmpty (..), toList)
409import qualified Data.Map.Strict as M
430import qualified Data.Map.Strict as M
410−import Data.Maybe
411−import Data.Scientific (Scientific)
412−import Data.Semigroup
413−import Data.Text (Text)
414import qualified Data.Text as T
431import qualified Data.Text as T
415−import Data.Time.Calendar
416−import Data.Time.Clock (NominalDiffTime,
417− UTCTime)
418−import Data.Time.Clock.POSIX
419−import qualified Data.Traversable as DT
420−import Data.Typeable (Typeable)
421−import qualified Data.Vector as V
422−import qualified Data.Version as Vers
423−import GHC.Enum
424−import GHC.Generics (Generic)
425−import Network.HTTP.Client
426−import qualified Network.HTTP.Types.Method as NHTM
427−import qualified Text.ParserCombinators.ReadP as RP
428−import qualified Text.Read as TR
429
432
430import Database.V5.Bloodhound.Types.Class
433import Database.V5.Bloodhound.Types.Class
431−import Database.V5.Bloodhound.Types.Internal
434+import Database.V5.Bloodhound.Types.Internal.Analysis
432−
435+import Database.V5.Bloodhound.Types.Internal.Client
433−-- $setup
436+import Database.V5.Bloodhound.Types.Internal.Newtypes
434−-- >>> :set -XOverloadedStrings
437+import Database.V5.Bloodhound.Types.Internal.Query
435−-- >>> import Data.Aeson
438+import Database.V5.Bloodhound.Types.Internal.StringlyTyped
436−-- >>> import Database.V5.Bloodhound
437−-- >>> let testServer = (Server "http://localhost:9200")
438−-- >>> let testIndex = IndexName "twitter"
439−-- >>> let testMapping = MappingName "tweet"
440−-- >>> let defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
441−
442−-- defaultIndexSettings is exported by Database.Bloodhound as well
443−-- no trailing slashes in servers, library handles building the path.
444−
445−-- | Create a 'BHEnv' with all optional fields defaulted. HTTP hook
446−-- will be a noop. You can use the exported fields to customize it further, e.g.:
447−--
448−-- >> (mkBHEnv myServer myManager) { bhRequestHook = customHook }
449−mkBHEnv :: Server -> Manager -> BHEnv
450−mkBHEnv s m = BHEnv s m return
451−
452−newtype BH m a = BH {
453− unBH :: ReaderT BHEnv m a
454− } deriving ( Functor
455− , A.Applicative
456− , Monad
457− , MonadIO
458− , MonadState s
459− , MonadWriter w
460− , MonadError e
461− , Alternative
462− , MonadPlus
463− , MonadFix
464− , MonadThrow
465− , MonadCatch
466− , MonadMask)
467−
468−instance MonadTrans BH where
469− lift = BH . lift
470−
471−instance (MonadReader r m) => MonadReader r (BH m) where
472− ask = lift ask
473− local f (BH (ReaderT m)) = BH $ ReaderT $ \r ->
474− local f (m r)
475−
476−instance (Functor m, Applicative m, MonadIO m) => MonadBH (BH m) where
477− getBHEnv = BH getBHEnv
478−
479−runBH :: BHEnv -> BH m a -> m a
480−runBH e f = runReaderT (unBH f) e
481−
482−{-| 'Version' is embedded in 'Status' -}
483−data Version = Version { number :: VersionNumber
484− , build_hash :: BuildHash
485− , build_date :: UTCTime
486− , build_snapshot :: Bool
487− , lucene_version :: VersionNumber } deriving (Eq, Read, Show, Generic, Typeable)
488−
489−-- | Traditional software versioning number
490−newtype VersionNumber = VersionNumber { versionNumber :: Vers.Version
491− } deriving (Eq, Read, Show, Generic, Typeable, Ord)
492−
493−{-| 'Status' is a data type for describing the JSON body returned by
494− Elasticsearch when you query its status. This was deprecated in 1.2.0.
495−
496− <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-status.html#indices-status>
497−-}
498−
499−data Status = Status { name :: Text
500− , cluster_name :: Text
501− , cluster_uuid :: Text
502− , version :: Version
503− , tagline :: Text } deriving (Eq, Read, Show, Generic)
504−
505−{-| 'IndexSettings' is used to configure the shards and replicas when you create
506− an Elasticsearch Index.
507−
508− <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html>
509−-}
510−
511−data IndexSettings =
512− IndexSettings { indexShards :: ShardCount
513− , indexReplicas :: ReplicaCount } deriving (Eq, Read, Show, Generic, Typeable)
514−
515−{-| 'defaultIndexSettings' is an 'IndexSettings' with 3 shards and 2 replicas. -}
516−defaultIndexSettings :: IndexSettings
517−defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
518−
519−
520−{-| 'ForceMergeIndexSettings' is used to configure index optimization. See
521− <https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-forcemerge.html>
522− for more info.
523−-}
524−data ForceMergeIndexSettings =
525− ForceMergeIndexSettings { maxNumSegments :: Maybe Int
526− -- ^ Number of segments to optimize to. 1 will fully optimize the index. If omitted, the default behavior is to only optimize if the server deems it necessary.
527− , onlyExpungeDeletes :: Bool
528− -- ^ Should the optimize process only expunge segments with deletes in them? If the purpose of the optimization is to free disk space, this should be set to True.
529− , flushAfterOptimize :: Bool
530− -- ^ Should a flush be performed after the optimize.
531− } deriving (Eq, Show, Generic, Typeable)
532−
533−
534−{-| 'defaultForceMergeIndexSettings' implements the default settings that
535− ElasticSearch uses for index optimization. 'maxNumSegments' is Nothing,
536− 'onlyExpungeDeletes' is False, and flushAfterOptimize is True.
537−-}
538−defaultForceMergeIndexSettings :: ForceMergeIndexSettings
539−defaultForceMergeIndexSettings = ForceMergeIndexSettings Nothing False True
540−
541−{-| 'UpdatableIndexSetting' are settings which may be updated after an index is created.
542−
543− <https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html>
544−-}
545−data UpdatableIndexSetting = NumberOfReplicas ReplicaCount
546− -- ^ The number of replicas each shard has.
547− | AutoExpandReplicas ReplicaBounds
548− | BlocksReadOnly Bool
549− -- ^ Set to True to have the index read only. False to allow writes and metadata changes.
550− | BlocksRead Bool
551− -- ^ Set to True to disable read operations against the index.
552− | BlocksWrite Bool
553− -- ^ Set to True to disable write operations against the index.
554− | BlocksMetaData Bool
555− -- ^ Set to True to disable metadata operations against the index.
556− | RefreshInterval NominalDiffTime
557− -- ^ The async refresh interval of a shard
558− | IndexConcurrency Int
559− | FailOnMergeFailure Bool
560− | TranslogFlushThresholdOps Int
561− -- ^ When to flush on operations.
562− | TranslogFlushThresholdSize Bytes
563− -- ^ When to flush based on translog (bytes) size.
564− | TranslogFlushThresholdPeriod NominalDiffTime
565− -- ^ When to flush based on a period of not flushing.
566− | TranslogDisableFlush Bool
567− -- ^ Disables flushing. Note, should be set for a short interval and then enabled.
568− | CacheFilterMaxSize (Maybe Bytes)
569− -- ^ The maximum size of filter cache (per segment in shard).
570− | CacheFilterExpire (Maybe NominalDiffTime)
571− -- ^ The expire after access time for filter cache.
572− | GatewaySnapshotInterval NominalDiffTime
573− -- ^ The gateway snapshot interval (only applies to shared gateways).
574− | RoutingAllocationInclude (NonEmpty NodeAttrFilter)
575− -- ^ A node matching any rule will be allowed to host shards from the index.
576− | RoutingAllocationExclude (NonEmpty NodeAttrFilter)
577− -- ^ A node matching any rule will NOT be allowed to host shards from the index.
578− | RoutingAllocationRequire (NonEmpty NodeAttrFilter)
579− -- ^ Only nodes matching all rules will be allowed to host shards from the index.
580− | RoutingAllocationEnable AllocationPolicy
581− -- ^ Enables shard allocation for a specific index.
582− | RoutingAllocationShardsPerNode ShardCount
583− -- ^ Controls the total number of shards (replicas and primaries) allowed to be allocated on a single node.
584− | RecoveryInitialShards InitialShardCount
585− -- ^ When using local gateway a particular shard is recovered only if there can be allocated quorum shards in the cluster.
586− | GCDeletes NominalDiffTime
587− | TTLDisablePurge Bool
588− -- ^ Disables temporarily the purge of expired docs.
589− | TranslogFSType FSType
590− | CompressionSetting Compression
591− | IndexCompoundFormat CompoundFormat
592− | IndexCompoundOnFlush Bool
593− | WarmerEnabled Bool
594− | MappingTotalFieldsLimit Int
595− | AnalysisSetting Analysis
596− -- ^ Analysis is not a dynamic setting and can only be performed on a closed index.
597− deriving (Eq, Show, Generic, Typeable)
598−
599−data Analysis = Analysis
600− { analysisAnalyzer :: M.Map Text AnalyzerDefinition
601− , analysisTokenizer :: M.Map Text TokenizerDefinition
602− } deriving (Eq,Show,Generic,Typeable)
603−
604−instance ToJSON Analysis where
605− toJSON (Analysis analyzer tokenizer) = object
606− [ "analyzer" .= analyzer
607− , "tokenizer" .= tokenizer
608− ]
609−
610−instance FromJSON Analysis where
611− parseJSON = withObject "Analysis" $ \m -> Analysis
612− <$> m .: "analyzer"
613− <*> m .: "tokenizer"
614−
615−data AnalyzerDefinition = AnalyzerDefinition
616− { analyzerDefinitionTokenizer :: Maybe Tokenizer
617− } deriving (Eq,Show,Generic,Typeable)
618−
619−instance ToJSON AnalyzerDefinition where
620− toJSON (AnalyzerDefinition tokenizer) = object $ catMaybes
621− [ fmap ("tokenizer" .=) tokenizer
622− ]
623−
624−instance FromJSON AnalyzerDefinition where
625− parseJSON = withObject "AnalyzerDefinition" $ \m -> AnalyzerDefinition
626− <$> m .:? "tokenizer"
627−
628−
629−data TokenizerDefinition
630− = TokenizerDefinitionNgram Ngram
631− deriving (Eq,Show,Generic,Typeable)
632−
633−instance ToJSON TokenizerDefinition where
634− toJSON x = case x of
635− TokenizerDefinitionNgram (Ngram minGram maxGram tokenChars) -> object
636− [ "type" .= ("ngram" :: Text)
637− , "min_gram" .= minGram
638− , "max_gram" .= maxGram
639− , "token_chars" .= tokenChars
640− ]
641−
642−instance FromJSON TokenizerDefinition where
643− parseJSON = withObject "TokenizerDefinition" $ \m -> do
644− typ <- m .: "type" :: Parser Text
645− case typ of
646− "ngram" -> fmap TokenizerDefinitionNgram $ Ngram
647− <$> (fmap unStringlyTypedInt (m .: "min_gram"))
648− <*> (fmap unStringlyTypedInt (m .: "max_gram"))
649− <*> m .: "token_chars"
650− _ -> fail "invalid TokenizerDefinition"
651−
652−data Ngram = Ngram
653− { ngramMinGram :: Int
654− , ngramMaxGram :: Int
655− , ngramTokenChars :: [TokenChar]
656− } deriving (Eq,Show,Generic,Typeable)
657−
658−data TokenChar = TokenLetter | TokenDigit | TokenWhitespace | TokenPunctuation | TokenSymbol
659− deriving (Eq,Read,Show,Generic,Typeable)
660−
661−instance ToJSON TokenChar where
662− toJSON t = String $ case t of
663− TokenLetter -> "letter"
664− TokenDigit -> "digit"
665− TokenWhitespace -> "whitespace"
666− TokenPunctuation -> "punctuation"
667− TokenSymbol -> "symbol"
668−
669−instance FromJSON TokenChar where
670− parseJSON = withText "TokenChar" $ \t -> case t of
671− "letter" -> return TokenLetter
672− "digit" -> return TokenDigit
673− "whitespace" -> return TokenWhitespace
674− "punctuation" -> return TokenPunctuation
675− "symbol" -> return TokenSymbol
676− _ -> fail "invalid TokenChar"
677−
678−data AllocationPolicy = AllocAll
679− -- ^ Allows shard allocation for all shards.
680− | AllocPrimaries
681− -- ^ Allows shard allocation only for primary shards.
682− | AllocNewPrimaries
683− -- ^ Allows shard allocation only for primary shards for new indices.
684− | AllocNone
685− -- ^ No shard allocation is allowed
686− deriving (Eq, Read, Show, Generic, Typeable)
687−
688−data ReplicaBounds = ReplicasBounded Int Int
689− | ReplicasLowerBounded Int
690− | ReplicasUnbounded
691− deriving (Eq, Read, Show, Generic, Typeable)
692−
693−data Compression
694− = CompressionDefault
695− -- ^ Compress with LZ4
696− | CompressionBest
697− -- ^ Compress with DEFLATE. Elastic
698− -- <https://www.elastic.co/blog/elasticsearch-storage-the-true-story-2.0 blogs>
699− -- that this can reduce disk use by 15%-25%.
700− deriving (Eq,Show,Generic,Typeable)
701−
702−instance ToJSON Compression where
703− toJSON x = case x of
704− CompressionDefault -> toJSON ("default" :: Text)
705− CompressionBest -> toJSON ("best_compression" :: Text)
706−
707−instance FromJSON Compression where
708− parseJSON = withText "Compression" $ \t -> case t of
709− "default" -> return CompressionDefault
710− "best_compression" -> return CompressionBest
711− _ -> fail "invalid compression codec"
712−
713−-- | A measure of bytes used for various configurations. You may want
714−-- to use smart constructors like 'gigabytes' for larger values.
715−--
716−-- >>> gigabytes 9
717−-- Bytes 9000000000
718−--
719−-- >>> megabytes 9
720−-- Bytes 9000000
721−--
722−-- >>> kilobytes 9
723−-- Bytes 9000
724−newtype Bytes = Bytes Int deriving (Eq, Read, Show, Generic, Typeable, Ord, ToJSON, FromJSON)
725−
726−gigabytes :: Int -> Bytes
727−gigabytes n = megabytes (1000 * n)
728−
729−
730−megabytes :: Int -> Bytes
731−megabytes n = kilobytes (1000 * n)
732−
733−
734−kilobytes :: Int -> Bytes
735−kilobytes n = Bytes (1000 * n)
736−
737−
738−data FSType = FSSimple
739− | FSBuffered deriving (Eq, Read, Show, Generic, Typeable, Ord)
740−
741−data InitialShardCount = QuorumShards
742− | QuorumMinus1Shards
743− | FullShards
744− | FullMinus1Shards
745− | ExplicitShards Int
746− deriving (Eq, Read, Show, Generic, Typeable)
747−
748−data NodeAttrFilter = NodeAttrFilter { nodeAttrFilterName :: NodeAttrName
749− , nodeAttrFilterValues :: NonEmpty Text}
750− deriving (Eq, Read, Show, Generic, Ord, Typeable)
751−
752−newtype NodeAttrName = NodeAttrName Text deriving (Eq, Read, Show, Ord, Generic, Typeable)
753−
754−data CompoundFormat = CompoundFileFormat Bool
755− | MergeSegmentVsTotalIndex Double
756− -- ^ percentage between 0 and 1 where 0 is false, 1 is true
757− deriving (Eq, Read, Show, Generic, Typeable)
758−
759−newtype NominalDiffTimeJSON = NominalDiffTimeJSON { ndtJSON :: NominalDiffTime }
760−
761−data IndexSettingsSummary = IndexSettingsSummary { sSummaryIndexName :: IndexName
762− , sSummaryFixedSettings :: IndexSettings
763− , sSummaryUpdateable :: [UpdatableIndexSetting]}
764− deriving (Eq, Show, Generic, Typeable)
765−
766−{-| 'Reply' and 'Method' are type synonyms from 'Network.HTTP.Types.Method.Method' -}
767−type Reply = Network.HTTP.Client.Response L.ByteString
768−type Method = NHTM.Method
769−
770−{-| 'OpenCloseIndex' is a sum type for opening and closing indices.
771−
772− <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-open-close.html>
773−-}
774−data OpenCloseIndex = OpenIndex | CloseIndex deriving (Eq, Read, Show, Generic, Typeable)
775−
776−data FieldType = GeoPointType
777− | GeoShapeType
778− | FloatType
779− | IntegerType
780− | LongType
781− | ShortType
782− | ByteType deriving (Eq, Read, Show, Generic, Typeable)
783−
784−data FieldDefinition =
785− FieldDefinition { fieldType :: FieldType } deriving (Eq, Read, Show, Generic, Typeable)
786−
787−{-| An 'IndexTemplate' defines a template that will automatically be
788− applied to new indices created. The templates include both
789− 'IndexSettings' and mappings, and a simple 'TemplatePattern' that
790− controls if the template will be applied to the index created.
791− Specify mappings as follows: @[toJSON TweetMapping, ...]@
792−
793− https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-templates.html
794−-}
795−data IndexTemplate =
796− IndexTemplate { templatePattern :: TemplatePattern
797− , templateSettings :: Maybe IndexSettings
798− , templateMappings :: [Value]
799− }
800−
801−data MappingField =
802− MappingField { mappingFieldName :: FieldName
803− , fieldDefinition :: FieldDefinition } deriving (Eq, Read, Show, Generic, Typeable)
804−
805−{-| Support for type reification of 'Mapping's is currently incomplete, for
806− now the mapping API verbiage expects a 'ToJSON'able blob.
807−
808− Indexes have mappings, mappings are schemas for the documents contained in the
809− index. I'd recommend having only one mapping per index, always having a mapping,
810− and keeping different kinds of documents separated if possible.
811−-}
812−data Mapping = Mapping { typeName :: TypeName
813− , mappingFields :: [MappingField] } deriving (Eq, Read, Show, Generic, Typeable)
814−
815−{-| 'BulkOperation' is a sum type for expressing the four kinds of bulk
816− operation index, create, delete, and update. 'BulkIndex' behaves like an
817− "upsert", 'BulkCreate' will fail if a document already exists at the DocId.
818−
819− <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-bulk.html#docs-bulk>
820−-}
821−data BulkOperation =
822− BulkIndex IndexName MappingName DocId Value
823− | BulkCreate IndexName MappingName DocId Value
824− | BulkCreateEncoding IndexName MappingName DocId Encoding
825− | BulkDelete IndexName MappingName DocId
826− | BulkUpdate IndexName MappingName DocId Value deriving (Eq, Show, Generic, Typeable)
827−
828−{-| 'EsResult' describes the standard wrapper JSON document that you see in
829− successful Elasticsearch lookups or lookups that couldn't find the document.
830−-}
831−data EsResult a = EsResult { _index :: Text
832− , _type :: Text
833− , _id :: Text
834− , foundResult :: Maybe (EsResultFound a)} deriving (Eq, Read, Show, Generic, Typeable)
835−
836−{-| 'EsResultFound' contains the document and its metadata inside of an
837− 'EsResult' when the document was successfully found.
838−-}
839−data EsResultFound a = EsResultFound { _version :: DocVersion
840− , _source :: a } deriving (Eq, Read, Show, Generic, Typeable)
841−
842−{-| 'EsError' is the generic type that will be returned when there was a
843− problem. If you can't parse the expected response, its a good idea to
844− try parsing this.
845−-}
846−data EsError = EsError { errorStatus :: Int
847− , errorMessage :: Text } deriving (Eq, Read, Show, Generic, Typeable)
848−
849−{-| 'EsProtocolException' will be thrown if Bloodhound cannot parse a response
850−returned by the ElasticSearch server. If you encounter this error, please
851−verify that your domain data types and FromJSON instances are working properly
852−(for example, the 'a' of '[Hit a]' in 'SearchResult.searchHits.hits'). If you're
853−sure that your mappings are correct, then this error may be an indication of an
854−incompatibility between Bloodhound and ElasticSearch. Please open a bug report
855−and be sure to include the exception body.
856−-}
857−data EsProtocolException = EsProtocolException { esProtoExBody :: L.ByteString }
858− deriving (Eq, Read, Show, Generic, Typeable)
859−
860−instance Exception EsProtocolException
861−
862−data IndexAlias = IndexAlias { srcIndex :: IndexName
863− , indexAlias :: IndexAliasName } deriving (Eq, Read, Show, Generic, Typeable)
864−
865−newtype IndexAliasName = IndexAliasName { indexAliasName :: IndexName } deriving (Eq, Read, Show, Generic, ToJSON)
866−
867−data IndexAliasAction = AddAlias IndexAlias IndexAliasCreate
868− | RemoveAlias IndexAlias deriving (Read, Show, Eq, Generic, Typeable)
869−
870−data IndexAliasCreate = IndexAliasCreate { aliasCreateRouting :: Maybe AliasRouting
871− , aliasCreateFilter :: Maybe Filter}
872− deriving (Read, Show, Eq, Generic, Typeable)
873−
874−data AliasRouting = AllAliasRouting RoutingValue
875− | GranularAliasRouting (Maybe SearchAliasRouting) (Maybe IndexAliasRouting)
876− deriving (Read, Show, Eq, Generic, Typeable)
877−
878−newtype SearchAliasRouting = SearchAliasRouting (NonEmpty RoutingValue) deriving (Read, Show, Eq, Generic, Typeable)
879−
880−newtype IndexAliasRouting = IndexAliasRouting RoutingValue deriving (Read, Show, Eq, Generic, ToJSON, FromJSON, Typeable)
881−
882−newtype RoutingValue = RoutingValue { routingValue :: Text } deriving (Read, Show, Eq, Generic, ToJSON, FromJSON, Typeable)
883−
884−newtype IndexAliasesSummary = IndexAliasesSummary { indexAliasesSummary :: [IndexAliasSummary] } deriving (Read, Show, Eq, Generic, Typeable)
885−
886−{-| 'IndexAliasSummary' is a summary of an index alias configured for a server. -}
887−data IndexAliasSummary = IndexAliasSummary { indexAliasSummaryAlias :: IndexAlias
888− , indexAliasSummaryCreate :: IndexAliasCreate} deriving (Read, Show, Eq, Generic, Typeable)
889−
890−{-| 'DocVersion' is an integer version number for a document between 1
891−and 9.2e+18 used for <<https://www.elastic.co/guide/en/elasticsearch/guide/current/optimistic-concurrency-control.html optimistic concurrency control>>.
892−-}
893−newtype DocVersion = DocVersion {
894− docVersionNumber :: Int
895− } deriving (Eq, Read, Show, Generic, Ord, ToJSON)
896−
897−-- | Smart constructor for in-range doc version
898−mkDocVersion :: Int -> Maybe DocVersion
899−mkDocVersion i
900− | i >= (docVersionNumber minBound) && i <= (docVersionNumber maxBound) =
901− Just $ DocVersion i
902− | otherwise = Nothing
903−
904−
905−{-| 'ExternalDocVersion' is a convenience wrapper if your code uses its
906−own version numbers instead of ones from ES.
907−-}
908−newtype ExternalDocVersion = ExternalDocVersion DocVersion
909− deriving (Eq, Read, Show, Generic, Ord, Bounded, Enum, ToJSON)
910−
911−{-| 'VersionControl' is specified when indexing documents as a
912−optimistic concurrency control.
913−-}
914−data VersionControl = NoVersionControl
915− -- ^ Don't send a version. This is a pure overwrite.
916− | InternalVersion DocVersion
917− -- ^ Use the default ES versioning scheme. Only
918− -- index the document if the version is the same
919− -- as the one specified. Only applicable to
920− -- updates, as you should be getting Version from
921− -- a search result.
922− | ExternalGT ExternalDocVersion
923− -- ^ Use your own version numbering. Only index
924− -- the document if the version is strictly higher
925− -- OR the document doesn't exist. The given
926− -- version will be used as the new version number
927− -- for the stored document. N.B. All updates must
928− -- increment this number, meaning there is some
929− -- global, external ordering of updates.
930− | ExternalGTE ExternalDocVersion
931− -- ^ Use your own version numbering. Only index
932− -- the document if the version is equal or higher
933− -- than the stored version. Will succeed if there
934− -- is no existing document. The given version will
935− -- be used as the new version number for the
936− -- stored document. Use with care, as this could
937− -- result in data loss.
938− | ForceVersion ExternalDocVersion
939− -- ^ The document will always be indexed and the
940− -- given version will be the new version. This is
941− -- typically used for correcting errors. Use with
942− -- care, as this could result in data loss.
943− deriving (Read, Show, Eq, Generic, Ord)
944−
945−{-| 'DocumentParent' is used to specify a parent document.
946−-}
947−newtype DocumentParent = DocumentParent DocId
948− deriving (Eq, Read, Show, Generic, Typeable)
949−
950−{-| 'IndexDocumentSettings' are special settings supplied when indexing
951−a document. For the best backwards compatiblity when new fields are
952−added, you should probably prefer to start with 'defaultIndexDocumentSettings'
953−-}
954−data IndexDocumentSettings =
955− IndexDocumentSettings { idsVersionControl :: VersionControl
956− , idsParent :: Maybe DocumentParent
957− } deriving (Eq, Read, Show, Generic, Typeable)
958−
959−{-| Reasonable default settings. Chooses no version control and no parent.
960−-}
961−defaultIndexDocumentSettings :: IndexDocumentSettings
962−defaultIndexDocumentSettings = IndexDocumentSettings NoVersionControl Nothing
963
439
964{-| 'Sort' is a synonym for a list of 'SortSpec's. Sort behavior is order
440{-| 'Sort' is a synonym for a list of 'SortSpec's. Sort behavior is order
965 dependent with later sorts acting as tie-breakers for earlier sorts.
441 dependent with later sorts acting as tie-breakers for earlier sorts.
@@ -974,7 +450,7 @@ type Sort = [SortSpec]
974<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
450<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
975-}
451-}
976data SortSpec = DefaultSortSpec DefaultSort
452data SortSpec = DefaultSortSpec DefaultSort
977− | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit deriving (Eq, Read, Show, Generic, Typeable)
453+ | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit deriving (Eq, Show)
978
454
979{-| 'DefaultSort' is usually the kind of 'SortSpec' you'll want. There's a
455{-| 'DefaultSort' is usually the kind of 'SortSpec' you'll want. There's a
980 'mkSort' convenience function for when you want to specify only the most
456 'mkSort' convenience function for when you want to specify only the most
@@ -991,7 +467,7 @@ data DefaultSort =
991 , ignoreUnmapped :: Maybe Text
467 , ignoreUnmapped :: Maybe Text
992 , sortMode :: Maybe SortMode
468 , sortMode :: Maybe SortMode
993 , missingSort :: Maybe Missing
469 , missingSort :: Maybe Missing
994− , nestedFilter :: Maybe Filter } deriving (Eq, Read, Show, Generic, Typeable)
470+ , nestedFilter :: Maybe Filter } deriving (Eq, Show)
995
471
996{-| 'SortOrder' is 'Ascending' or 'Descending', as you might expect. These get
472{-| 'SortOrder' is 'Ascending' or 'Descending', as you might expect. These get
997 encoded into "asc" or "desc" when turned into JSON.
473 encoded into "asc" or "desc" when turned into JSON.
@@ -999,7 +475,7 @@ data DefaultSort =
999<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
475<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
1000-}
476-}
1001data SortOrder = Ascending
477data SortOrder = Ascending
1002− | Descending deriving (Eq, Read, Show, Generic, Typeable)
478+ | Descending deriving (Eq, Show)
1003
479
1004{-| 'Missing' prescribes how to handle missing fields. A missing field can be
480{-| 'Missing' prescribes how to handle missing fields. A missing field can be
1005 sorted last, first, or using a custom value as a substitute.
481 sorted last, first, or using a custom value as a substitute.
@@ -1008,7 +484,7 @@ data SortOrder = Ascending
1008-}
484-}
1009data Missing = LastMissing
485data Missing = LastMissing
1010 | FirstMissing
486 | FirstMissing
1011− | CustomMissing Text deriving (Eq, Read, Show, Generic, Typeable)
487+ | CustomMissing Text deriving (Eq, Show)
1012
488
1013{-| 'SortMode' prescribes how to handle sorting array/multi-valued fields.
489{-| 'SortMode' prescribes how to handle sorting array/multi-valued fields.
1014
490
@@ -1017,7 +493,7 @@ http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-req
1017data SortMode = SortMin
493data SortMode = SortMin
1018 | SortMax
494 | SortMax
1019 | SortSum
495 | SortSum
1020− | SortAvg deriving (Eq, Read, Show, Generic, Typeable)
496+ | SortAvg deriving (Eq, Show)
1021
497
1022{-| 'mkSort' defaults everything but the 'FieldName' and the 'SortOrder' so
498{-| 'mkSort' defaults everything but the 'FieldName' and the 'SortOrder' so
1023 that you can concisely describe the usual kind of 'SortSpec's you want.
499 that you can concisely describe the usual kind of 'SortSpec's you want.
@@ -1025,203 +501,14 @@ data SortMode = SortMin
1025mkSort :: FieldName -> SortOrder -> DefaultSort
501mkSort :: FieldName -> SortOrder -> DefaultSort
1026mkSort fieldName sOrder = DefaultSort fieldName sOrder Nothing Nothing Nothing Nothing
502mkSort fieldName sOrder = DefaultSort fieldName sOrder Nothing Nothing Nothing Nothing
1027
503
1028−{-| 'Cache' is for telling ES whether it should cache a 'Filter' not.
1029− 'Query's cannot be cached.
1030−-}
1031−type Cache = Bool -- caching on/off
1032−defaultCache :: Cache
1033−defaultCache = False
1034−
1035−{-| 'PrefixValue' is used in 'PrefixQuery' as the main query component.
1036−-}
1037−-- type PrefixValue = Text
1038−
1039−{-| 'BooleanOperator' is the usual And/Or operators with an ES compatible
1040− JSON encoding baked in. Used all over the place.
1041−-}
1042−data BooleanOperator = And | Or deriving (Eq, Read, Show, Generic, Typeable)
1043−
1044−{-| 'ShardCount' is part of 'IndexSettings'
1045−-}
1046−newtype ShardCount = ShardCount Int deriving (Eq, Read, Show, Generic, ToJSON, Typeable)
1047−
1048−{-| 'ReplicaCount' is part of 'IndexSettings'
1049−-}
1050−newtype ReplicaCount = ReplicaCount Int deriving (Eq, Read, Show, Generic, ToJSON, Typeable)
1051−
1052−{-| 'IndexName' is used to describe which index to query/create/delete
1053−-}
1054−newtype IndexName = IndexName Text deriving (Eq, Generic, Read, Show, ToJSON, FromJSON, Typeable)
1055−
1056−{-| 'IndexSelection' is used for APIs which take a single index, a list of
1057− indexes, or the special @_all@ index.
1058−-}
1059−--TODO: this does not fully support <https://www.elastic.co/guide/en/elasticsearch/reference/1.7/multi-index.html multi-index syntax>. It wouldn't be too hard to implement but you'd have to add the optional parameters (ignore_unavailable, allow_no_indices, expand_wildcards) to any APIs using it. Also would be a breaking API.
1060−data IndexSelection = IndexList (NonEmpty IndexName)
1061− | AllIndexes deriving (Eq, Generic, Show, Typeable)
1062−
1063−{-| 'NodeSelection' is used for most cluster APIs. See <https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster.html#cluster-nodes here> for more details.
1064−-}
1065−data NodeSelection = LocalNode
1066− -- ^ Whatever node receives this request
1067− | NodeList (NonEmpty NodeSelector)
1068− | AllNodes deriving (Eq, Generic, Show, Typeable)
1069−
1070−
1071−-- | An exact match or pattern to identify a node. Note that All of
1072−-- these options support wildcarding, so your node name, server, attr
1073−-- name can all contain * characters to be a fuzzy match.
1074−data NodeSelector = NodeByName NodeName
1075− | NodeByFullNodeId FullNodeId
1076− | NodeByHost Server
1077− -- ^ e.g. 10.0.0.1 or even 10.0.0.*
1078− | NodeByAttribute NodeAttrName Text
1079− -- ^ NodeAttrName can be a pattern, e.g. rack*. The value can too.
1080− deriving (Eq, Generic, Show, Typeable)
1081−
1082−{-| 'TemplateName' is used to describe which template to query/create/delete
1083−-}
1084−newtype TemplateName = TemplateName Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1085−
1086−{-| 'TemplatePattern' represents a pattern which is matched against index names
1087−-}
1088−newtype TemplatePattern = TemplatePattern Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1089−
1090−{-| 'MappingName' is part of mappings which are how ES describes and schematizes
1091− the data in the indices.
1092−-}
1093−newtype MappingName = MappingName Text deriving (Eq, Generic, Read, Show, ToJSON, FromJSON, Typeable)
1094−
1095−{-| 'DocId' is a generic wrapper value for expressing unique Document IDs.
1096− Can be set by the user or created by ES itself. Often used in client
1097− functions for poking at specific documents.
1098−-}
1099−newtype DocId = DocId Text deriving (Eq, Generic, Read, Show, ToJSON, FromJSON, Typeable)
1100−
1101−{-| 'QueryString' is used to wrap query text bodies, be they human written or not.
1102−-}
1103−newtype QueryString = QueryString Text deriving (Eq, Generic, Read, Show, ToJSON, FromJSON, Typeable)
1104−
1105−{-| 'FieldName' is used all over the place wherever a specific field within
1106− a document needs to be specified, usually in 'Query's or 'Filter's.
1107−-}
1108−newtype FieldName = FieldName Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1109−
1110−
1111−{-| 'Script' is often used in place of 'FieldName' to specify more
1112−complex ways of extracting a value from a document.
1113−-}
1114−newtype Script = Script { scriptText :: Text } deriving (Eq, Read, Show, Generic, Typeable)
1115−
1116−{-| 'CacheName' is used in 'RegexpFilter' for describing the
1117− 'CacheKey' keyed caching behavior.
1118−-}
1119−newtype CacheName = CacheName Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1120−
1121−{-| 'CacheKey' is used in 'RegexpFilter' to key regex caching.
1122−-}
1123−newtype CacheKey =
1124− CacheKey Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1125−newtype Existence =
1126− Existence Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1127−newtype NullValue =
1128− NullValue Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1129−newtype CutoffFrequency =
1130− CutoffFrequency Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1131−newtype Analyzer =
1132− Analyzer Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1133−newtype Tokenizer =
1134− Tokenizer Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1135−newtype MaxExpansions =
1136− MaxExpansions Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1137−
1138−{-| 'Lenient', if set to true, will cause format based failures to be
1139− ignored. I don't know what the bloody default is, Elasticsearch
1140− documentation didn't say what it was. Let me know if you figure it out.
1141−-}
1142−newtype Lenient =
1143− Lenient Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1144−newtype Tiebreaker =
1145− Tiebreaker Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1146−newtype Boost =
1147− Boost Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1148−newtype BoostTerms =
1149− BoostTerms Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1150−
1151−{-| 'MinimumMatch' controls how many should clauses in the bool query should
1152− match. Can be an absolute value (2) or a percentage (30%) or a
1153− combination of both.
1154−-}
1155−newtype MinimumMatch =
1156− MinimumMatch Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1157−newtype DisableCoord =
1158− DisableCoord Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1159−newtype IgnoreTermFrequency =
1160− IgnoreTermFrequency Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1161−newtype MinimumTermFrequency =
1162− MinimumTermFrequency Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1163−newtype MaxQueryTerms =
1164− MaxQueryTerms Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1165−newtype Fuzziness =
1166− Fuzziness Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1167−
1168−{-| 'PrefixLength' is the prefix length used in queries, defaults to 0. -}
1169−newtype PrefixLength =
1170− PrefixLength Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1171−newtype TypeName =
1172− TypeName Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1173−newtype PercentMatch =
1174− PercentMatch Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1175−newtype StopWord =
1176− StopWord Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1177−newtype QueryPath =
1178− QueryPath Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1179−
1180−{-| Allowing a wildcard at the beginning of a word (eg "*ing") is particularly
1181− heavy, because all terms in the index need to be examined, just in case
1182− they match. Leading wildcards can be disabled by setting
1183− 'AllowLeadingWildcard' to false. -}
1184−newtype AllowLeadingWildcard =
1185− AllowLeadingWildcard Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1186−newtype LowercaseExpanded =
1187− LowercaseExpanded Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1188−newtype EnablePositionIncrements =
1189− EnablePositionIncrements Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1190−
1191−{-| By default, wildcard terms in a query are not analyzed.
1192− Setting 'AnalyzeWildcard' to true enables best-effort analysis.
1193−-}
1194−newtype AnalyzeWildcard = AnalyzeWildcard Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1195−
1196−{-| 'GeneratePhraseQueries' defaults to false.
1197−-}
1198−newtype GeneratePhraseQueries =
1199− GeneratePhraseQueries Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1200−
1201−{-| 'Locale' is used for string conversions - defaults to ROOT.
1202−-}
1203−newtype Locale = Locale Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1204−newtype MaxWordLength = MaxWordLength Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1205−newtype MinWordLength = MinWordLength Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1206−
1207−{-| 'PhraseSlop' sets the default slop for phrases, 0 means exact
1208− phrase matches. Default is 0.
1209−-}
1210−newtype PhraseSlop = PhraseSlop Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1211−newtype MinDocFrequency = MinDocFrequency Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1212−newtype MaxDocFrequency = MaxDocFrequency Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1213−
1214−-- | Newtype wrapper to parse ES's concerning tendency to in some APIs return a floating point number of milliseconds since epoch ಠ_ಠ
1215−newtype POSIXMS = POSIXMS { posixMS :: UTCTime }
1216−
1217{-| 'unpackId' is a silly convenience function that gets used once.
504{-| 'unpackId' is a silly convenience function that gets used once.
1218-}
505-}
1219unpackId :: DocId -> Text
506unpackId :: DocId -> Text
1220unpackId (DocId docId) = docId
507unpackId (DocId docId) = docId
1221
508
1222type TrackSortScores = Bool
509type TrackSortScores = Bool
1223−newtype From = From Int deriving (Eq, Read, Show, Generic, ToJSON)
510+newtype From = From Int deriving (Eq, Show, ToJSON)
1224−newtype Size = Size Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON)
511+newtype Size = Size Int deriving (Eq, Show, ToJSON, FromJSON)
1225
512
1226data Search = Search { queryBody :: Maybe Query
513data Search = Search { queryBody :: Maybe Query
1227 , filterBody :: Maybe Filter
514 , filterBody :: Maybe Filter
@@ -1236,44 +523,51 @@ data Search = Search { queryBody :: Maybe Query
1236 , fields :: Maybe [FieldName]
523 , fields :: Maybe [FieldName]
1237 , source :: Maybe Source
524 , source :: Maybe Source
1238 , suggestBody :: Maybe Suggest -- ^ Only one Suggestion request / response per Search is supported.
525 , suggestBody :: Maybe Suggest -- ^ Only one Suggestion request / response per Search is supported.
1239− } deriving (Eq, Read, Show, Generic, Typeable)
526+ } deriving (Eq, Show)
1240
527
1241data SearchType = SearchTypeQueryThenFetch
528data SearchType = SearchTypeQueryThenFetch
1242 | SearchTypeDfsQueryThenFetch
529 | SearchTypeDfsQueryThenFetch
1243− deriving (Eq, Read, Show, Generic, Typeable)
530+ deriving (Eq, Show)
1244
531
1245data Source =
532data Source =
1246 NoSource
533 NoSource
1247 | SourcePatterns PatternOrPatterns
534 | SourcePatterns PatternOrPatterns
1248 | SourceIncludeExclude Include Exclude
535 | SourceIncludeExclude Include Exclude
1249− deriving (Read, Show, Eq, Generic, Typeable)
536+ deriving (Eq, Show)
1250
537
1251data PatternOrPatterns = PopPattern Pattern
538data PatternOrPatterns = PopPattern Pattern
1252− | PopPatterns [Pattern] deriving (Eq, Read, Show, Generic, Typeable)
539+ | PopPatterns [Pattern] deriving (Eq, Read, Show)
1253
540
1254−data Include = Include [Pattern] deriving (Eq, Read, Show, Generic, Typeable)
541+data Include = Include [Pattern] deriving (Eq, Read, Show)
1255−data Exclude = Exclude [Pattern] deriving (Eq, Read, Show, Generic, Typeable)
542+data Exclude = Exclude [Pattern] deriving (Eq, Read, Show)
1256
543
1257−newtype Pattern = Pattern Text deriving (Eq, Read, Show, Generic, Typeable)
544+newtype Pattern = Pattern Text deriving (Eq, Read, Show)
1258
545
546+data Highlights = Highlights
1259−data Highlights = Highlights { globalsettings :: Maybe HighlightSettings
547+ { globalsettings :: Maybe HighlightSettings
1260− , highlightFields :: [FieldHighlight]
548+ , highlightFields :: [FieldHighlight]
1261− } deriving (Read, Show, Eq, Generic, Typeable)
549+ } deriving (Eq, Show)
1262
550
551+data FieldHighlight =
1263−data FieldHighlight = FieldHighlight FieldName (Maybe HighlightSettings)
552+ FieldHighlight FieldName (Maybe HighlightSettings)
1264− deriving (Read, Show, Eq, Generic, Typeable)
553+ deriving (Eq, Show)
1265
554
1266
555
1267−data HighlightSettings = Plain PlainHighlight
556+data HighlightSettings =
557+ Plain PlainHighlight
1268− | Postings PostingsHighlight
558+ | Postings PostingsHighlight
1269− | FastVector FastVectorHighlight
559+ | FastVector FastVectorHighlight
1270− deriving (Read, Show, Eq, Generic, Typeable)
560+ deriving (Eq, Show)
561+
1271data PlainHighlight =
562data PlainHighlight =
1272− PlainHighlight { plainCommon :: Maybe CommonHighlight
563+ PlainHighlight { plainCommon :: Maybe CommonHighlight
1273− , plainNonPost :: Maybe NonPostings } deriving (Read, Show, Eq, Generic, Typeable)
564+ , plainNonPost :: Maybe NonPostings }
565+ deriving (Eq, Show)
1274
566
1275 -- This requires that index_options are set to 'offset' in the mapping.
567 -- This requires that index_options are set to 'offset' in the mapping.
568+data PostingsHighlight =
1276−data PostingsHighlight = PostingsHighlight (Maybe CommonHighlight) deriving (Read, Show, Eq, Generic, Typeable)
569+ PostingsHighlight (Maybe CommonHighlight)
570+ deriving (Eq, Show)
1277
571
1278-- This requires that term_vector is set to 'with_positions_offsets' in the mapping.
572-- This requires that term_vector is set to 'with_positions_offsets' in the mapping.
1279data FastVectorHighlight =
573data FastVectorHighlight =
@@ -1284,7 +578,7 @@ data FastVectorHighlight =
1284 , fragmentOffset :: Maybe Int
578 , fragmentOffset :: Maybe Int
1285 , matchedFields :: [Text]
579 , matchedFields :: [Text]
1286 , phraseLimit :: Maybe Int
580 , phraseLimit :: Maybe Int
1287− } deriving (Read, Show, Eq, Generic, Typeable)
581+ } deriving (Eq, Show)
1288
582
1289data CommonHighlight =
583data CommonHighlight =
1290 CommonHighlight { order :: Maybe Text
584 CommonHighlight { order :: Maybe Text
@@ -1294,496 +588,26 @@ data CommonHighlight =
1294 , noMatchSize :: Maybe Int
588 , noMatchSize :: Maybe Int
1295 , highlightQuery :: Maybe Query
589 , highlightQuery :: Maybe Query
1296 , requireFieldMatch :: Maybe Bool
590 , requireFieldMatch :: Maybe Bool
1297− } deriving (Read, Show, Eq, Generic, Typeable)
591+ } deriving (Eq, Show)
1298
592
1299-- Settings that are only applicable to FastVector and Plain highlighters.
593-- Settings that are only applicable to FastVector and Plain highlighters.
1300data NonPostings =
594data NonPostings =
1301 NonPostings { fragmentSize :: Maybe Int
595 NonPostings { fragmentSize :: Maybe Int
1302− , numberOfFragments :: Maybe Int} deriving (Read, Show, Eq, Generic, Typeable)
596+ , numberOfFragments :: Maybe Int
597+ } deriving (Eq, Show)
1303
598
1304data HighlightEncoder = DefaultEncoder
599data HighlightEncoder = DefaultEncoder
1305 | HTMLEncoder
600 | HTMLEncoder
1306− deriving (Read, Show, Eq, Generic, Typeable)
601+ deriving (Eq, Show)
1307
602
1308-- NOTE: Should the tags use some kind of HTML type, rather than Text?
603-- NOTE: Should the tags use some kind of HTML type, rather than Text?
1309−data HighlightTag = TagSchema Text
604+data HighlightTag =
605+ TagSchema Text
1310− | CustomTags ([Text], [Text]) -- Only uses more than the first value in the lists if fvh
606+ -- Only uses more than the first value in the lists if fvh
1311− deriving (Read, Show, Eq, Generic, Typeable)
607+ | CustomTags ([Text], [Text])
1312−
1313−
1314−data Query =
1315− TermQuery Term (Maybe Boost)
1316− | TermsQuery Text (NonEmpty Text)
1317− | QueryMatchQuery MatchQuery
1318− | QueryMultiMatchQuery MultiMatchQuery
1319− | QueryBoolQuery BoolQuery
1320− | QueryBoostingQuery BoostingQuery
1321− | QueryCommonTermsQuery CommonTermsQuery
1322− | ConstantScoreQuery Query Boost
1323− | QueryDisMaxQuery DisMaxQuery
1324− | QueryFuzzyLikeThisQuery FuzzyLikeThisQuery
1325− | QueryFuzzyLikeFieldQuery FuzzyLikeFieldQuery
1326− | QueryFuzzyQuery FuzzyQuery
1327− | QueryHasChildQuery HasChildQuery
1328− | QueryHasParentQuery HasParentQuery
1329− | IdsQuery MappingName [DocId]
1330− | QueryIndicesQuery IndicesQuery
1331− | MatchAllQuery (Maybe Boost)
1332− | QueryMoreLikeThisQuery MoreLikeThisQuery
1333− | QueryMoreLikeThisFieldQuery MoreLikeThisFieldQuery
1334− | QueryNestedQuery NestedQuery
1335− | QueryPrefixQuery PrefixQuery
1336− | QueryQueryStringQuery QueryStringQuery
1337− | QuerySimpleQueryStringQuery SimpleQueryStringQuery
1338− | QueryRangeQuery RangeQuery
1339− | QueryRegexpQuery RegexpQuery
1340− | QueryExistsQuery FieldName
1341− | QueryMatchNoneQuery
1342− | QueryTemplateQueryInline TemplateQueryInline
1343− deriving (Eq, Read, Show, Generic, Typeable)
1344−
1345−-- | As of Elastic 2.0, 'Filters' are just 'Queries' housed in a Bool Query, and
1346−-- flagged in a different context.
1347−newtype Filter = Filter { unFilter :: Query }
1348− deriving (Eq, Read, Show, Generic, Typeable)
1349−
1350−instance ToJSON Filter where
1351− toJSON = toJSON . unFilter
1352−
1353−instance FromJSON Filter where
1354− parseJSON v = Filter <$> parseJSON v
1355−
1356−data RegexpQuery =
1357− RegexpQuery { regexpQueryField :: FieldName
1358− , regexpQuery :: Regexp
1359− , regexpQueryFlags :: RegexpFlags
1360− , regexpQueryBoost :: Maybe Boost
1361− } deriving (Eq, Read, Show, Generic, Typeable)
1362−
1363−data RangeQuery =
1364− RangeQuery { rangeQueryField :: FieldName
1365− , rangeQueryRange :: RangeValue
1366− , rangeQueryBoost :: Boost } deriving (Eq, Read, Show, Generic, Typeable)
1367−
1368−mkRangeQuery :: FieldName -> RangeValue -> RangeQuery
1369−mkRangeQuery f r = RangeQuery f r (Boost 1.0)
1370−
1371−data SimpleQueryStringQuery =
1372− SimpleQueryStringQuery
1373− { simpleQueryStringQuery :: QueryString
1374− , simpleQueryStringField :: Maybe FieldOrFields
1375− , simpleQueryStringOperator :: Maybe BooleanOperator
1376− , simpleQueryStringAnalyzer :: Maybe Analyzer
1377− , simpleQueryStringFlags :: Maybe (NonEmpty SimpleQueryFlag)
1378− , simpleQueryStringLowercaseExpanded :: Maybe LowercaseExpanded
1379− , simpleQueryStringLocale :: Maybe Locale
1380− } deriving (Eq, Read, Show, Generic, Typeable)
1381−
1382−data SimpleQueryFlag =
1383− SimpleQueryAll
1384− | SimpleQueryNone
1385− | SimpleQueryAnd
1386− | SimpleQueryOr
1387− | SimpleQueryPrefix
1388− | SimpleQueryPhrase
1389− | SimpleQueryPrecedence
1390− | SimpleQueryEscape
1391− | SimpleQueryWhitespace
1392− | SimpleQueryFuzzy
1393− | SimpleQueryNear
1394− | SimpleQuerySlop deriving (Eq, Read, Show, Generic, Typeable)
1395−
1396−-- use_dis_max and tie_breaker when fields are plural?
1397−data QueryStringQuery =
1398− QueryStringQuery
1399− { queryStringQuery :: QueryString
1400− , queryStringDefaultField :: Maybe FieldName
1401− , queryStringOperator :: Maybe BooleanOperator
1402− , queryStringAnalyzer :: Maybe Analyzer
1403− , queryStringAllowLeadingWildcard :: Maybe AllowLeadingWildcard
1404− , queryStringLowercaseExpanded :: Maybe LowercaseExpanded
1405− , queryStringEnablePositionIncrements :: Maybe EnablePositionIncrements
1406− , queryStringFuzzyMaxExpansions :: Maybe MaxExpansions
1407− , queryStringFuzziness :: Maybe Fuzziness
1408− , queryStringFuzzyPrefixLength :: Maybe PrefixLength
1409− , queryStringPhraseSlop :: Maybe PhraseSlop
1410− , queryStringBoost :: Maybe Boost
1411− , queryStringAnalyzeWildcard :: Maybe AnalyzeWildcard
1412− , queryStringGeneratePhraseQueries :: Maybe GeneratePhraseQueries
1413− , queryStringMinimumShouldMatch :: Maybe MinimumMatch
1414− , queryStringLenient :: Maybe Lenient
1415− , queryStringLocale :: Maybe Locale
1416− } deriving (Eq, Read, Show, Generic, Typeable)
1417−
1418−mkQueryStringQuery :: QueryString -> QueryStringQuery
1419−mkQueryStringQuery qs =
1420− QueryStringQuery qs Nothing Nothing
1421− Nothing Nothing Nothing Nothing
1422− Nothing Nothing Nothing Nothing
1423− Nothing Nothing Nothing Nothing
1424− Nothing Nothing
1425−
1426−data FieldOrFields = FofField FieldName
1427− | FofFields (NonEmpty FieldName) deriving (Eq, Read, Show, Generic, Typeable)
1428−
1429−data PrefixQuery =
1430− PrefixQuery
1431− { prefixQueryField :: FieldName
1432− , prefixQueryPrefixValue :: Text
1433− , prefixQueryBoost :: Maybe Boost } deriving (Eq, Read, Show, Generic, Typeable)
1434−
1435−data NestedQuery =
1436− NestedQuery
1437− { nestedQueryPath :: QueryPath
1438− , nestedQueryScoreType :: ScoreType
1439− , nestedQuery :: Query } deriving (Eq, Read, Show, Generic, Typeable)
1440−
1441−data MoreLikeThisFieldQuery =
1442− MoreLikeThisFieldQuery
1443− { moreLikeThisFieldText :: Text
1444− , moreLikeThisFieldFields :: FieldName
1445− -- default 0.3 (30%)
1446− , moreLikeThisFieldPercentMatch :: Maybe PercentMatch
1447− , moreLikeThisFieldMinimumTermFreq :: Maybe MinimumTermFrequency
1448− , moreLikeThisFieldMaxQueryTerms :: Maybe MaxQueryTerms
1449− , moreLikeThisFieldStopWords :: Maybe (NonEmpty StopWord)
1450− , moreLikeThisFieldMinDocFrequency :: Maybe MinDocFrequency
1451− , moreLikeThisFieldMaxDocFrequency :: Maybe MaxDocFrequency
1452− , moreLikeThisFieldMinWordLength :: Maybe MinWordLength
1453− , moreLikeThisFieldMaxWordLength :: Maybe MaxWordLength
1454− , moreLikeThisFieldBoostTerms :: Maybe BoostTerms
1455− , moreLikeThisFieldBoost :: Maybe Boost
1456− , moreLikeThisFieldAnalyzer :: Maybe Analyzer
1457− } deriving (Eq, Read, Show, Generic, Typeable)
1458−
1459−data MoreLikeThisQuery =
1460− MoreLikeThisQuery
1461− { moreLikeThisText :: Text
1462− , moreLikeThisFields :: Maybe (NonEmpty FieldName)
1463− -- default 0.3 (30%)
1464− , moreLikeThisPercentMatch :: Maybe PercentMatch
1465− , moreLikeThisMinimumTermFreq :: Maybe MinimumTermFrequency
1466− , moreLikeThisMaxQueryTerms :: Maybe MaxQueryTerms
1467− , moreLikeThisStopWords :: Maybe (NonEmpty StopWord)
1468− , moreLikeThisMinDocFrequency :: Maybe MinDocFrequency
1469− , moreLikeThisMaxDocFrequency :: Maybe MaxDocFrequency
1470− , moreLikeThisMinWordLength :: Maybe MinWordLength
1471− , moreLikeThisMaxWordLength :: Maybe MaxWordLength
1472− , moreLikeThisBoostTerms :: Maybe BoostTerms
1473− , moreLikeThisBoost :: Maybe Boost
1474− , moreLikeThisAnalyzer :: Maybe Analyzer
1475− } deriving (Eq, Read, Show, Generic, Typeable)
1476−
1477−data IndicesQuery =
1478− IndicesQuery
1479− { indicesQueryIndices :: [IndexName]
1480− , indicesQuery :: Query
1481− -- default "all"
1482− , indicesQueryNoMatch :: Maybe Query } deriving (Eq, Read, Show, Generic, Typeable)
1483−
1484−data HasParentQuery =
1485− HasParentQuery
1486− { hasParentQueryType :: TypeName
1487− , hasParentQuery :: Query
1488− , hasParentQueryScoreType :: Maybe ScoreType } deriving (Eq, Read, Show, Generic, Typeable)
1489−
1490−data HasChildQuery =
1491− HasChildQuery
1492− { hasChildQueryType :: TypeName
1493− , hasChildQuery :: Query
1494− , hasChildQueryScoreType :: Maybe ScoreType } deriving (Eq, Read, Show, Generic, Typeable)
1495−
1496−data ScoreType =
1497− ScoreTypeMax
1498− | ScoreTypeSum
1499− | ScoreTypeAvg
1500− | ScoreTypeNone deriving (Eq, Read, Show, Generic, Typeable)
1501−
1502−data FuzzyQuery =
1503− FuzzyQuery { fuzzyQueryField :: FieldName
1504− , fuzzyQueryValue :: Text
1505− , fuzzyQueryPrefixLength :: PrefixLength
1506− , fuzzyQueryMaxExpansions :: MaxExpansions
1507− , fuzzyQueryFuzziness :: Fuzziness
1508− , fuzzyQueryBoost :: Maybe Boost
1509− } deriving (Eq, Read, Show, Generic, Typeable)
1510−
1511−data FuzzyLikeFieldQuery =
1512− FuzzyLikeFieldQuery
1513− { fuzzyLikeField :: FieldName
1514− -- anaphora is good for the soul.
1515− , fuzzyLikeFieldText :: Text
1516− , fuzzyLikeFieldMaxQueryTerms :: MaxQueryTerms
1517− , fuzzyLikeFieldIgnoreTermFrequency :: IgnoreTermFrequency
1518− , fuzzyLikeFieldFuzziness :: Fuzziness
1519− , fuzzyLikeFieldPrefixLength :: PrefixLength
1520− , fuzzyLikeFieldBoost :: Boost
1521− , fuzzyLikeFieldAnalyzer :: Maybe Analyzer
1522− } deriving (Eq, Read, Show, Generic, Typeable)
1523−
1524−data FuzzyLikeThisQuery =
1525− FuzzyLikeThisQuery
1526− { fuzzyLikeFields :: [FieldName]
1527− , fuzzyLikeText :: Text
1528− , fuzzyLikeMaxQueryTerms :: MaxQueryTerms
1529− , fuzzyLikeIgnoreTermFrequency :: IgnoreTermFrequency
1530− , fuzzyLikeFuzziness :: Fuzziness
1531− , fuzzyLikePrefixLength :: PrefixLength
1532− , fuzzyLikeBoost :: Boost
1533− , fuzzyLikeAnalyzer :: Maybe Analyzer
1534− } deriving (Eq, Read, Show, Generic, Typeable)
1535−
1536−data DisMaxQuery =
1537− DisMaxQuery { disMaxQueries :: [Query]
1538− -- default 0.0
1539− , disMaxTiebreaker :: Tiebreaker
1540− , disMaxBoost :: Maybe Boost
1541− } deriving (Eq, Read, Show, Generic, Typeable)
1542−
1543−data MatchQuery =
1544− MatchQuery { matchQueryField :: FieldName
1545− , matchQueryQueryString :: QueryString
1546− , matchQueryOperator :: BooleanOperator
1547− , matchQueryZeroTerms :: ZeroTermsQuery
1548− , matchQueryCutoffFrequency :: Maybe CutoffFrequency
1549− , matchQueryMatchType :: Maybe MatchQueryType
1550− , matchQueryAnalyzer :: Maybe Analyzer
1551− , matchQueryMaxExpansions :: Maybe MaxExpansions
1552− , matchQueryLenient :: Maybe Lenient
1553− , matchQueryBoost :: Maybe Boost
1554− , matchQueryMinimumShouldMatch :: Maybe Text
1555− } deriving (Eq, Read, Show, Generic, Typeable)
608+ deriving (Eq, Show)
1556−
609+
1557−{-| 'mkMatchQuery' is a convenience function that defaults the less common parameters,
1558− enabling you to provide only the 'FieldName' and 'QueryString' to make a 'MatchQuery'
1559−-}
1560−mkMatchQuery :: FieldName -> QueryString -> MatchQuery
1561−mkMatchQuery field query = MatchQuery field query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1562−
1563−data MatchQueryType =
1564− MatchPhrase
1565− | MatchPhrasePrefix deriving (Eq, Read, Show, Generic, Typeable)
1566−
1567−data MultiMatchQuery =
1568− MultiMatchQuery { multiMatchQueryFields :: [FieldName]
1569− , multiMatchQueryString :: QueryString
1570− , multiMatchQueryOperator :: BooleanOperator
1571− , multiMatchQueryZeroTerms :: ZeroTermsQuery
1572− , multiMatchQueryTiebreaker :: Maybe Tiebreaker
1573− , multiMatchQueryType :: Maybe MultiMatchQueryType
1574− , multiMatchQueryCutoffFrequency :: Maybe CutoffFrequency
1575− , multiMatchQueryAnalyzer :: Maybe Analyzer
1576− , multiMatchQueryMaxExpansions :: Maybe MaxExpansions
1577− , multiMatchQueryLenient :: Maybe Lenient } deriving (Eq, Read, Show, Generic, Typeable)
1578−
1579−{-| 'mkMultiMatchQuery' is a convenience function that defaults the less common parameters,
1580− enabling you to provide only the list of 'FieldName's and 'QueryString' to
1581− make a 'MultiMatchQuery'.
1582−-}
1583
610
1584−mkMultiMatchQuery :: [FieldName] -> QueryString -> MultiMatchQuery
1585−mkMultiMatchQuery matchFields query =
1586− MultiMatchQuery matchFields query
1587− Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1588−
1589−data MultiMatchQueryType =
1590− MultiMatchBestFields
1591− | MultiMatchMostFields
1592− | MultiMatchCrossFields
1593− | MultiMatchPhrase
1594− | MultiMatchPhrasePrefix deriving (Eq, Read, Show, Generic, Typeable)
1595−
1596−data BoolQuery =
1597− BoolQuery { boolQueryMustMatch :: [Query]
1598− , boolQueryFilter :: [Filter]
1599− , boolQueryMustNotMatch :: [Query]
1600− , boolQueryShouldMatch :: [Query]
1601− , boolQueryMinimumShouldMatch :: Maybe MinimumMatch
1602− , boolQueryBoost :: Maybe Boost
1603− , boolQueryDisableCoord :: Maybe DisableCoord
1604− } deriving (Eq, Read, Show, Generic, Typeable)
1605−
1606−mkBoolQuery :: [Query] -> [Filter] -> [Query] -> [Query] -> BoolQuery
1607−mkBoolQuery must filt mustNot should =
1608− BoolQuery must filt mustNot should Nothing Nothing Nothing
1609−
1610−data BoostingQuery =
1611− BoostingQuery { positiveQuery :: Query
1612− , negativeQuery :: Query
1613− , negativeBoost :: Boost } deriving (Eq, Read, Show, Generic, Typeable)
1614−
1615−data CommonTermsQuery =
1616− CommonTermsQuery { commonField :: FieldName
1617− , commonQuery :: QueryString
1618− , commonCutoffFrequency :: CutoffFrequency
1619− , commonLowFreqOperator :: BooleanOperator
1620− , commonHighFreqOperator :: BooleanOperator
1621− , commonMinimumShouldMatch :: Maybe CommonMinimumMatch
1622− , commonBoost :: Maybe Boost
1623− , commonAnalyzer :: Maybe Analyzer
1624− , commonDisableCoord :: Maybe DisableCoord
1625− } deriving (Eq, Read, Show, Generic, Typeable)
1626−
1627−data CommonMinimumMatch =
1628− CommonMinimumMatchHighLow MinimumMatchHighLow
1629− | CommonMinimumMatch MinimumMatch
1630− deriving (Eq, Read, Show, Generic, Typeable)
1631−
1632−data MinimumMatchHighLow =
1633− MinimumMatchHighLow { lowFreq :: MinimumMatch
1634− , highFreq :: MinimumMatch } deriving (Eq, Read, Show, Generic, Typeable)
1635−
1636−data ZeroTermsQuery = ZeroTermsNone
1637− | ZeroTermsAll deriving (Eq, Read, Show, Generic, Typeable)
1638−
1639−data RangeExecution = RangeExecutionIndex
1640− | RangeExecutionFielddata deriving (Eq, Read, Show, Generic, Typeable)
1641−
1642−newtype Regexp = Regexp Text deriving (Eq, Read, Show, Generic, Typeable, FromJSON)
1643−
1644−data RegexpFlags = AllRegexpFlags
1645− | NoRegexpFlags
1646− | SomeRegexpFlags (NonEmpty RegexpFlag) deriving (Eq, Read, Show, Generic, Typeable)
1647−
1648−data RegexpFlag = AnyString
1649− | Automaton
1650− | Complement
1651− | Empty
1652− | Intersection
1653− | Interval deriving (Eq, Read, Show, Generic, Typeable)
1654−
1655−newtype LessThan = LessThan Double deriving (Eq, Read, Show, Generic, Typeable)
1656−newtype LessThanEq = LessThanEq Double deriving (Eq, Read, Show, Generic, Typeable)
1657−newtype GreaterThan = GreaterThan Double deriving (Eq, Read, Show, Generic, Typeable)
1658−newtype GreaterThanEq = GreaterThanEq Double deriving (Eq, Read, Show, Generic, Typeable)
1659−
1660−newtype LessThanD = LessThanD UTCTime deriving (Eq, Read, Show, Generic, Typeable)
1661−newtype LessThanEqD = LessThanEqD UTCTime deriving (Eq, Read, Show, Generic, Typeable)
1662−newtype GreaterThanD = GreaterThanD UTCTime deriving (Eq, Read, Show, Generic, Typeable)
1663−newtype GreaterThanEqD = GreaterThanEqD UTCTime deriving (Eq, Read, Show, Generic, Typeable)
1664−
1665−data RangeValue = RangeDateLte LessThanEqD
1666− | RangeDateLt LessThanD
1667− | RangeDateGte GreaterThanEqD
1668− | RangeDateGt GreaterThanD
1669− | RangeDateGtLt GreaterThanD LessThanD
1670− | RangeDateGteLte GreaterThanEqD LessThanEqD
1671− | RangeDateGteLt GreaterThanEqD LessThanD
1672− | RangeDateGtLte GreaterThanD LessThanEqD
1673− | RangeDoubleLte LessThanEq
1674− | RangeDoubleLt LessThan
1675− | RangeDoubleGte GreaterThanEq
1676− | RangeDoubleGt GreaterThan
1677− | RangeDoubleGtLt GreaterThan LessThan
1678− | RangeDoubleGteLte GreaterThanEq LessThanEq
1679− | RangeDoubleGteLt GreaterThanEq LessThan
1680− | RangeDoubleGtLte GreaterThan LessThanEq
1681− deriving (Eq, Read, Show, Generic, Typeable)
1682−
1683−rangeValueToPair :: RangeValue -> [Pair]
1684−rangeValueToPair rv = case rv of
1685− RangeDateLte (LessThanEqD t) -> ["lte" .= t]
1686− RangeDateGte (GreaterThanEqD t) -> ["gte" .= t]
1687− RangeDateLt (LessThanD t) -> ["lt" .= t]
1688− RangeDateGt (GreaterThanD t) -> ["gt" .= t]
1689− RangeDateGteLte (GreaterThanEqD l) (LessThanEqD g) -> ["gte" .= l, "lte" .= g]
1690− RangeDateGtLte (GreaterThanD l) (LessThanEqD g) -> ["gt" .= l, "lte" .= g]
1691− RangeDateGteLt (GreaterThanEqD l) (LessThanD g) -> ["gte" .= l, "lt" .= g]
1692− RangeDateGtLt (GreaterThanD l) (LessThanD g) -> ["gt" .= l, "lt" .= g]
1693− RangeDoubleLte (LessThanEq t) -> ["lte" .= t]
1694− RangeDoubleGte (GreaterThanEq t) -> ["gte" .= t]
1695− RangeDoubleLt (LessThan t) -> ["lt" .= t]
1696− RangeDoubleGt (GreaterThan t) -> ["gt" .= t]
1697− RangeDoubleGteLte (GreaterThanEq l) (LessThanEq g) -> ["gte" .= l, "lte" .= g]
1698− RangeDoubleGtLte (GreaterThan l) (LessThanEq g) -> ["gt" .= l, "lte" .= g]
1699− RangeDoubleGteLt (GreaterThanEq l) (LessThan g) -> ["gte" .= l, "lt" .= g]
1700− RangeDoubleGtLt (GreaterThan l) (LessThan g) -> ["gt" .= l, "lt" .= g]
1701−
1702−data Term = Term { termField :: Text
1703− , termValue :: Text } deriving (Eq, Read, Show, Generic, Typeable)
1704−
1705−data BoolMatch = MustMatch Term Cache
1706− | MustNotMatch Term Cache
1707− | ShouldMatch [Term] Cache deriving (Eq, Read, Show, Generic, Typeable)
1708−
1709−-- "memory" or "indexed"
1710−data GeoFilterType = GeoFilterMemory
1711− | GeoFilterIndexed deriving (Eq, Read, Show, Generic, Typeable)
1712−
1713−data LatLon = LatLon { lat :: Double
1714− , lon :: Double } deriving (Eq, Read, Show, Generic, Typeable)
1715−
1716−data GeoBoundingBox =
1717− GeoBoundingBox { topLeft :: LatLon
1718− , bottomRight :: LatLon } deriving (Eq, Read, Show, Generic, Typeable)
1719−
1720−data GeoBoundingBoxConstraint =
1721− GeoBoundingBoxConstraint { geoBBField :: FieldName
1722− , constraintBox :: GeoBoundingBox
1723− , bbConstraintcache :: Cache
1724− , geoType :: GeoFilterType
1725− } deriving (Eq, Read, Show, Generic, Typeable)
1726−
1727−data GeoPoint =
1728− GeoPoint { geoField :: FieldName
1729− , latLon :: LatLon} deriving (Eq, Read, Show, Generic, Typeable)
1730−
1731−data DistanceUnit = Miles
1732− | Yards
1733− | Feet
1734− | Inches
1735− | Kilometers
1736− | Meters
1737− | Centimeters
1738− | Millimeters
1739− | NauticalMiles deriving (Eq, Read, Show, Generic, Typeable)
1740−
1741−data DistanceType = Arc
1742− | SloppyArc -- doesn't exist <1.0
1743− | Plane deriving (Eq, Read, Show, Generic, Typeable)
1744−
1745−data OptimizeBbox = OptimizeGeoFilterType GeoFilterType
1746− | NoOptimizeBbox deriving (Eq, Read, Show, Generic, Typeable)
1747−
1748−data Distance =
1749− Distance { coefficient :: Double
1750− , unit :: DistanceUnit } deriving (Eq, Read, Show, Generic, Typeable)
1751−
1752−data DistanceRange =
1753− DistanceRange { distanceFrom :: Distance
1754− , distanceTo :: Distance } deriving (Eq, Read, Show, Generic, Typeable)
1755−
1756−type TemplateQueryKey = Text
1757−type TemplateQueryValue = Text
1758−
1759−newtype TemplateQueryKeyValuePairs = TemplateQueryKeyValuePairs (HM.HashMap TemplateQueryKey TemplateQueryValue)
1760− deriving (Eq, Read, Show, Generic)
1761−
1762−instance ToJSON TemplateQueryKeyValuePairs where
1763− toJSON (TemplateQueryKeyValuePairs x) = Object $ HM.map toJSON x
1764−
1765−instance FromJSON TemplateQueryKeyValuePairs where
1766− parseJSON (Object o) = pure . TemplateQueryKeyValuePairs $ HM.mapMaybe getValue o
1767− where getValue (String x) = Just x
1768− getValue _ = Nothing
1769− parseJSON _ = fail "error parsing TemplateQueryKeyValuePairs"
1770−
1771−data TemplateQueryInline =
1772− TemplateQueryInline { inline :: Query
1773− , params :: TemplateQueryKeyValuePairs
1774− }
1775− deriving (Eq, Read, Show, Generic, Typeable)
1776−
1777−instance ToJSON TemplateQueryInline where
1778− toJSON TemplateQueryInline{..} = object [ "inline" .= inline
1779− , "params" .= params
1780− ]
1781−
1782−instance FromJSON TemplateQueryInline where
1783− parseJSON = withObject "TemplateQueryInline" parse
1784− where parse o = TemplateQueryInline
1785− <$> o .: "inline"
1786− <*> o .: "params"
1787
611
1788
612
1789data SearchResult a =
613data SearchResult a =
@@ -1795,16 +619,18 @@ data SearchResult a =
1795 , scrollId :: Maybe ScrollId
619 , scrollId :: Maybe ScrollId
1796 , suggest :: Maybe NamedSuggestionResponse -- ^ Only one Suggestion request / response per Search is supported.
620 , suggest :: Maybe NamedSuggestionResponse -- ^ Only one Suggestion request / response per Search is supported.
1797 }
621 }
1798− deriving (Eq, Read, Show, Generic, Typeable)
622+ deriving (Eq, Show)
1799
623
624+newtype ScrollId =
625+ ScrollId Text
1800−newtype ScrollId = ScrollId Text deriving (Eq, Read, Show, Generic, Ord, ToJSON, FromJSON)
626+ deriving (Eq, Show, Ord, ToJSON, FromJSON)
1801
627
1802type Score = Maybe Double
628type Score = Maybe Double
1803
629
1804data SearchHits a =
630data SearchHits a =
1805 SearchHits { hitsTotal :: Int
631 SearchHits { hitsTotal :: Int
1806 , maxScore :: Score
632 , maxScore :: Score
1807− , hits :: [Hit a] } deriving (Eq, Read, Show, Generic, Typeable)
633+ , hits :: [Hit a] } deriving (Eq, Show)
1808
634
1809instance Semigroup (SearchHits a) where
635instance Semigroup (SearchHits a) where
1810 (SearchHits ta ma ha) <> (SearchHits tb mb hb) = SearchHits (ta + tb) (max ma mb) (ha <> hb)
636 (SearchHits ta ma ha) <> (SearchHits tb mb hb) = SearchHits (ta + tb) (max ma mb) (ha <> hb)
@@ -1819,25 +645,10 @@ data Hit a =
1819 , hitDocId :: DocId
645 , hitDocId :: DocId
1820 , hitScore :: Score
646 , hitScore :: Score
1821 , hitSource :: Maybe a
647 , hitSource :: Maybe a
1822− , hitHighlight :: Maybe HitHighlight } deriving (Eq, Read, Show, Generic, Typeable)
648+ , hitHighlight :: Maybe HitHighlight } deriving (Eq, Show)
1823−
1824−data ShardResult =
1825− ShardResult { shardTotal :: Int
1826− , shardsSuccessful :: Int
1827− , shardsFailed :: Int } deriving (Eq, Read, Show, Generic, Typeable)
1828
649
1829type HitHighlight = M.Map Text [Text]
650type HitHighlight = M.Map Text [Text]
1830
651
1831−showText :: Show a => a -> Text
1832−showText = T.pack . show
1833−
1834−readMay :: Read a => String -> Maybe a
1835−readMay s = case reads s of
1836− (a, ""):_ -> Just a
1837− _ -> Nothing
1838−
1839−parseReadText :: Read a => Text -> Parser a
1840−parseReadText = maybe mzero return . readMay . T.unpack
1841
652
1842type Aggregations = M.Map Text Aggregation
653type Aggregations = M.Map Text Aggregation
1843
654
@@ -1848,34 +659,19 @@ mkAggregations :: Text -> Aggregation -> Aggregations
1848mkAggregations name aggregation = M.insert name aggregation emptyAggregations
659mkAggregations name aggregation = M.insert name aggregation emptyAggregations
1849
660
1850data TermOrder = TermOrder{ termSortField :: Text
661data TermOrder = TermOrder{ termSortField :: Text
1851− , termSortOrder :: SortOrder } deriving (Eq, Read, Show, Generic, Typeable)
662+ , termSortOrder :: SortOrder } deriving (Eq, Show)
1852
663
1853data TermInclusion = TermInclusion Text
664data TermInclusion = TermInclusion Text
1854− | TermPattern Text Text deriving (Eq, Read, Show, Generic, Typeable)
665+ | TermPattern Text Text deriving (Eq, Show)
1855
666
1856data CollectionMode = BreadthFirst
667data CollectionMode = BreadthFirst
1857− | DepthFirst deriving (Eq, Read, Show, Generic, Typeable)
668+ | DepthFirst deriving (Eq, Show)
1858
669
1859data ExecutionHint = Ordinals
670data ExecutionHint = Ordinals
1860 | GlobalOrdinals
671 | GlobalOrdinals
1861 | GlobalOrdinalsHash
672 | GlobalOrdinalsHash
1862 | GlobalOrdinalsLowCardinality
673 | GlobalOrdinalsLowCardinality
1863− | Map deriving (Eq, Read, Show, Generic, Typeable)
674+ | Map deriving (Eq, Show)
1864−
1865−data TimeInterval = Weeks
1866− | Days
1867− | Hours
1868− | Minutes
1869− | Seconds deriving Eq
1870−
1871−data Interval = Year
1872− | Quarter
1873− | Month
1874− | Week
1875− | Day
1876− | Hour
1877− | Minute
1878− | Second deriving (Eq, Read, Show, Generic, Typeable)
1879
675
1880data Aggregation = TermsAgg TermsAggregation
676data Aggregation = TermsAgg TermsAggregation
1881 | CardinalityAgg CardinalityAggregation
677 | CardinalityAgg CardinalityAggregation
@@ -1886,17 +682,17 @@ data Aggregation = TermsAgg TermsAggregation
1886 | MissingAgg MissingAggregation
682 | MissingAgg MissingAggregation
1887 | TopHitsAgg TopHitsAggregation
683 | TopHitsAgg TopHitsAggregation
1888 | StatsAgg StatisticsAggregation
684 | StatsAgg StatisticsAggregation
1889− deriving (Eq, Read, Show, Generic, Typeable)
685+ deriving (Eq, Show)
1890
686
1891data TopHitsAggregation = TopHitsAggregation
687data TopHitsAggregation = TopHitsAggregation
1892 { taFrom :: Maybe From
688 { taFrom :: Maybe From
1893 , taSize :: Maybe Size
689 , taSize :: Maybe Size
1894 , taSort :: Maybe Sort
690 , taSort :: Maybe Sort
1895− } deriving (Eq, Read, Show)
691+ } deriving (Eq, Show)
1896
692
1897data MissingAggregation = MissingAggregation
693data MissingAggregation = MissingAggregation
1898 { maField :: Text
694 { maField :: Text
1899− } deriving (Eq, Read, Show, Generic, Typeable)
695+ } deriving (Eq, Show)
1900
696
1901data TermsAggregation = TermsAggregation { term :: Either Text Text
697data TermsAggregation = TermsAggregation { term :: Either Text Text
1902 , termInclude :: Maybe TermInclusion
698 , termInclude :: Maybe TermInclusion
@@ -1908,71 +704,91 @@ data TermsAggregation = TermsAggregation { term :: Either Text Text
1908 , termCollectMode :: Maybe CollectionMode
704 , termCollectMode :: Maybe CollectionMode
1909 , termExecutionHint :: Maybe ExecutionHint
705 , termExecutionHint :: Maybe ExecutionHint
1910 , termAggs :: Maybe Aggregations
706 , termAggs :: Maybe Aggregations
1911− } deriving (Eq, Read, Show, Generic, Typeable)
707+ } deriving (Eq, Show)
1912−
708+
1913−data CardinalityAggregation = CardinalityAggregation { cardinalityField :: FieldName,
709+data CardinalityAggregation = CardinalityAggregation
710+ { cardinalityField :: FieldName,
1914− precisionThreshold :: Maybe Int
711+ precisionThreshold :: Maybe Int
1915− } deriving (Eq, Read, Show, Generic, Typeable)
712+ } deriving (Eq, Show)
1916−
713+
1917−data DateHistogramAggregation = DateHistogramAggregation { dateField :: FieldName
714+data DateHistogramAggregation = DateHistogramAggregation
715+ { dateField :: FieldName
1918− , dateInterval :: Interval
716+ , dateInterval :: Interval
1919− , dateFormat :: Maybe Text
717+ , dateFormat :: Maybe Text
1920− -- pre and post deprecated in 1.5
718+ -- pre and post deprecated in 1.5
1921− , datePreZone :: Maybe Text
719+ , datePreZone :: Maybe Text
1922− , datePostZone :: Maybe Text
720+ , datePostZone :: Maybe Text
1923− , datePreOffset :: Maybe Text
721+ , datePreOffset :: Maybe Text
1924− , datePostOffset :: Maybe Text
722+ , datePostOffset :: Maybe Text
1925− , dateAggs :: Maybe Aggregations
723+ , dateAggs :: Maybe Aggregations
1926− } deriving (Eq, Read, Show, Generic, Typeable)
724+ } deriving (Eq, Show)
1927−
725+
1928−
1929−data DateRangeAggregation = DateRangeAggregation { draField :: FieldName
726+data DateRangeAggregation = DateRangeAggregation
727+ { draField :: FieldName
1930− , draFormat :: Maybe Text
728+ , draFormat :: Maybe Text
1931− , draRanges :: NonEmpty DateRangeAggRange
729+ , draRanges :: NonEmpty DateRangeAggRange
1932− } deriving (Eq, Read, Show, Generic, Typeable)
730+ } deriving (Eq, Show)
1933−
731+
732+data DateRangeAggRange =
1934−data DateRangeAggRange = DateRangeFrom DateMathExpr
733+ DateRangeFrom DateMathExpr
1935− | DateRangeTo DateMathExpr
734+ | DateRangeTo DateMathExpr
1936− | DateRangeFromAndTo DateMathExpr DateMathExpr deriving (Eq, Read, Show, Generic, Typeable)
735+ | DateRangeFromAndTo DateMathExpr DateMathExpr
736+ deriving (Eq, Show)
1937
737
1938-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math> for more information.
738-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math> for more information.
739+data DateMathExpr =
1939−data DateMathExpr = DateMathExpr DateMathAnchor [DateMathModifier] deriving (Eq, Read, Show, Generic, Typeable)
740+ DateMathExpr DateMathAnchor [DateMathModifier]
741+ deriving (Eq, Show)
1940
742
1941
743
1942-- | Starting point for a date range. This along with the 'DateMathModifiers' gets you the date ES will start from.
744-- | Starting point for a date range. This along with the 'DateMathModifiers' gets you the date ES will start from.
1943−data DateMathAnchor = DMNow
745+data DateMathAnchor =
746+ DMNow
747+ | DMDate Day
1944− | DMDate Day deriving (Eq, Read, Show, Generic, Typeable)
748+ deriving (Eq, Show)
1945−
749+
750+data DateMathModifier =
1946−data DateMathModifier = AddTime Int DateMathUnit
751+ AddTime Int DateMathUnit
1947− | SubtractTime Int DateMathUnit
752+ | SubtractTime Int DateMathUnit
1948− | RoundDownTo DateMathUnit deriving (Eq, Read, Show, Generic, Typeable)
753+ | RoundDownTo DateMathUnit
1949−
754+ deriving (Eq, Show)
755+
1950−data DateMathUnit = DMYear
756+data DateMathUnit =
757+ DMYear
1951− | DMMonth
758+ | DMMonth
1952− | DMWeek
759+ | DMWeek
1953− | DMDay
760+ | DMDay
1954− | DMHour
761+ | DMHour
1955− | DMMinute
762+ | DMMinute
763+ | DMSecond
1956− | DMSecond deriving (Eq, Read, Show, Generic, Typeable)
764+ deriving (Eq, Show)
1957
765
1958-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html> for more information.
766-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html> for more information.
1959−data ValueCountAggregation = FieldValueCount FieldName
767+data ValueCountAggregation =
768+ FieldValueCount FieldName
1960− | ScriptValueCount Script deriving (Eq, Read, Show, Generic, Typeable)
769+ | ScriptValueCount Script
770+ deriving (Eq, Show)
1961
771
1962-- | Single-bucket filter aggregations. See <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filter-aggregation.html#search-aggregations-bucket-filter-aggregation> for more information.
772-- | Single-bucket filter aggregations. See <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filter-aggregation.html#search-aggregations-bucket-filter-aggregation> for more information.
1963−data FilterAggregation = FilterAggregation { faFilter :: Filter
773+data FilterAggregation = FilterAggregation
774+ { faFilter :: Filter
1964− , faAggs :: Maybe Aggregations} deriving (Eq, Read, Show, Generic, Typeable)
775+ , faAggs :: Maybe Aggregations }
776+ deriving (Eq, Show)
1965
777
1966−data StatisticsAggregation = StatisticsAggregation { statsType :: StatsType
778+data StatisticsAggregation = StatisticsAggregation
779+ { statsType :: StatsType
1967− , statsField :: FieldName } deriving (Eq, Read, Show, Generic, Typeable)
780+ , statsField :: FieldName }
781+ deriving (Eq, Show)
1968
782
1969data StatsType
783data StatsType
1970 = Basic
784 = Basic
1971 | Extended
785 | Extended
1972− deriving (Eq, Read, Show, Generic, Typeable)
786+ deriving (Eq, Show)
1973
787
1974mkTermsAggregation :: Text -> TermsAggregation
788mkTermsAggregation :: Text -> TermsAggregation
789+mkTermsAggregation t =
790+ TermsAggregation (Left t)
1975−mkTermsAggregation t = TermsAggregation (Left t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
791+ Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1976
792
1977mkTermsScriptAggregation :: Text -> TermsAggregation
793mkTermsScriptAggregation :: Text -> TermsAggregation
1978mkTermsScriptAggregation t = TermsAggregation (Right t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
794mkTermsScriptAggregation t = TermsAggregation (Right t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
@@ -1989,33 +805,6 @@ mkStatsAggregation = StatisticsAggregation Basic
1989mkExtendedStatsAggregation :: FieldName -> StatisticsAggregation
805mkExtendedStatsAggregation :: FieldName -> StatisticsAggregation
1990mkExtendedStatsAggregation = StatisticsAggregation Extended
806mkExtendedStatsAggregation = StatisticsAggregation Extended
1991
807
1992−instance ToJSON Version where
1993− toJSON Version {..} = object ["number" .= number
1994− ,"build_hash" .= build_hash
1995− ,"build_date" .= build_date
1996− ,"build_snapshot" .= build_snapshot
1997− ,"lucene_version" .= lucene_version]
1998−
1999−instance FromJSON Version where
2000− parseJSON = withObject "Version" parse
2001− where parse o = Version
2002− <$> o .: "number"
2003− <*> o .: "build_hash"
2004− <*> o .: "build_date"
2005− <*> o .: "build_snapshot"
2006− <*> o .: "lucene_version"
2007−
2008−instance ToJSON VersionNumber where
2009− toJSON = toJSON . Vers.showVersion . versionNumber
2010−
2011−instance FromJSON VersionNumber where
2012− parseJSON = withText "VersionNumber" (parse . T.unpack)
2013− where
2014− parse s = case filter (null . snd)(RP.readP_to_S Vers.parseVersion s) of
2015− [(v, _)] -> pure (VersionNumber v)
2016− [] -> fail ("Invalid version string " ++ s)
2017− xs -> fail ("Ambiguous version string " ++ s ++ " (" ++ intercalate ", " (Vers.showVersion . fst <$> xs) ++ ")")
2018−
2019instance ToJSON TermOrder where
808instance ToJSON TermOrder where
2020 toJSON (TermOrder termSortField termSortOrder) = object [termSortField .= termSortOrder]
809 toJSON (TermOrder termSortField termSortOrder) = object [termSortField .= termSortOrder]
2021
810
@@ -2045,23 +834,6 @@ instance ToJSON Interval where
2045 toJSON Minute = "minute"
834 toJSON Minute = "minute"
2046 toJSON Second = "second"
835 toJSON Second = "second"
2047
836
2048−instance Show TimeInterval where
2049− show Weeks = "w"
2050− show Days = "d"
2051− show Hours = "h"
2052− show Minutes = "m"
2053− show Seconds = "s"
2054−
2055−instance Read TimeInterval where
2056− readPrec = f =<< TR.get
2057− where
2058− f 'w' = return Weeks
2059− f 'd' = return Days
2060− f 'h' = return Hours
2061− f 'm' = return Minutes
2062− f 's' = return Seconds
2063− f _ = fail "TimeInterval expected one of w, d, h, m, s"
2064−
2065instance ToJSON Aggregation where
837instance ToJSON Aggregation where
2066 toJSON (TermsAgg (TermsAggregation term include exclude order minDocCount size shardSize collectMode executionHint termAggs)) =
838 toJSON (TermsAgg (TermsAggregation term include exclude order minDocCount size shardSize collectMode executionHint termAggs)) =
2067 omitNulls ["terms" .= omitNulls [ toJSON' term,
839 omitNulls ["terms" .= omitNulls [ toJSON' term,
@@ -2175,13 +947,15 @@ data DateHistogramResult = DateHistogramResult { dateKey :: Int
2175 , dateDocCount :: Int
947 , dateDocCount :: Int
2176 , dateHistogramAggs :: Maybe AggregationResults } deriving (Read, Show)
948 , dateHistogramAggs :: Maybe AggregationResults } deriving (Read, Show)
2177
949
950+data DateRangeResult =
2178−data DateRangeResult = DateRangeResult { dateRangeKey :: Text
951+ DateRangeResult { dateRangeKey :: Text
2179− , dateRangeFrom :: Maybe UTCTime
952+ , dateRangeFrom :: Maybe UTCTime
2180− , dateRangeFromAsString :: Maybe Text
953+ , dateRangeFromAsString :: Maybe Text
2181− , dateRangeTo :: Maybe UTCTime
954+ , dateRangeTo :: Maybe UTCTime
2182− , dateRangeToAsString :: Maybe Text
955+ , dateRangeToAsString :: Maybe Text
2183− , dateRangeDocCount :: Int
956+ , dateRangeDocCount :: Int
2184− , dateRangeAggs :: Maybe AggregationResults } deriving (Read, Show, Eq, Generic, Typeable)
957+ , dateRangeAggs :: Maybe AggregationResults }
958+ deriving (Eq, Show)
2185
959
2186toTerms :: Text -> AggregationResults -> Maybe (Bucket TermsResult)
960toTerms :: Text -> AggregationResults -> Maybe (Bucket TermsResult)
2187toTerms = toAggResult
961toTerms = toAggResult
@@ -2266,21 +1040,11 @@ instance FromJSON DateRangeResult where
2266 ]
1040 ]
2267 )
1041 )
2268
1042
2269−instance FromJSON POSIXMS where
2270− parseJSON = withScientific "POSIXMS" (return . parse)
2271− where parse n = let n' = truncate n :: Integer
2272− in POSIXMS (posixSecondsToUTCTime (fromInteger (n' `div` 1000)))
2273−
2274instance (FromJSON a) => FromJSON (TopHitResult a) where
1043instance (FromJSON a) => FromJSON (TopHitResult a) where
2275 parseJSON (Object v) = TopHitResult <$>
1044 parseJSON (Object v) = TopHitResult <$>
2276 v .: "hits"
1045 v .: "hits"
2277 parseJSON _ = fail "Failure in FromJSON (TopHitResult a)"
1046 parseJSON _ = fail "Failure in FromJSON (TopHitResult a)"
2278
1047
2279−fieldTagged :: Monad m => (FieldName -> Object -> m a) -> Object -> m a
2280−fieldTagged f o = case HM.toList o of
2281− [(k, Object o')] -> f (FieldName k) o'
2282− _ -> fail "Expected object with 1 field-named key"
2283−
2284-- Try to get an AggregationResults when we don't know the
1048-- Try to get an AggregationResults when we don't know the
2285-- field name. We filter out the known keys to try to minimize the noise.
1049-- field name. We filter out the known keys to try to minimize the noise.
2286getNamedSubAgg :: Object -> [Text] -> Maybe AggregationResults
1050getNamedSubAgg :: Object -> [Text] -> Maybe AggregationResults
@@ -2295,765 +1059,9 @@ instance ToJSON GeoPoint where
2295 object [ geoPointField .= geoPointLatLon ]
1059 object [ geoPointField .= geoPointLatLon ]
2296
1060
2297
1061
2298−instance ToJSON Query where
2299− toJSON (TermQuery (Term termQueryField termQueryValue) boost) =
2300− object [ "term" .=
2301− object [termQueryField .= object merged]]
2302− where
2303− base = [ "value" .= termQueryValue ]
2304− boosted = maybe [] (return . ("boost" .=)) boost
2305− merged = mappend base boosted
2306−
2307− toJSON (TermsQuery fieldName terms) =
2308− object [ "terms" .= object conjoined ]
2309− where conjoined = [fieldName .= terms]
2310−
2311− toJSON (IdsQuery idsQueryMappingName docIds) =
2312− object [ "ids" .= object conjoined ]
2313− where conjoined = [ "type" .= idsQueryMappingName
2314− , "values" .= fmap toJSON docIds ]
2315−
2316− toJSON (QueryQueryStringQuery qQueryStringQuery) =
2317− object [ "query_string" .= qQueryStringQuery ]
2318−
2319− toJSON (QueryMatchQuery matchQuery) =
2320− object [ "match" .= matchQuery ]
2321−
2322− toJSON (QueryMultiMatchQuery multiMatchQuery) =
2323− toJSON multiMatchQuery
2324−
2325− toJSON (QueryBoolQuery boolQuery) =
2326− object [ "bool" .= boolQuery ]
2327−
2328− toJSON (QueryBoostingQuery boostingQuery) =
2329− object [ "boosting" .= boostingQuery ]
2330−
2331− toJSON (QueryCommonTermsQuery commonTermsQuery) =
2332− object [ "common" .= commonTermsQuery ]
2333−
2334− toJSON (ConstantScoreQuery query boost) =
2335− object ["constant_score" .= object ["query" .= query
2336− , "boost" .= boost]]
2337
1062
2338− toJSON (QueryDisMaxQuery disMaxQuery) =
2339− object [ "dis_max" .= disMaxQuery ]
2340
1063
2341− toJSON (QueryFuzzyLikeThisQuery fuzzyQuery) =
2342− object [ "fuzzy_like_this" .= fuzzyQuery ]
2343
1064
2344− toJSON (QueryFuzzyLikeFieldQuery fuzzyFieldQuery) =
2345− object [ "fuzzy_like_this_field" .= fuzzyFieldQuery ]
2346−
2347− toJSON (QueryFuzzyQuery fuzzyQuery) =
2348− object [ "fuzzy" .= fuzzyQuery ]
2349−
2350− toJSON (QueryHasChildQuery childQuery) =
2351− object [ "has_child" .= childQuery ]
2352−
2353− toJSON (QueryHasParentQuery parentQuery) =
2354− object [ "has_parent" .= parentQuery ]
2355−
2356− toJSON (QueryIndicesQuery qIndicesQuery) =
2357− object [ "indices" .= qIndicesQuery ]
2358−
2359− toJSON (MatchAllQuery boost) =
2360− object [ "match_all" .= omitNulls [ "boost" .= boost ] ]
2361−
2362− toJSON (QueryMoreLikeThisQuery query) =
2363− object [ "more_like_this" .= query ]
2364−
2365− toJSON (QueryMoreLikeThisFieldQuery query) =
2366− object [ "more_like_this_field" .= query ]
2367−
2368− toJSON (QueryNestedQuery query) =
2369− object [ "nested" .= query ]
2370−
2371− toJSON (QueryPrefixQuery query) =
2372− object [ "prefix" .= query ]
2373−
2374− toJSON (QueryRangeQuery query) =
2375− object [ "range" .= query ]
2376−
2377− toJSON (QueryRegexpQuery query) =
2378− object [ "regexp" .= query ]
2379−
2380− toJSON (QuerySimpleQueryStringQuery query) =
2381− object [ "simple_query_string" .= query ]
2382−
2383− toJSON (QueryExistsQuery (FieldName fieldName)) =
2384− object ["exists" .= object
2385− ["field" .= fieldName]
2386− ]
2387− toJSON QueryMatchNoneQuery =
2388− object ["match_none" .= object []]
2389−
2390− toJSON (QueryTemplateQueryInline templateQuery) =
2391− object [ "template" .= templateQuery ]
2392−
2393−instance FromJSON Query where
2394− parseJSON v = withObject "Query" parse v
2395− where parse o = termQuery `taggedWith` "term"
2396− <|> termsQuery `taggedWith` "terms"
2397− <|> idsQuery `taggedWith` "ids"
2398− <|> queryQueryStringQuery `taggedWith` "query_string"
2399− <|> queryMatchQuery `taggedWith` "match"
2400− <|> queryMultiMatchQuery
2401− <|> queryBoolQuery `taggedWith` "bool"
2402− <|> queryBoostingQuery `taggedWith` "boosting"
2403− <|> queryCommonTermsQuery `taggedWith` "common"
2404− <|> constantScoreQuery `taggedWith` "constant_score"
2405− <|> queryDisMaxQuery `taggedWith` "dis_max"
2406− <|> queryFuzzyLikeThisQuery `taggedWith` "fuzzy_like_this"
2407− <|> queryFuzzyLikeFieldQuery `taggedWith` "fuzzy_like_this_field"
2408− <|> queryFuzzyQuery `taggedWith` "fuzzy"
2409− <|> queryHasChildQuery `taggedWith` "has_child"
2410− <|> queryHasParentQuery `taggedWith` "has_parent"
2411− <|> queryIndicesQuery `taggedWith` "indices"
2412− <|> matchAllQuery `taggedWith` "match_all"
2413− <|> queryMoreLikeThisQuery `taggedWith` "more_like_this"
2414− <|> queryMoreLikeThisFieldQuery `taggedWith` "more_like_this_field"
2415− <|> queryNestedQuery `taggedWith` "nested"
2416− <|> queryPrefixQuery `taggedWith` "prefix"
2417− <|> queryRangeQuery `taggedWith` "range"
2418− <|> queryRegexpQuery `taggedWith` "regexp"
2419− <|> querySimpleQueryStringQuery `taggedWith` "simple_query_string"
2420− <|> queryTemplateQueryInline `taggedWith` "template"
2421− where taggedWith parser k = parser =<< o .: k
2422− termQuery = fieldTagged $ \(FieldName fn) o ->
2423− TermQuery <$> (Term fn <$> o .: "value") <*> o .:? "boost"
2424− termsQuery o = case HM.toList o of
2425− [(fn, vs)] -> do vals <- parseJSON vs
2426− case vals of
2427− x:xs -> return (TermsQuery fn (x :| xs))
2428− _ -> fail "Expected non empty list of values"
2429− _ -> fail "Expected object with 1 field-named key"
2430− idsQuery o = IdsQuery <$> o .: "type"
2431− <*> o .: "values"
2432− queryQueryStringQuery = pure . QueryQueryStringQuery
2433− queryMatchQuery = pure . QueryMatchQuery
2434− queryMultiMatchQuery = QueryMultiMatchQuery <$> parseJSON v
2435− queryBoolQuery = pure . QueryBoolQuery
2436− queryBoostingQuery = pure . QueryBoostingQuery
2437− queryCommonTermsQuery = pure . QueryCommonTermsQuery
2438− constantScoreQuery o = case HM.lookup "query" o of
2439− Just x -> ConstantScoreQuery <$> parseJSON x
2440− <*> o .: "boost"
2441− _ -> fail "Does not appear to be a ConstantScoreQuery"
2442− queryDisMaxQuery = pure . QueryDisMaxQuery
2443− queryFuzzyLikeThisQuery = pure . QueryFuzzyLikeThisQuery
2444− queryFuzzyLikeFieldQuery = pure . QueryFuzzyLikeFieldQuery
2445− queryFuzzyQuery = pure . QueryFuzzyQuery
2446− queryHasChildQuery = pure . QueryHasChildQuery
2447− queryHasParentQuery = pure . QueryHasParentQuery
2448− queryIndicesQuery = pure . QueryIndicesQuery
2449− matchAllQuery o = MatchAllQuery <$> o .:? "boost"
2450− queryMoreLikeThisQuery = pure . QueryMoreLikeThisQuery
2451− queryMoreLikeThisFieldQuery = pure . QueryMoreLikeThisFieldQuery
2452− queryNestedQuery = pure . QueryNestedQuery
2453− queryPrefixQuery = pure . QueryPrefixQuery
2454− queryRangeQuery = pure . QueryRangeQuery
2455− queryRegexpQuery = pure . QueryRegexpQuery
2456− querySimpleQueryStringQuery = pure . QuerySimpleQueryStringQuery
2457− -- queryExistsQuery o = QueryExistsQuery <$> o .: "field"
2458− queryTemplateQueryInline = pure . QueryTemplateQueryInline
2459−
2460−
2461−omitNulls :: [(Text, Value)] -> Value
2462−omitNulls = object . filter notNull where
2463− notNull (_, Null) = False
2464− notNull (_, Array a) = (not . V.null) a
2465− notNull _ = True
2466−
2467−instance ToJSON SimpleQueryStringQuery where
2468− toJSON SimpleQueryStringQuery {..} =
2469− omitNulls (base ++ maybeAdd)
2470− where base = [ "query" .= simpleQueryStringQuery ]
2471− maybeAdd = [ "fields" .= simpleQueryStringField
2472− , "default_operator" .= simpleQueryStringOperator
2473− , "analyzer" .= simpleQueryStringAnalyzer
2474− , "flags" .= simpleQueryStringFlags
2475− , "lowercase_expanded_terms" .= simpleQueryStringLowercaseExpanded
2476− , "locale" .= simpleQueryStringLocale ]
2477−
2478−instance FromJSON SimpleQueryStringQuery where
2479− parseJSON = withObject "SimpleQueryStringQuery" parse
2480− where parse o = SimpleQueryStringQuery <$> o .: "query"
2481− <*> o .:? "fields"
2482− <*> o .:? "default_operator"
2483− <*> o .:? "analyzer"
2484− <*> (parseFlags <$> o .:? "flags")
2485− <*> o .:? "lowercase_expanded_terms"
2486− <*> o .:? "locale"
2487− parseFlags (Just (x:xs)) = Just (x :| xs)
2488− parseFlags _ = Nothing
2489−
2490−instance ToJSON FieldOrFields where
2491− toJSON (FofField fieldName) =
2492− toJSON fieldName
2493− toJSON (FofFields fieldNames) =
2494− toJSON fieldNames
2495−
2496−instance FromJSON FieldOrFields where
2497− parseJSON v = FofField <$> parseJSON v
2498− <|> FofFields <$> (parseNEJSON =<< parseJSON v)
2499−
2500−instance ToJSON SimpleQueryFlag where
2501− toJSON SimpleQueryAll = "ALL"
2502− toJSON SimpleQueryNone = "NONE"
2503− toJSON SimpleQueryAnd = "AND"
2504− toJSON SimpleQueryOr = "OR"
2505− toJSON SimpleQueryPrefix = "PREFIX"
2506− toJSON SimpleQueryPhrase = "PHRASE"
2507− toJSON SimpleQueryPrecedence = "PRECEDENCE"
2508− toJSON SimpleQueryEscape = "ESCAPE"
2509− toJSON SimpleQueryWhitespace = "WHITESPACE"
2510− toJSON SimpleQueryFuzzy = "FUZZY"
2511− toJSON SimpleQueryNear = "NEAR"
2512− toJSON SimpleQuerySlop = "SLOP"
2513−
2514−instance FromJSON SimpleQueryFlag where
2515− parseJSON = withText "SimpleQueryFlag" parse
2516− where parse "ALL" = pure SimpleQueryAll
2517− parse "NONE" = pure SimpleQueryNone
2518− parse "AND" = pure SimpleQueryAnd
2519− parse "OR" = pure SimpleQueryOr
2520− parse "PREFIX" = pure SimpleQueryPrefix
2521− parse "PHRASE" = pure SimpleQueryPhrase
2522− parse "PRECEDENCE" = pure SimpleQueryPrecedence
2523− parse "ESCAPE" = pure SimpleQueryEscape
2524− parse "WHITESPACE" = pure SimpleQueryWhitespace
2525− parse "FUZZY" = pure SimpleQueryFuzzy
2526− parse "NEAR" = pure SimpleQueryNear
2527− parse "SLOP" = pure SimpleQuerySlop
2528− parse f = fail ("Unexpected SimpleQueryFlag: " <> show f)
2529−
2530−instance ToJSON RegexpQuery where
2531− toJSON (RegexpQuery (FieldName rqQueryField)
2532− (Regexp regexpQueryQuery) rqQueryFlags
2533− rqQueryBoost) =
2534− object [ rqQueryField .= omitNulls base ]
2535− where base = [ "value" .= regexpQueryQuery
2536− , "flags" .= rqQueryFlags
2537− , "boost" .= rqQueryBoost ]
2538−
2539−instance FromJSON RegexpQuery where
2540− parseJSON = withObject "RegexpQuery" parse
2541− where parse = fieldTagged $ \fn o ->
2542− RegexpQuery fn
2543− <$> o .: "value"
2544− <*> o .: "flags"
2545− <*> o .:? "boost"
2546−
2547−instance ToJSON QueryStringQuery where
2548− toJSON (QueryStringQuery qsQueryString
2549− qsDefaultField qsOperator
2550− qsAnalyzer qsAllowWildcard
2551− qsLowercaseExpanded qsEnablePositionIncrements
2552− qsFuzzyMaxExpansions qsFuzziness
2553− qsFuzzyPrefixLength qsPhraseSlop
2554− qsBoost qsAnalyzeWildcard
2555− qsGeneratePhraseQueries qsMinimumShouldMatch
2556− qsLenient qsLocale) =
2557− omitNulls base
2558− where
2559− base = [ "query" .= qsQueryString
2560− , "default_field" .= qsDefaultField
2561− , "default_operator" .= qsOperator
2562− , "analyzer" .= qsAnalyzer
2563− , "allow_leading_wildcard" .= qsAllowWildcard
2564− , "lowercase_expanded_terms" .= qsLowercaseExpanded
2565− , "enable_position_increments" .= qsEnablePositionIncrements
2566− , "fuzzy_max_expansions" .= qsFuzzyMaxExpansions
2567− , "fuzziness" .= qsFuzziness
2568− , "fuzzy_prefix_length" .= qsFuzzyPrefixLength
2569− , "phrase_slop" .= qsPhraseSlop
2570− , "boost" .= qsBoost
2571− , "analyze_wildcard" .= qsAnalyzeWildcard
2572− , "auto_generate_phrase_queries" .= qsGeneratePhraseQueries
2573− , "minimum_should_match" .= qsMinimumShouldMatch
2574− , "lenient" .= qsLenient
2575− , "locale" .= qsLocale ]
2576−
2577−instance FromJSON QueryStringQuery where
2578− parseJSON = withObject "QueryStringQuery" parse
2579− where parse o = QueryStringQuery
2580− <$> o .: "query"
2581− <*> o .:? "default_field"
2582− <*> o .:? "default_operator"
2583− <*> o .:? "analyzer"
2584− <*> o .:? "allow_leading_wildcard"
2585− <*> o .:? "lowercase_expanded_terms"
2586− <*> o .:? "enable_position_increments"
2587− <*> o .:? "fuzzy_max_expansions"
2588− <*> o .:? "fuzziness"
2589− <*> o .:? "fuzzy_prefix_length"
2590− <*> o .:? "phrase_slop"
2591− <*> o .:? "boost"
2592− <*> o .:? "analyze_wildcard"
2593− <*> o .:? "auto_generate_phrase_queries"
2594− <*> o .:? "minimum_should_match"
2595− <*> o .:? "lenient"
2596− <*> o .:? "locale"
2597−
2598−instance ToJSON RangeQuery where
2599− toJSON (RangeQuery (FieldName fieldName) range boost) =
2600− object [ fieldName .= object conjoined ]
2601− where conjoined = [ "boost" .= boost ] ++ (rangeValueToPair range)
2602−
2603−instance FromJSON RangeQuery where
2604− parseJSON = withObject "RangeQuery" parse
2605− where parse = fieldTagged $ \fn o ->
2606− RangeQuery fn
2607− <$> parseJSON (Object o)
2608− <*> o .: "boost"
2609−
2610−instance FromJSON RangeValue where
2611− parseJSON = withObject "RangeValue" parse
2612− where parse o = parseDate o
2613− <|> parseDouble o
2614− parseDate o = do lt <- o .:? "lt"
2615− lte <- o .:? "lte"
2616− gt <- o .:? "gt"
2617− gte <- o .:? "gte"
2618− case (lt, lte, gt, gte) of
2619− (Just a, _, Just b, _) -> return (RangeDateGtLt (GreaterThanD b) (LessThanD a))
2620− (Just a, _, _, Just b)-> return (RangeDateGteLt (GreaterThanEqD b) (LessThanD a))
2621− (_, Just a, Just b, _)-> return (RangeDateGtLte (GreaterThanD b) (LessThanEqD a))
2622− (_, Just a, _, Just b)-> return (RangeDateGteLte (GreaterThanEqD b) (LessThanEqD a))
2623− (_, _, Just a, _)-> return (RangeDateGt (GreaterThanD a))
2624− (Just a, _, _, _)-> return (RangeDateLt (LessThanD a))
2625− (_, _, _, Just a)-> return (RangeDateGte (GreaterThanEqD a))
2626− (_, Just a, _, _)-> return (RangeDateLte (LessThanEqD a))
2627− (Nothing, Nothing, Nothing, Nothing) -> mzero
2628− parseDouble o = do lt <- o .:? "lt"
2629− lte <- o .:? "lte"
2630− gt <- o .:? "gt"
2631− gte <- o .:? "gte"
2632− case (lt, lte, gt, gte) of
2633− (Just a, _, Just b, _) -> return (RangeDoubleGtLt (GreaterThan b) (LessThan a))
2634− (Just a, _, _, Just b)-> return (RangeDoubleGteLt (GreaterThanEq b) (LessThan a))
2635− (_, Just a, Just b, _)-> return (RangeDoubleGtLte (GreaterThan b) (LessThanEq a))
2636− (_, Just a, _, Just b)-> return (RangeDoubleGteLte (GreaterThanEq b) (LessThanEq a))
2637− (_, _, Just a, _)-> return (RangeDoubleGt (GreaterThan a))
2638− (Just a, _, _, _)-> return (RangeDoubleLt (LessThan a))
2639− (_, _, _, Just a)-> return (RangeDoubleGte (GreaterThanEq a))
2640− (_, Just a, _, _)-> return (RangeDoubleLte (LessThanEq a))
2641− (Nothing, Nothing, Nothing, Nothing) -> mzero
2642−
2643−instance ToJSON PrefixQuery where
2644− toJSON (PrefixQuery (FieldName fieldName) queryValue boost) =
2645− object [ fieldName .= omitNulls base ]
2646− where base = [ "value" .= queryValue
2647− , "boost" .= boost ]
2648−
2649−instance FromJSON PrefixQuery where
2650− parseJSON = withObject "PrefixQuery" parse
2651− where parse = fieldTagged $ \fn o ->
2652− PrefixQuery fn
2653− <$> o .: "value"
2654− <*> o .:? "boost"
2655−
2656−instance ToJSON NestedQuery where
2657− toJSON (NestedQuery nqPath nqScoreType nqQuery) =
2658− object [ "path" .= nqPath
2659− , "score_mode" .= nqScoreType
2660− , "query" .= nqQuery ]
2661−
2662−instance FromJSON NestedQuery where
2663− parseJSON = withObject "NestedQuery" parse
2664− where parse o = NestedQuery
2665− <$> o .: "path"
2666− <*> o .: "score_mode"
2667− <*> o .: "query"
2668−
2669−instance ToJSON MoreLikeThisFieldQuery where
2670− toJSON (MoreLikeThisFieldQuery text (FieldName fieldName)
2671− percent mtf mqt stopwords mindf maxdf
2672− minwl maxwl boostTerms boost analyzer) =
2673− object [ fieldName .= omitNulls base ]
2674− where base = [ "like_text" .= text
2675− , "percent_terms_to_match" .= percent
2676− , "min_term_freq" .= mtf
2677− , "max_query_terms" .= mqt
2678− , "stop_words" .= stopwords
2679− , "min_doc_freq" .= mindf
2680− , "max_doc_freq" .= maxdf
2681− , "min_word_length" .= minwl
2682− , "max_word_length" .= maxwl
2683− , "boost_terms" .= boostTerms
2684− , "boost" .= boost
2685− , "analyzer" .= analyzer ]
2686−
2687−instance FromJSON MoreLikeThisFieldQuery where
2688− parseJSON = withObject "MoreLikeThisFieldQuery" parse
2689− where parse = fieldTagged $ \fn o ->
2690− MoreLikeThisFieldQuery
2691− <$> o .: "like_text"
2692− <*> pure fn
2693− <*> o .:? "percent_terms_to_match"
2694− <*> o .:? "min_term_freq"
2695− <*> o .:? "max_query_terms"
2696− -- <*> (optionalNE =<< o .:? "stop_words")
2697− <*> o .:? "stop_words"
2698− <*> o .:? "min_doc_freq"
2699− <*> o .:? "max_doc_freq"
2700− <*> o .:? "min_word_length"
2701− <*> o .:? "max_word_length"
2702− <*> o .:? "boost_terms"
2703− <*> o .:? "boost"
2704− <*> o .:? "analyzer"
2705− -- optionalNE = maybe (pure Nothing) (fmap Just . parseNEJSON)
2706−
2707−instance ToJSON MoreLikeThisQuery where
2708− toJSON (MoreLikeThisQuery text fields percent
2709− mtf mqt stopwords mindf maxdf
2710− minwl maxwl boostTerms boost analyzer) =
2711− omitNulls base
2712− where base = [ "like_text" .= text
2713− , "fields" .= fields
2714− , "percent_terms_to_match" .= percent
2715− , "min_term_freq" .= mtf
2716− , "max_query_terms" .= mqt
2717− , "stop_words" .= stopwords
2718− , "min_doc_freq" .= mindf
2719− , "max_doc_freq" .= maxdf
2720− , "min_word_length" .= minwl
2721− , "max_word_length" .= maxwl
2722− , "boost_terms" .= boostTerms
2723− , "boost" .= boost
2724− , "analyzer" .= analyzer ]
2725−
2726−instance FromJSON MoreLikeThisQuery where
2727− parseJSON = withObject "MoreLikeThisQuery" parse
2728− where parse o = MoreLikeThisQuery
2729− <$> o .: "like_text"
2730− -- <*> (optionalNE =<< o .:? "fields")
2731− <*> o .:? "fields"
2732− <*> o .:? "percent_terms_to_match"
2733− <*> o .:? "min_term_freq"
2734− <*> o .:? "max_query_terms"
2735− -- <*> (optionalNE =<< o .:? "stop_words")
2736− <*> o .:? "stop_words"
2737− <*> o .:? "min_doc_freq"
2738− <*> o .:? "max_doc_freq"
2739− <*> o .:? "min_word_length"
2740− <*> o .:? "max_word_length"
2741− <*> o .:? "boost_terms"
2742− <*> o .:? "boost"
2743− <*> o .:? "analyzer"
2744− -- optionalNE = maybe (pure Nothing) (fmap Just . parseNEJSON)
2745−
2746−instance ToJSON IndicesQuery where
2747− toJSON (IndicesQuery indices query noMatch) =
2748− omitNulls [ "indices" .= indices
2749− , "no_match_query" .= noMatch
2750− , "query" .= query ]
2751−
2752−instance FromJSON IndicesQuery where
2753− parseJSON = withObject "IndicesQuery" parse
2754− where parse o = IndicesQuery
2755− <$> o .:? "indices" .!= []
2756− <*> o .: "query"
2757− <*> o .:? "no_match_query"
2758−
2759−instance ToJSON HasParentQuery where
2760− toJSON (HasParentQuery queryType query scoreType) =
2761− omitNulls [ "parent_type" .= queryType
2762− , "score_type" .= scoreType
2763− , "query" .= query ]
2764−
2765−instance FromJSON HasParentQuery where
2766− parseJSON = withObject "HasParentQuery" parse
2767− where parse o = HasParentQuery
2768− <$> o .: "parent_type"
2769− <*> o .: "query"
2770− <*> o .:? "score_type"
2771−
2772−instance ToJSON HasChildQuery where
2773− toJSON (HasChildQuery queryType query scoreType) =
2774− omitNulls [ "query" .= query
2775− , "score_type" .= scoreType
2776− , "type" .= queryType ]
2777−
2778−instance FromJSON HasChildQuery where
2779− parseJSON = withObject "HasChildQuery" parse
2780− where parse o = HasChildQuery
2781− <$> o .: "type"
2782− <*> o .: "query"
2783− <*> o .:? "score_type"
2784−
2785−instance ToJSON FuzzyQuery where
2786− toJSON (FuzzyQuery (FieldName fieldName) queryText
2787− prefixLength maxEx fuzziness boost) =
2788− object [ fieldName .= omitNulls base ]
2789− where base = [ "value" .= queryText
2790− , "fuzziness" .= fuzziness
2791− , "prefix_length" .= prefixLength
2792− , "boost" .= boost
2793− , "max_expansions" .= maxEx ]
2794−
2795−instance FromJSON FuzzyQuery where
2796− parseJSON = withObject "FuzzyQuery" parse
2797− where parse = fieldTagged $ \fn o ->
2798− FuzzyQuery fn
2799− <$> o .: "value"
2800− <*> o .: "prefix_length"
2801− <*> o .: "max_expansions"
2802− <*> o .: "fuzziness"
2803− <*> o .:? "boost"
2804−
2805−instance ToJSON FuzzyLikeFieldQuery where
2806− toJSON (FuzzyLikeFieldQuery (FieldName fieldName)
2807− fieldText maxTerms ignoreFreq fuzziness prefixLength
2808− boost analyzer) =
2809− object [ fieldName .=
2810− omitNulls [ "like_text" .= fieldText
2811− , "max_query_terms" .= maxTerms
2812− , "ignore_tf" .= ignoreFreq
2813− , "fuzziness" .= fuzziness
2814− , "prefix_length" .= prefixLength
2815− , "analyzer" .= analyzer
2816− , "boost" .= boost ]]
2817−
2818−instance FromJSON FuzzyLikeFieldQuery where
2819− parseJSON = withObject "FuzzyLikeFieldQuery" parse
2820− where parse = fieldTagged $ \fn o ->
2821− FuzzyLikeFieldQuery fn
2822− <$> o .: "like_text"
2823− <*> o .: "max_query_terms"
2824− <*> o .: "ignore_tf"
2825− <*> o .: "fuzziness"
2826− <*> o .: "prefix_length"
2827− <*> o .: "boost"
2828− <*> o .:? "analyzer"
2829−
2830−instance ToJSON FuzzyLikeThisQuery where
2831− toJSON (FuzzyLikeThisQuery fields text maxTerms
2832− ignoreFreq fuzziness prefixLength boost analyzer) =
2833− omitNulls base
2834− where base = [ "fields" .= fields
2835− , "like_text" .= text
2836− , "max_query_terms" .= maxTerms
2837− , "ignore_tf" .= ignoreFreq
2838− , "fuzziness" .= fuzziness
2839− , "prefix_length" .= prefixLength
2840− , "analyzer" .= analyzer
2841− , "boost" .= boost ]
2842−
2843−instance FromJSON FuzzyLikeThisQuery where
2844− parseJSON = withObject "FuzzyLikeThisQuery" parse
2845− where parse o = FuzzyLikeThisQuery
2846− <$> o .:? "fields" .!= []
2847− <*> o .: "like_text"
2848− <*> o .: "max_query_terms"
2849− <*> o .: "ignore_tf"
2850− <*> o .: "fuzziness"
2851− <*> o .: "prefix_length"
2852− <*> o .: "boost"
2853− <*> o .:? "analyzer"
2854−
2855−instance ToJSON DisMaxQuery where
2856− toJSON (DisMaxQuery queries tiebreaker boost) =
2857− omitNulls base
2858− where base = [ "queries" .= queries
2859− , "boost" .= boost
2860− , "tie_breaker" .= tiebreaker ]
2861−
2862−instance FromJSON DisMaxQuery where
2863− parseJSON = withObject "DisMaxQuery" parse
2864− where parse o = DisMaxQuery
2865− <$> o .:? "queries" .!= []
2866− <*> o .: "tie_breaker"
2867− <*> o .:? "boost"
2868−
2869−instance ToJSON CommonTermsQuery where
2870− toJSON (CommonTermsQuery (FieldName fieldName)
2871− (QueryString query) cf lfo hfo msm
2872− boost analyzer disableCoord) =
2873− object [fieldName .= omitNulls base ]
2874− where base = [ "query" .= query
2875− , "cutoff_frequency" .= cf
2876− , "low_freq_operator" .= lfo
2877− , "minimum_should_match" .= msm
2878− , "boost" .= boost
2879− , "analyzer" .= analyzer
2880− , "disable_coord" .= disableCoord
2881− , "high_freq_operator" .= hfo ]
2882−
2883−instance FromJSON CommonTermsQuery where
2884− parseJSON = withObject "CommonTermsQuery" parse
2885− where parse = fieldTagged $ \fn o ->
2886− CommonTermsQuery fn
2887− <$> o .: "query"
2888− <*> o .: "cutoff_frequency"
2889− <*> o .: "low_freq_operator"
2890− <*> o .: "high_freq_operator"
2891− <*> o .:? "minimum_should_match"
2892− <*> o .:? "boost"
2893− <*> o .:? "analyzer"
2894− <*> o .:? "disable_coord"
2895−
2896−instance ToJSON CommonMinimumMatch where
2897− toJSON (CommonMinimumMatch mm) = toJSON mm
2898− toJSON (CommonMinimumMatchHighLow (MinimumMatchHighLow lowF highF)) =
2899− object [ "low_freq" .= lowF
2900− , "high_freq" .= highF ]
2901−
2902−instance FromJSON CommonMinimumMatch where
2903− parseJSON v = parseMinimum v
2904− <|> parseMinimumHighLow v
2905− where parseMinimum = fmap CommonMinimumMatch . parseJSON
2906− parseMinimumHighLow = fmap CommonMinimumMatchHighLow . withObject "CommonMinimumMatchHighLow" (\o ->
2907− MinimumMatchHighLow
2908− <$> o .: "low_freq"
2909− <*> o .: "high_freq")
2910−
2911−
2912−instance ToJSON BoostingQuery where
2913− toJSON (BoostingQuery bqPositiveQuery bqNegativeQuery bqNegativeBoost) =
2914− object [ "positive" .= bqPositiveQuery
2915− , "negative" .= bqNegativeQuery
2916− , "negative_boost" .= bqNegativeBoost ]
2917−
2918−instance FromJSON BoostingQuery where
2919− parseJSON = withObject "BoostingQuery" parse
2920− where parse o = BoostingQuery
2921− <$> o .: "positive"
2922− <*> o .: "negative"
2923− <*> o .: "negative_boost"
2924−
2925−instance ToJSON BoolQuery where
2926− toJSON (BoolQuery mustM filterM' notM shouldM bqMin boost disableCoord) =
2927− omitNulls base
2928− where base = [ "must" .= mustM
2929− , "filter" .= filterM'
2930− , "must_not" .= notM
2931− , "should" .= shouldM
2932− , "minimum_should_match" .= bqMin
2933− , "boost" .= boost
2934− , "disable_coord" .= disableCoord ]
2935−
2936−instance FromJSON BoolQuery where
2937− parseJSON = withObject "BoolQuery" parse
2938− where parse o = BoolQuery
2939− <$> o .:? "must" .!= []
2940− <*> o .:? "filter" .!= []
2941− <*> o .:? "must_not" .!= []
2942− <*> o .:? "should" .!= []
2943− <*> o .:? "minimum_should_match"
2944− <*> o .:? "boost"
2945− <*> o .:? "disable_coord"
2946−
2947−instance ToJSON MatchQuery where
2948− toJSON (MatchQuery (FieldName fieldName)
2949− (QueryString mqQueryString) booleanOperator
2950− zeroTermsQuery cutoffFrequency matchQueryType
2951− analyzer maxExpansions lenient boost
2952− minShouldMatch
2953− ) =
2954− object [ fieldName .= omitNulls base ]
2955− where base = [ "query" .= mqQueryString
2956− , "operator" .= booleanOperator
2957− , "zero_terms_query" .= zeroTermsQuery
2958− , "cutoff_frequency" .= cutoffFrequency
2959− , "type" .= matchQueryType
2960− , "analyzer" .= analyzer
2961− , "max_expansions" .= maxExpansions
2962− , "lenient" .= lenient
2963− , "boost" .= boost
2964− , "minimum_should_match" .= minShouldMatch
2965− ]
2966−
2967−instance FromJSON MatchQuery where
2968− parseJSON = withObject "MatchQuery" parse
2969− where parse = fieldTagged $ \fn o ->
2970− MatchQuery fn
2971− <$> o .: "query"
2972− <*> o .: "operator"
2973− <*> o .: "zero_terms_query"
2974− <*> o .:? "cutoff_frequency"
2975− <*> o .:? "type"
2976− <*> o .:? "analyzer"
2977− <*> o .:? "max_expansions"
2978− <*> o .:? "lenient"
2979− <*> o .:? "boost"
2980− <*> o .:? "minimum_should_match"
2981−
2982−instance ToJSON MultiMatchQuery where
2983− toJSON (MultiMatchQuery fields (QueryString query) boolOp
2984− ztQ tb mmqt cf analyzer maxEx lenient) =
2985− object ["multi_match" .= omitNulls base]
2986− where base = [ "fields" .= fmap toJSON fields
2987− , "query" .= query
2988− , "operator" .= boolOp
2989− , "zero_terms_query" .= ztQ
2990− , "tie_breaker" .= tb
2991− , "type" .= mmqt
2992− , "cutoff_frequency" .= cf
2993− , "analyzer" .= analyzer
2994− , "max_expansions" .= maxEx
2995− , "lenient" .= lenient ]
2996−
2997−instance FromJSON MultiMatchQuery where
2998− parseJSON = withObject "MultiMatchQuery" parse
2999− where parse raw = do o <- raw .: "multi_match"
3000− MultiMatchQuery
3001− <$> o .:? "fields" .!= []
3002− <*> o .: "query"
3003− <*> o .: "operator"
3004− <*> o .: "zero_terms_query"
3005− <*> o .:? "tie_breaker"
3006− <*> o .:? "type"
3007− <*> o .:? "cutoff_frequency"
3008− <*> o .:? "analyzer"
3009− <*> o .:? "max_expansions"
3010− <*> o .:? "lenient"
3011−
3012−instance ToJSON MultiMatchQueryType where
3013− toJSON MultiMatchBestFields = "best_fields"
3014− toJSON MultiMatchMostFields = "most_fields"
3015− toJSON MultiMatchCrossFields = "cross_fields"
3016− toJSON MultiMatchPhrase = "phrase"
3017− toJSON MultiMatchPhrasePrefix = "phrase_prefix"
3018−
3019−instance FromJSON MultiMatchQueryType where
3020− parseJSON = withText "MultiMatchPhrasePrefix" parse
3021− where parse "best_fields" = pure MultiMatchBestFields
3022− parse "most_fields" = pure MultiMatchMostFields
3023− parse "cross_fields" = pure MultiMatchCrossFields
3024− parse "phrase" = pure MultiMatchPhrase
3025− parse "phrase_prefix" = pure MultiMatchPhrasePrefix
3026− parse t = fail ("Unexpected MultiMatchPhrasePrefix: " <> show t)
3027−
3028−instance ToJSON BooleanOperator where
3029− toJSON And = String "and"
3030− toJSON Or = String "or"
3031−
3032−instance FromJSON BooleanOperator where
3033− parseJSON = withText "BooleanOperator" parse
3034− where parse "and" = pure And
3035− parse "or" = pure Or
3036− parse o = fail ("Unexpected BooleanOperator: " <> show o)
3037−
3038−instance ToJSON ZeroTermsQuery where
3039− toJSON ZeroTermsNone = String "none"
3040− toJSON ZeroTermsAll = String "all"
3041−
3042−instance FromJSON ZeroTermsQuery where
3043− parseJSON = withText "ZeroTermsQuery" parse
3044− where parse "none" = pure ZeroTermsNone
3045− parse "all" = pure ZeroTermsAll
3046− parse q = fail ("Unexpected ZeroTermsQuery: " <> show q)
3047−
3048−instance ToJSON MatchQueryType where
3049− toJSON MatchPhrase = "phrase"
3050− toJSON MatchPhrasePrefix = "phrase_prefix"
3051−
3052−instance FromJSON MatchQueryType where
3053− parseJSON = withText "MatchQueryType" parse
3054− where parse "phrase" = pure MatchPhrase
3055− parse "phrase_prefix" = pure MatchPhrasePrefix
3056− parse t = fail ("Unexpected MatchQueryType: " <> show t)
3057
1065
3058instance FromJSON Status where
1066instance FromJSON Status where
3059 parseJSON (Object v) = Status <$>
1067 parseJSON (Object v) = Status <$>
@@ -3064,7 +1072,6 @@ instance FromJSON Status where
3064 v .: "tagline"
1072 v .: "tagline"
3065 parseJSON _ = empty
1073 parseJSON _ = empty
3066
1074
3067−
3068instance ToJSON IndexSettings where
1075instance ToJSON IndexSettings where
3069 toJSON (IndexSettings s r) = object ["settings" .=
1076 toJSON (IndexSettings s r) = object ["settings" .=
3070 object ["index" .=
1077 object ["index" .=
@@ -3191,18 +1198,6 @@ instance FromJSON IndexSettingsSummary where
3191 redundant (NumberOfReplicas _) = True
1198 redundant (NumberOfReplicas _) = True
3192 redundant _ = False
1199 redundant _ = False
3193
1200
3194−-- | For some reason in several settings APIs, all leaf values get returned
3195−-- as strings. This function attepmts to recover from this for all
3196−-- non-recursive JSON types. If nothing can be done, the value is left alone.
3197−unStringlyTypeJSON :: Value -> Value
3198−unStringlyTypeJSON (String "true") = Bool True
3199−unStringlyTypeJSON (String "false") = Bool False
3200−unStringlyTypeJSON (String "null") = Null
3201−unStringlyTypeJSON v@(String t) = case readMay (T.unpack t) of
3202− Just n -> Number n
3203− Nothing -> v
3204−unStringlyTypeJSON v = v
3205−
3206
1201
3207parseSettings :: Object -> Parser [UpdatableIndexSetting]
1202parseSettings :: Object -> Parser [UpdatableIndexSetting]
3208parseSettings o = do
1203parseSettings o = do
@@ -3482,9 +1477,6 @@ fastVectorHighPairs (Just
3482 ++ commonHighlightPairs fvCom
1477 ++ commonHighlightPairs fvCom
3483 ++ nonPostingsToPairs fvNonPostSettings
1478 ++ nonPostingsToPairs fvNonPostSettings
3484
1479
3485−deleteSeveral :: (Eq k, Hashable k) => [k] -> HM.HashMap k v -> HM.HashMap k v
3486−deleteSeveral ks hm = foldr HM.delete hm ks
3487−
3488commonHighlightPairs :: Maybe CommonHighlight -> [Pair]
1480commonHighlightPairs :: Maybe CommonHighlight -> [Pair]
3489commonHighlightPairs Nothing = []
1481commonHighlightPairs Nothing = []
3490commonHighlightPairs (Just (CommonHighlight chScore chForceSource chTag chEncoder
1482commonHighlightPairs (Just (CommonHighlight chScore chForceSource chTag chEncoder
@@ -3505,10 +1497,6 @@ nonPostingsToPairs (Just (NonPostings npFragSize npNumOfFrags)) =
3505 [ "fragment_size" .= npFragSize
1497 [ "fragment_size" .= npFragSize
3506 , "number_of_fragments" .= npNumOfFrags]
1498 , "number_of_fragments" .= npNumOfFrags]
3507
1499
3508−parseNEJSON :: (FromJSON a) => [Value] -> Parser (NonEmpty a)
3509−parseNEJSON [] = fail "Expected non-empty list"
3510−parseNEJSON (x:xs) = DT.mapM parseJSON (x :| xs)
3511−
3512
1500
3513instance ToJSON HighlightEncoder where
1501instance ToJSON HighlightEncoder where
3514 toJSON DefaultEncoder = String "default"
1502 toJSON DefaultEncoder = String "default"
@@ -3555,204 +1543,6 @@ instance ToJSON Missing where
3555 toJSON (CustomMissing txt) = String txt
1543 toJSON (CustomMissing txt) = String txt
3556
1544
3557
1545
3558−instance ToJSON ScoreType where
3559− toJSON ScoreTypeMax = "max"
3560− toJSON ScoreTypeAvg = "avg"
3561− toJSON ScoreTypeSum = "sum"
3562− toJSON ScoreTypeNone = "none"
3563−
3564−instance FromJSON ScoreType where
3565− parseJSON = withText "ScoreType" parse
3566− where parse "max" = pure ScoreTypeMax
3567− parse "avg" = pure ScoreTypeAvg
3568− parse "sum" = pure ScoreTypeSum
3569− parse "none" = pure ScoreTypeNone
3570− parse t = fail ("Unexpected ScoreType: " <> show t)
3571−
3572−instance ToJSON Distance where
3573− toJSON (Distance dCoefficient dUnit) =
3574− String boltedTogether where
3575− coefText = showText dCoefficient
3576− (String unitText) = toJSON dUnit
3577− boltedTogether = mappend coefText unitText
3578−
3579−instance FromJSON Distance where
3580− parseJSON = withText "Distance" parse
3581− where parse t = Distance <$> parseCoeff nT
3582− <*> parseJSON (String unitT)
3583− where (nT, unitT) = T.span validForNumber t
3584− -- may be a better way to do this
3585− validForNumber '-' = True
3586− validForNumber '.' = True
3587− validForNumber 'e' = True
3588− validForNumber c = isNumber c
3589− parseCoeff "" = fail "Empty string cannot be parsed as number"
3590− parseCoeff s = return (read (T.unpack s))
3591−
3592−instance ToJSON DistanceUnit where
3593− toJSON Miles = String "mi"
3594− toJSON Yards = String "yd"
3595− toJSON Feet = String "ft"
3596− toJSON Inches = String "in"
3597− toJSON Kilometers = String "km"
3598− toJSON Meters = String "m"
3599− toJSON Centimeters = String "cm"
3600− toJSON Millimeters = String "mm"
3601− toJSON NauticalMiles = String "nmi"
3602−
3603−
3604−instance FromJSON DistanceUnit where
3605− parseJSON = withText "DistanceUnit" parse
3606− where parse "mi" = pure Miles
3607− parse "yd" = pure Yards
3608− parse "ft" = pure Feet
3609− parse "in" = pure Inches
3610− parse "km" = pure Kilometers
3611− parse "m" = pure Meters
3612− parse "cm" = pure Centimeters
3613− parse "mm" = pure Millimeters
3614− parse "nmi" = pure NauticalMiles
3615− parse u = fail ("Unrecognized DistanceUnit: " <> show u)
3616−
3617−instance ToJSON DistanceType where
3618− toJSON Arc = String "arc"
3619− toJSON SloppyArc = String "sloppy_arc"
3620− toJSON Plane = String "plane"
3621−
3622−instance FromJSON DistanceType where
3623− parseJSON = withText "DistanceType" parse
3624− where parse "arc" = pure Arc
3625− parse "sloppy_arc" = pure SloppyArc
3626− parse "plane" = pure Plane
3627− parse t = fail ("Unrecognized DistanceType: " <> show t)
3628−
3629−
3630−instance ToJSON OptimizeBbox where
3631− toJSON NoOptimizeBbox = String "none"
3632− toJSON (OptimizeGeoFilterType gft) = toJSON gft
3633−
3634−instance FromJSON OptimizeBbox where
3635− parseJSON v = withText "NoOptimizeBbox" parseNoOptimize v
3636− <|> parseOptimize v
3637− where parseNoOptimize "none" = pure NoOptimizeBbox
3638− parseNoOptimize _ = mzero
3639− parseOptimize = fmap OptimizeGeoFilterType . parseJSON
3640−
3641−instance ToJSON GeoBoundingBoxConstraint where
3642− toJSON (GeoBoundingBoxConstraint
3643− (FieldName gbbcGeoBBField) gbbcConstraintBox cache type') =
3644− object [gbbcGeoBBField .= gbbcConstraintBox
3645− , "_cache" .= cache
3646− , "type" .= type']
3647−
3648−instance FromJSON GeoBoundingBoxConstraint where
3649− parseJSON = withObject "GeoBoundingBoxConstraint" parse
3650− where parse o = case HM.toList (deleteSeveral ["type", "_cache"] o) of
3651− [(fn, v)] -> GeoBoundingBoxConstraint (FieldName fn)
3652− <$> parseJSON v
3653− <*> o .:? "_cache" .!= defaultCache
3654− <*> o .: "type"
3655− _ -> fail "Could not find field name for GeoBoundingBoxConstraint"
3656−
3657−instance ToJSON GeoFilterType where
3658− toJSON GeoFilterMemory = String "memory"
3659− toJSON GeoFilterIndexed = String "indexed"
3660−
3661−instance FromJSON GeoFilterType where
3662− parseJSON = withText "GeoFilterType" parse
3663− where parse "memory" = pure GeoFilterMemory
3664− parse "indexed" = pure GeoFilterIndexed
3665− parse t = fail ("Unrecognized GeoFilterType: " <> show t)
3666−
3667−instance ToJSON GeoBoundingBox where
3668− toJSON (GeoBoundingBox gbbTopLeft gbbBottomRight) =
3669− object ["top_left" .= gbbTopLeft
3670− , "bottom_right" .= gbbBottomRight]
3671−
3672−instance FromJSON GeoBoundingBox where
3673− parseJSON = withObject "GeoBoundingBox" parse
3674− where parse o = GeoBoundingBox
3675− <$> o .: "top_left"
3676− <*> o .: "bottom_right"
3677−
3678−instance ToJSON LatLon where
3679− toJSON (LatLon lLat lLon) =
3680− object ["lat" .= lLat
3681− , "lon" .= lLon]
3682−
3683−instance FromJSON LatLon where
3684− parseJSON = withObject "LatLon" parse
3685− where parse o = LatLon <$> o .: "lat"
3686− <*> o .: "lon"
3687−
3688−-- index for smaller ranges, fielddata for longer ranges
3689−instance ToJSON RangeExecution where
3690− toJSON RangeExecutionIndex = "index"
3691− toJSON RangeExecutionFielddata = "fielddata"
3692−
3693−
3694−instance FromJSON RangeExecution where
3695− parseJSON = withText "RangeExecution" parse
3696− where parse "index" = pure RangeExecutionIndex
3697− parse "fielddata" = pure RangeExecutionFielddata
3698− parse t = error ("Unrecognized RangeExecution " <> show t)
3699−
3700−instance ToJSON RegexpFlags where
3701− toJSON AllRegexpFlags = String "ALL"
3702− toJSON NoRegexpFlags = String "NONE"
3703− toJSON (SomeRegexpFlags (h :| fs)) = String $ T.intercalate "|" flagStrs
3704− where flagStrs = map flagStr . nub $ h:fs
3705− flagStr AnyString = "ANYSTRING"
3706− flagStr Automaton = "AUTOMATON"
3707− flagStr Complement = "COMPLEMENT"
3708− flagStr Empty = "EMPTY"
3709− flagStr Intersection = "INTERSECTION"
3710− flagStr Interval = "INTERVAL"
3711−
3712−instance FromJSON RegexpFlags where
3713− parseJSON = withText "RegexpFlags" parse
3714− where parse "ALL" = pure AllRegexpFlags
3715− parse "NONE" = pure NoRegexpFlags
3716− parse t = SomeRegexpFlags <$> parseNEJSON (String <$> T.splitOn "|" t)
3717−
3718−instance FromJSON RegexpFlag where
3719− parseJSON = withText "RegexpFlag" parse
3720− where parse "ANYSTRING" = pure AnyString
3721− parse "AUTOMATON" = pure Automaton
3722− parse "COMPLEMENT" = pure Complement
3723− parse "EMPTY" = pure Empty
3724− parse "INTERSECTION" = pure Intersection
3725− parse "INTERVAL" = pure Interval
3726− parse f = fail ("Unknown RegexpFlag: " <> show f)
3727−
3728−instance ToJSON Term where
3729− toJSON (Term field value) = object ["term" .= object
3730− [field .= value]]
3731−
3732−instance FromJSON Term where
3733− parseJSON = withObject "Term" parse
3734− where parse o = do termObj <- o .: "term"
3735− case HM.toList termObj of
3736− [(fn, v)] -> Term fn <$> parseJSON v
3737− _ -> fail "Expected object with 1 field-named key"
3738−
3739−instance ToJSON BoolMatch where
3740− toJSON (MustMatch term cache) = object ["must" .= term,
3741− "_cache" .= cache]
3742− toJSON (MustNotMatch term cache) = object ["must_not" .= term,
3743− "_cache" .= cache]
3744− toJSON (ShouldMatch terms cache) = object ["should" .= fmap toJSON terms,
3745− "_cache" .= cache]
3746−
3747−instance FromJSON BoolMatch where
3748− parseJSON = withObject "BoolMatch" parse
3749− where parse o = mustMatch `taggedWith` "must"
3750− <|> mustNotMatch `taggedWith` "must_not"
3751− <|> shouldMatch `taggedWith` "should"
3752− where taggedWith parser k = parser =<< o .: k
3753− mustMatch t = MustMatch t <$> o .:? "_cache" .!= defaultCache
3754− mustNotMatch t = MustNotMatch t <$> o .:? "_cache" .!= defaultCache
3755− shouldMatch t = ShouldMatch t <$> o .:? "_cache" .!= defaultCache
3756
1546
3757instance (FromJSON a) => FromJSON (SearchResult a) where
1547instance (FromJSON a) => FromJSON (SearchResult a) where
3758 parseJSON (Object v) = SearchResult <$>
1548 parseJSON (Object v) = SearchResult <$>
@@ -3782,1476 +1572,20 @@ instance (FromJSON a) => FromJSON (Hit a) where
3782 v .:? "highlight"
1572 v .:? "highlight"
3783 parseJSON _ = empty
1573 parseJSON _ = empty
3784
1574
3785−instance FromJSON ShardResult where
3786− parseJSON (Object v) = ShardResult <$>
3787− v .: "total" <*>
3788− v .: "successful" <*>
3789− v .: "failed"
3790− parseJSON _ = empty
3791−
3792
1575
3793instance FromJSON DocVersion where
1576instance FromJSON DocVersion where
3794 parseJSON v = do
1577 parseJSON v = do
3795 i <- parseJSON v
1578 i <- parseJSON v
3796 maybe (fail "DocVersion out of range") return $ mkDocVersion i
1579 maybe (fail "DocVersion out of range") return $ mkDocVersion i
3797
1580
3798−-- This insanity is because ES *sometimes* returns Replica/Shard counts as strings
3799−instance FromJSON ReplicaCount where
3800− parseJSON v = parseAsInt v
3801− <|> parseAsString v
3802− where parseAsInt = fmap ReplicaCount . parseJSON
3803− parseAsString = withText "ReplicaCount" (fmap ReplicaCount . parseReadText)
3804−
3805−instance FromJSON ShardCount where
3806− parseJSON v = parseAsInt v
3807− <|> parseAsString v
3808− where parseAsInt = fmap ShardCount . parseJSON
3809− parseAsString = withText "ShardCount" (fmap ShardCount . parseReadText)
3810−
3811−instance Bounded DocVersion where
3812− minBound = DocVersion 1
3813− maxBound = DocVersion 9200000000000000000 -- 9.2e+18
3814−
3815−instance Enum DocVersion where
3816− succ x
3817− | x /= maxBound = DocVersion (succ $ docVersionNumber x)
3818− | otherwise = succError "DocVersion"
3819− pred x
3820− | x /= minBound = DocVersion (pred $ docVersionNumber x)
3821− | otherwise = predError "DocVersion"
3822− toEnum i =
3823− fromMaybe (error $ show i ++ " out of DocVersion range") $ mkDocVersion i
3824− fromEnum = docVersionNumber
3825− enumFrom = boundedEnumFrom
3826− enumFromThen = boundedEnumFromThen
3827−
3828−-- | Username type used for HTTP Basic authentication. See 'basicAuthHook'.
3829−newtype EsUsername = EsUsername { esUsername :: Text } deriving (Read, Show, Eq)
3830−
3831−-- | Password type used for HTTP Basic authentication. See 'basicAuthHook'.
3832−newtype EsPassword = EsPassword { esPassword :: Text } deriving (Read, Show, Eq)
3833−
3834−
3835−data SnapshotRepoSelection = SnapshotRepoList (NonEmpty SnapshotRepoPattern)
3836− | AllSnapshotRepos deriving (Eq, Generic, Show, Typeable)
3837−
3838−
3839−-- | Either specifies an exact repo name or one with globs in it,
3840−-- e.g. @RepoPattern "foo*"@ __NOTE__: Patterns are not supported on ES < 1.7
3841−data SnapshotRepoPattern = ExactRepo SnapshotRepoName
3842− | RepoPattern Text
3843− deriving (Eq, Generic, Show, Typeable)
3844−
3845−-- | The unique name of a snapshot repository.
3846−newtype SnapshotRepoName = SnapshotRepoName { snapshotRepoName :: Text }
3847− deriving (Eq, Ord, Generic, Show, Typeable, ToJSON, FromJSON)
3848−
3849−
3850−-- | A generic representation of a snapshot repo. This is what gets
3851−-- sent to and parsed from the server. For repo types enabled by
3852−-- plugins that aren't exported by this library, consider making a
3853−-- custom type which implements 'SnapshotRepo'. If it is a common repo
3854−-- type, consider submitting a pull request to have it included in the
3855−-- library proper
3856−data GenericSnapshotRepo = GenericSnapshotRepo {
3857− gSnapshotRepoName :: SnapshotRepoName
3858− , gSnapshotRepoType :: SnapshotRepoType
3859− , gSnapshotRepoSettings :: GenericSnapshotRepoSettings
3860− } deriving (Eq, Generic, Show, Typeable)
3861−
3862−
3863−instance SnapshotRepo GenericSnapshotRepo where
3864− toGSnapshotRepo = id
3865− fromGSnapshotRepo = Right
3866−
3867−
3868−newtype SnapshotRepoType = SnapshotRepoType { snapshotRepoType :: Text }
3869− deriving (Eq, Ord, Generic, Show, Typeable, ToJSON, FromJSON)
3870−
3871−
3872−-- | Opaque representation of snapshot repo settings. Instances of
3873−-- 'SnapshotRepo' will produce this.
3874−newtype GenericSnapshotRepoSettings = GenericSnapshotRepoSettings { gSnapshotRepoSettingsObject :: Object }
3875− deriving (Eq, Generic, Show, Typeable, ToJSON)
3876−
3877−
3878− -- Regardless of whether you send strongly typed json, my version of
3879− -- ES sends back stringly typed json in the settings, e.g. booleans
3880− -- as strings, so we'll try to convert them.
3881−instance FromJSON GenericSnapshotRepoSettings where
3882− parseJSON = fmap (GenericSnapshotRepoSettings . fmap unStringlyTypeJSON). parseJSON
3883−
3884−-- | The result of running 'verifySnapshotRepo'.
3885−newtype SnapshotVerification = SnapshotVerification { snapshotNodeVerifications :: [SnapshotNodeVerification] }
3886− deriving (Eq, Generic, Show, Typeable)
3887−
3888−
3889−instance FromJSON SnapshotVerification where
3890− parseJSON = withObject "SnapshotVerification" parse
3891− where
3892− parse o = do
3893− o2 <- o .: "nodes"
3894− SnapshotVerification <$> mapM (uncurry parse') (HM.toList o2)
3895− parse' rawFullId = withObject "SnapshotNodeVerification" $ \o ->
3896− SnapshotNodeVerification (FullNodeId rawFullId) <$> o .: "name"
3897−
3898−
3899−-- | A node that has verified a snapshot
3900−data SnapshotNodeVerification = SnapshotNodeVerification {
3901− snvFullId :: FullNodeId
3902− , snvNodeName :: NodeName
3903− } deriving (Eq, Generic, Show, Typeable)
3904−
3905−
3906−-- | Unique, automatically-generated name assigned to nodes that are
3907−-- usually returned in node-oriented APIs.
3908−newtype FullNodeId = FullNodeId { fullNodeId :: Text }
3909− deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
3910−
3911−
3912−-- | A human-readable node name that is supplied by the user in the
3913−-- node config or automatically generated by ElasticSearch.
3914−newtype NodeName = NodeName { nodeName :: Text }
3915− deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
3916−
3917−newtype ClusterName = ClusterName { clusterName :: Text }
3918− deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
3919−
3920−data NodesInfo = NodesInfo {
3921− nodesInfo :: [NodeInfo]
3922− , nodesClusterName :: ClusterName
3923− } deriving (Eq, Show, Generic, Typeable)
3924−
3925−data NodesStats = NodesStats {
3926− nodesStats :: [NodeStats]
3927− , nodesStatsClusterName :: ClusterName
3928− } deriving (Eq, Show, Generic, Typeable)
3929−
3930−data NodeStats = NodeStats {
3931− nodeStatsName :: NodeName
3932− , nodeStatsFullId :: FullNodeId
3933− , nodeStatsBreakersStats :: Maybe NodeBreakersStats
3934− , nodeStatsHTTP :: NodeHTTPStats
3935− , nodeStatsTransport :: NodeTransportStats
3936− , nodeStatsFS :: NodeFSStats
3937− , nodeStatsNetwork :: Maybe NodeNetworkStats
3938− , nodeStatsThreadPool :: NodeThreadPoolsStats
3939− , nodeStatsJVM :: NodeJVMStats
3940− , nodeStatsProcess :: NodeProcessStats
3941− , nodeStatsOS :: NodeOSStats
3942− , nodeStatsIndices :: NodeIndicesStats
3943− } deriving (Eq, Show, Generic, Typeable)
3944−
3945−data NodeBreakersStats = NodeBreakersStats {
3946− nodeStatsParentBreaker :: NodeBreakerStats
3947− , nodeStatsRequestBreaker :: NodeBreakerStats
3948− , nodeStatsFieldDataBreaker :: NodeBreakerStats
3949− } deriving (Eq, Show, Generic, Typeable)
3950−
3951−data NodeBreakerStats = NodeBreakerStats {
3952− nodeBreakersTripped :: Int
3953− , nodeBreakersOverhead :: Double
3954− , nodeBreakersEstSize :: Bytes
3955− , nodeBreakersLimitSize :: Bytes
3956− } deriving (Eq, Show, Generic, Typeable)
3957−
3958−data NodeHTTPStats = NodeHTTPStats {
3959− nodeHTTPTotalOpened :: Int
3960− , nodeHTTPCurrentOpen :: Int
3961− } deriving (Eq, Show, Generic, Typeable)
3962−
3963−data NodeTransportStats = NodeTransportStats {
3964− nodeTransportTXSize :: Bytes
3965− , nodeTransportCount :: Int
3966− , nodeTransportRXSize :: Bytes
3967− , nodeTransportRXCount :: Int
3968− , nodeTransportServerOpen :: Int
3969− } deriving (Eq, Show, Generic, Typeable)
3970−
3971−data NodeFSStats = NodeFSStats {
3972− nodeFSDataPaths :: [NodeDataPathStats]
3973− , nodeFSTotal :: NodeFSTotalStats
3974− , nodeFSTimestamp :: UTCTime
3975− } deriving (Eq, Show, Generic, Typeable)
3976−
3977−data NodeDataPathStats = NodeDataPathStats {
3978− nodeDataPathDiskServiceTime :: Maybe Double
3979− , nodeDataPathDiskQueue :: Maybe Double
3980− , nodeDataPathIOSize :: Maybe Bytes
3981− , nodeDataPathWriteSize :: Maybe Bytes
3982− , nodeDataPathReadSize :: Maybe Bytes
3983− , nodeDataPathIOOps :: Maybe Int
3984− , nodeDataPathWrites :: Maybe Int
3985− , nodeDataPathReads :: Maybe Int
3986− , nodeDataPathAvailable :: Bytes
3987− , nodeDataPathFree :: Bytes
3988− , nodeDataPathTotal :: Bytes
3989− , nodeDataPathType :: Maybe Text
3990− , nodeDataPathDevice :: Maybe Text
3991− , nodeDataPathMount :: Text
3992− , nodeDataPathPath :: Text
3993− } deriving (Eq, Show, Generic, Typeable)
3994−
3995−data NodeFSTotalStats = NodeFSTotalStats {
3996− nodeFSTotalDiskServiceTime :: Maybe Double
3997− , nodeFSTotalDiskQueue :: Maybe Double
3998− , nodeFSTotalIOSize :: Maybe Bytes
3999− , nodeFSTotalWriteSize :: Maybe Bytes
4000− , nodeFSTotalReadSize :: Maybe Bytes
4001− , nodeFSTotalIOOps :: Maybe Int
4002− , nodeFSTotalWrites :: Maybe Int
4003− , nodeFSTotalReads :: Maybe Int
4004− , nodeFSTotalAvailable :: Bytes
4005− , nodeFSTotalFree :: Bytes
4006− , nodeFSTotalTotal :: Bytes
4007− } deriving (Eq, Show, Generic, Typeable)
4008−
4009−data NodeNetworkStats = NodeNetworkStats {
4010− nodeNetTCPOutRSTs :: Int
4011− , nodeNetTCPInErrs :: Int
4012− , nodeNetTCPAttemptFails :: Int
4013− , nodeNetTCPEstabResets :: Int
4014− , nodeNetTCPRetransSegs :: Int
4015− , nodeNetTCPOutSegs :: Int
4016− , nodeNetTCPInSegs :: Int
4017− , nodeNetTCPCurrEstab :: Int
4018− , nodeNetTCPPassiveOpens :: Int
4019− , nodeNetTCPActiveOpens :: Int
4020− } deriving (Eq, Show, Generic, Typeable)
4021−
4022−data NodeThreadPoolsStats = NodeThreadPoolsStats {
4023− nodeThreadPoolsStatsSnapshot :: NodeThreadPoolStats
4024− , nodeThreadPoolsStatsBulk :: NodeThreadPoolStats
4025− , nodeThreadPoolsStatsMerge :: NodeThreadPoolStats
4026− , nodeThreadPoolsStatsGet :: NodeThreadPoolStats
4027− , nodeThreadPoolsStatsManagement :: NodeThreadPoolStats
4028− , nodeThreadPoolsStatsFetchShardStore :: Maybe NodeThreadPoolStats
4029− , nodeThreadPoolsStatsOptimize :: Maybe NodeThreadPoolStats
4030− , nodeThreadPoolsStatsFlush :: NodeThreadPoolStats
4031− , nodeThreadPoolsStatsSearch :: NodeThreadPoolStats
4032− , nodeThreadPoolsStatsWarmer :: NodeThreadPoolStats
4033− , nodeThreadPoolsStatsGeneric :: NodeThreadPoolStats
4034− , nodeThreadPoolsStatsSuggest :: Maybe NodeThreadPoolStats
4035− , nodeThreadPoolsStatsRefresh :: NodeThreadPoolStats
4036− , nodeThreadPoolsStatsIndex :: NodeThreadPoolStats
4037− , nodeThreadPoolsStatsListener :: Maybe NodeThreadPoolStats
4038− , nodeThreadPoolsStatsFetchShardStarted :: Maybe NodeThreadPoolStats
4039− , nodeThreadPoolsStatsPercolate :: Maybe NodeThreadPoolStats
4040− } deriving (Eq, Show, Generic, Typeable)
4041−
4042−data NodeThreadPoolStats = NodeThreadPoolStats {
4043− nodeThreadPoolCompleted :: Int
4044− , nodeThreadPoolLargest :: Int
4045− , nodeThreadPoolRejected :: Int
4046− , nodeThreadPoolActive :: Int
4047− , nodeThreadPoolQueue :: Int
4048− , nodeThreadPoolThreads :: Int
4049− } deriving (Eq, Show, Generic, Typeable)
4050−
4051−data NodeJVMStats = NodeJVMStats {
4052− nodeJVMStatsMappedBufferPool :: JVMBufferPoolStats
4053− , nodeJVMStatsDirectBufferPool :: JVMBufferPoolStats
4054− , nodeJVMStatsGCOldCollector :: JVMGCStats
4055− , nodeJVMStatsGCYoungCollector :: JVMGCStats
4056− , nodeJVMStatsPeakThreadsCount :: Int
4057− , nodeJVMStatsThreadsCount :: Int
4058− , nodeJVMStatsOldPool :: JVMPoolStats
4059− , nodeJVMStatsSurvivorPool :: JVMPoolStats
4060− , nodeJVMStatsYoungPool :: JVMPoolStats
4061− , nodeJVMStatsNonHeapCommitted :: Bytes
4062− , nodeJVMStatsNonHeapUsed :: Bytes
4063− , nodeJVMStatsHeapMax :: Bytes
4064− , nodeJVMStatsHeapCommitted :: Bytes
4065− , nodeJVMStatsHeapUsedPercent :: Int
4066− , nodeJVMStatsHeapUsed :: Bytes
4067− , nodeJVMStatsUptime :: NominalDiffTime
4068− , nodeJVMStatsTimestamp :: UTCTime
4069− } deriving (Eq, Show, Generic, Typeable)
4070−
4071−data JVMBufferPoolStats = JVMBufferPoolStats {
4072− jvmBufferPoolStatsTotalCapacity :: Bytes
4073− , jvmBufferPoolStatsUsed :: Bytes
4074− , jvmBufferPoolStatsCount :: Int
4075− } deriving (Eq, Show, Generic, Typeable)
4076−
4077−data JVMGCStats = JVMGCStats {
4078− jvmGCStatsCollectionTime :: NominalDiffTime
4079− , jvmGCStatsCollectionCount :: Int
4080− } deriving (Eq, Show, Generic, Typeable)
4081−
4082−data JVMPoolStats = JVMPoolStats {
4083− jvmPoolStatsPeakMax :: Bytes
4084− , jvmPoolStatsPeakUsed :: Bytes
4085− , jvmPoolStatsMax :: Bytes
4086− , jvmPoolStatsUsed :: Bytes
4087− } deriving (Eq, Show, Generic, Typeable)
4088−
4089−data NodeProcessStats = NodeProcessStats {
4090− nodeProcessTimestamp :: UTCTime
4091− , nodeProcessOpenFDs :: Int
4092− , nodeProcessMaxFDs :: Int
4093− , nodeProcessCPUPercent :: Int
4094− , nodeProcessCPUTotal :: NominalDiffTime
4095− , nodeProcessMemTotalVirtual :: Bytes
4096− } deriving (Eq, Show, Generic, Typeable)
4097−
4098−data NodeOSStats = NodeOSStats {
4099− nodeOSTimestamp :: UTCTime
4100− , nodeOSCPUPercent :: Int
4101− , nodeOSLoad :: Maybe LoadAvgs
4102− , nodeOSMemTotal :: Bytes
4103− , nodeOSMemFree :: Bytes
4104− , nodeOSMemFreePercent :: Int
4105− , nodeOSMemUsed :: Bytes
4106− , nodeOSMemUsedPercent :: Int
4107− , nodeOSSwapTotal :: Bytes
4108− , nodeOSSwapFree :: Bytes
4109− , nodeOSSwapUsed :: Bytes
4110− } deriving (Eq, Show, Generic, Typeable)
4111−
4112−data LoadAvgs = LoadAvgs {
4113− loadAvg1Min :: Double
4114− , loadAvg5Min :: Double
4115− , loadAvg15Min :: Double
4116− } deriving (Eq, Show, Generic, Typeable)
4117−
4118−data NodeIndicesStats = NodeIndicesStats {
4119− nodeIndicesStatsRecoveryThrottleTime :: Maybe NominalDiffTime
4120− , nodeIndicesStatsRecoveryCurrentAsTarget :: Maybe Int
4121− , nodeIndicesStatsRecoveryCurrentAsSource :: Maybe Int
4122− , nodeIndicesStatsQueryCacheMisses :: Maybe Int
4123− , nodeIndicesStatsQueryCacheHits :: Maybe Int
4124− , nodeIndicesStatsQueryCacheEvictions :: Maybe Int
4125− , nodeIndicesStatsQueryCacheSize :: Maybe Bytes
4126− , nodeIndicesStatsSuggestCurrent :: Maybe Int
4127− , nodeIndicesStatsSuggestTime :: Maybe NominalDiffTime
4128− , nodeIndicesStatsSuggestTotal :: Maybe Int
4129− , nodeIndicesStatsTranslogSize :: Bytes
4130− , nodeIndicesStatsTranslogOps :: Int
4131− , nodeIndicesStatsSegFixedBitSetMemory :: Maybe Bytes
4132− , nodeIndicesStatsSegVersionMapMemory :: Bytes
4133− , nodeIndicesStatsSegIndexWriterMaxMemory :: Maybe Bytes
4134− , nodeIndicesStatsSegIndexWriterMemory :: Bytes
4135− , nodeIndicesStatsSegMemory :: Bytes
4136− , nodeIndicesStatsSegCount :: Int
4137− , nodeIndicesStatsCompletionSize :: Bytes
4138− , nodeIndicesStatsPercolateQueries :: Maybe Int
4139− , nodeIndicesStatsPercolateMemory :: Maybe Bytes
4140− , nodeIndicesStatsPercolateCurrent :: Maybe Int
4141− , nodeIndicesStatsPercolateTime :: Maybe NominalDiffTime
4142− , nodeIndicesStatsPercolateTotal :: Maybe Int
4143− , nodeIndicesStatsFieldDataEvictions :: Int
4144− , nodeIndicesStatsFieldDataMemory :: Bytes
4145− , nodeIndicesStatsWarmerTotalTime :: NominalDiffTime
4146− , nodeIndicesStatsWarmerTotal :: Int
4147− , nodeIndicesStatsWarmerCurrent :: Int
4148− , nodeIndicesStatsFlushTotalTime :: NominalDiffTime
4149− , nodeIndicesStatsFlushTotal :: Int
4150− , nodeIndicesStatsRefreshTotalTime :: NominalDiffTime
4151− , nodeIndicesStatsRefreshTotal :: Int
4152− , nodeIndicesStatsMergesTotalSize :: Bytes
4153− , nodeIndicesStatsMergesTotalDocs :: Int
4154− , nodeIndicesStatsMergesTotalTime :: NominalDiffTime
4155− , nodeIndicesStatsMergesTotal :: Int
4156− , nodeIndicesStatsMergesCurrentSize :: Bytes
4157− , nodeIndicesStatsMergesCurrentDocs :: Int
4158− , nodeIndicesStatsMergesCurrent :: Int
4159− , nodeIndicesStatsSearchFetchCurrent :: Int
4160− , nodeIndicesStatsSearchFetchTime :: NominalDiffTime
4161− , nodeIndicesStatsSearchFetchTotal :: Int
4162− , nodeIndicesStatsSearchQueryCurrent :: Int
4163− , nodeIndicesStatsSearchQueryTime :: NominalDiffTime
4164− , nodeIndicesStatsSearchQueryTotal :: Int
4165− , nodeIndicesStatsSearchOpenContexts :: Int
4166− , nodeIndicesStatsGetCurrent :: Int
4167− , nodeIndicesStatsGetMissingTime :: NominalDiffTime
4168− , nodeIndicesStatsGetMissingTotal :: Int
4169− , nodeIndicesStatsGetExistsTime :: NominalDiffTime
4170− , nodeIndicesStatsGetExistsTotal :: Int
4171− , nodeIndicesStatsGetTime :: NominalDiffTime
4172− , nodeIndicesStatsGetTotal :: Int
4173− , nodeIndicesStatsIndexingThrottleTime :: Maybe NominalDiffTime
4174− , nodeIndicesStatsIndexingIsThrottled :: Maybe Bool
4175− , nodeIndicesStatsIndexingNoopUpdateTotal :: Maybe Int
4176− , nodeIndicesStatsIndexingDeleteCurrent :: Int
4177− , nodeIndicesStatsIndexingDeleteTime :: NominalDiffTime
4178− , nodeIndicesStatsIndexingDeleteTotal :: Int
4179− , nodeIndicesStatsIndexingIndexCurrent :: Int
4180− , nodeIndicesStatsIndexingIndexTime :: NominalDiffTime
4181− , nodeIndicesStatsIndexingTotal :: Int
4182− , nodeIndicesStatsStoreThrottleTime :: NominalDiffTime
4183− , nodeIndicesStatsStoreSize :: Bytes
4184− , nodeIndicesStatsDocsDeleted :: Int
4185− , nodeIndicesStatsDocsCount :: Int
4186− } deriving (Eq, Show, Generic, Typeable)
4187−
4188−-- | A quirky address format used throughout ElasticSearch. An example
4189−-- would be inet[/1.1.1.1:9200]. inet may be a placeholder for a
4190−-- <https://en.wikipedia.org/wiki/Fully_qualified_domain_name FQDN>.
4191−newtype EsAddress = EsAddress { esAddress :: Text }
4192− deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
4193−
4194−-- | Typically a 7 character hex string.
4195−newtype BuildHash = BuildHash { buildHash :: Text }
4196− deriving (Eq, Ord, Generic, Read, Show, Typeable, FromJSON, ToJSON)
4197−
4198−newtype PluginName = PluginName { pluginName :: Text }
4199− deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
4200−
4201−data NodeInfo = NodeInfo {
4202− nodeInfoHTTPAddress :: Maybe EsAddress
4203− , nodeInfoBuild :: BuildHash
4204− , nodeInfoESVersion :: VersionNumber
4205− , nodeInfoIP :: Server
4206− , nodeInfoHost :: Server
4207− , nodeInfoTransportAddress :: EsAddress
4208− , nodeInfoName :: NodeName
4209− , nodeInfoFullId :: FullNodeId
4210− , nodeInfoPlugins :: [NodePluginInfo]
4211− , nodeInfoHTTP :: NodeHTTPInfo
4212− , nodeInfoTransport :: NodeTransportInfo
4213− , nodeInfoNetwork :: Maybe NodeNetworkInfo
4214− , nodeInfoThreadPool :: NodeThreadPoolsInfo
4215− , nodeInfoJVM :: NodeJVMInfo
4216− , nodeInfoProcess :: NodeProcessInfo
4217− , nodeInfoOS :: NodeOSInfo
4218− , nodeInfoSettings :: Object
4219− -- ^ The members of the settings objects are not consistent,
4220− -- dependent on plugins, etc.
4221− } deriving (Eq, Show, Generic, Typeable)
4222−
4223−data NodePluginInfo = NodePluginInfo {
4224− nodePluginSite :: Maybe Bool
4225− -- ^ Is this a site plugin?
4226− , nodePluginJVM :: Maybe Bool
4227− -- ^ Is this plugin running on the JVM
4228− , nodePluginDescription :: Text
4229− , nodePluginVersion :: MaybeNA VersionNumber
4230− , nodePluginName :: PluginName
4231− } deriving (Eq, Show, Generic, Typeable)
4232−
4233−data NodeHTTPInfo = NodeHTTPInfo {
4234− nodeHTTPMaxContentLength :: Bytes
4235− , nodeHTTPTransportAddress :: BoundTransportAddress
4236− } deriving (Eq, Show, Generic, Typeable)
4237−
4238−data NodeTransportInfo = NodeTransportInfo {
4239− nodeTransportProfiles :: [BoundTransportAddress]
4240− , nodeTransportAddress :: BoundTransportAddress
4241− } deriving (Eq, Show, Generic, Typeable)
4242−
4243−data BoundTransportAddress = BoundTransportAddress {
4244− publishAddress :: EsAddress
4245− , boundAddress :: [EsAddress]
4246− } deriving (Eq, Show, Generic, Typeable)
4247−
4248−data NodeNetworkInfo = NodeNetworkInfo {
4249− nodeNetworkPrimaryInterface :: NodeNetworkInterface
4250− , nodeNetworkRefreshInterval :: NominalDiffTime
4251− } deriving (Eq, Show, Generic, Typeable)
4252−
4253−newtype MacAddress = MacAddress { macAddress :: Text }
4254− deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
4255−
4256−newtype NetworkInterfaceName = NetworkInterfaceName { networkInterfaceName :: Text }
4257− deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
4258−
4259−data NodeNetworkInterface = NodeNetworkInterface {
4260− nodeNetIfaceMacAddress :: MacAddress
4261− , nodeNetIfaceName :: NetworkInterfaceName
4262− , nodeNetIfaceAddress :: Server
4263− } deriving (Eq, Show, Generic, Typeable)
4264−
4265−data NodeThreadPoolsInfo = NodeThreadPoolsInfo {
4266− nodeThreadPoolsRefresh :: NodeThreadPoolInfo
4267− , nodeThreadPoolsManagement :: NodeThreadPoolInfo
4268− , nodeThreadPoolsPercolate :: Maybe NodeThreadPoolInfo
4269− , nodeThreadPoolsListener :: Maybe NodeThreadPoolInfo
4270− , nodeThreadPoolsFetchShardStarted :: Maybe NodeThreadPoolInfo
4271− , nodeThreadPoolsSearch :: NodeThreadPoolInfo
4272− , nodeThreadPoolsFlush :: NodeThreadPoolInfo
4273− , nodeThreadPoolsWarmer :: NodeThreadPoolInfo
4274− , nodeThreadPoolsOptimize :: Maybe NodeThreadPoolInfo
4275− , nodeThreadPoolsBulk :: NodeThreadPoolInfo
4276− , nodeThreadPoolsSuggest :: Maybe NodeThreadPoolInfo
4277− , nodeThreadPoolsMerge :: NodeThreadPoolInfo
4278− , nodeThreadPoolsSnapshot :: NodeThreadPoolInfo
4279− , nodeThreadPoolsGet :: NodeThreadPoolInfo
4280− , nodeThreadPoolsFetchShardStore :: Maybe NodeThreadPoolInfo
4281− , nodeThreadPoolsIndex :: NodeThreadPoolInfo
4282− , nodeThreadPoolsGeneric :: NodeThreadPoolInfo
4283− } deriving (Eq, Show, Generic, Typeable)
4284−
4285−data NodeThreadPoolInfo = NodeThreadPoolInfo {
4286− nodeThreadPoolQueueSize :: ThreadPoolSize
4287− , nodeThreadPoolKeepalive :: Maybe NominalDiffTime
4288− , nodeThreadPoolMin :: Maybe Int
4289− , nodeThreadPoolMax :: Maybe Int
4290− , nodeThreadPoolType :: ThreadPoolType
4291− } deriving (Eq, Show, Generic, Typeable)
4292−
4293−data ThreadPoolSize = ThreadPoolBounded Int
4294− | ThreadPoolUnbounded
4295− deriving (Eq, Show, Generic, Typeable)
4296−
4297−data ThreadPoolType = ThreadPoolScaling
4298− | ThreadPoolFixed
4299− | ThreadPoolCached
4300− deriving (Eq, Show, Generic, Typeable)
4301−
4302−data NodeJVMInfo = NodeJVMInfo {
4303− nodeJVMInfoMemoryPools :: [JVMMemoryPool]
4304− , nodeJVMInfoMemoryPoolsGCCollectors :: [JVMGCCollector]
4305− , nodeJVMInfoMemoryInfo :: JVMMemoryInfo
4306− , nodeJVMInfoStartTime :: UTCTime
4307− , nodeJVMInfoVMVendor :: Text
4308− , nodeJVMVMVersion :: VersionNumber
4309− -- ^ JVM doesn't seme to follow normal version conventions
4310− , nodeJVMVMName :: Text
4311− , nodeJVMVersion :: VersionNumber
4312− , nodeJVMPID :: PID
4313− } deriving (Eq, Show, Generic, Typeable)
4314−
4315−-- | Handles quirks in the way JVM versions are rendered (1.7.0_101 -> 1.7.0.101)
4316−newtype JVMVersion = JVMVersion { unJVMVersion :: VersionNumber }
4317−
4318−data JVMMemoryInfo = JVMMemoryInfo {
4319− jvmMemoryInfoDirectMax :: Bytes
4320− , jvmMemoryInfoNonHeapMax :: Bytes
4321− , jvmMemoryInfoNonHeapInit :: Bytes
4322− , jvmMemoryInfoHeapMax :: Bytes
4323− , jvmMemoryInfoHeapInit :: Bytes
4324− } deriving (Eq, Show, Generic, Typeable)
4325−
4326−newtype JVMMemoryPool = JVMMemoryPool {
4327− jvmMemoryPool :: Text
4328− } deriving (Eq, Show, Generic, Typeable, FromJSON)
4329−
4330−newtype JVMGCCollector = JVMGCCollector {
4331− jvmGCCollector :: Text
4332− } deriving (Eq, Show, Generic, Typeable, FromJSON)
4333−
4334−newtype PID = PID {
4335− pid :: Int
4336− } deriving (Eq, Show, Generic, Typeable, FromJSON)
4337−
4338−data NodeOSInfo = NodeOSInfo {
4339− nodeOSRefreshInterval :: NominalDiffTime
4340− , nodeOSName :: Text
4341− , nodeOSArch :: Text
4342− , nodeOSVersion :: VersionNumber
4343− , nodeOSAvailableProcessors :: Int
4344− , nodeOSAllocatedProcessors :: Int
4345− } deriving (Eq, Show, Generic, Typeable)
4346−
4347−data CPUInfo = CPUInfo {
4348− cpuCacheSize :: Bytes
4349− , cpuCoresPerSocket :: Int
4350− , cpuTotalSockets :: Int
4351− , cpuTotalCores :: Int
4352− , cpuMHZ :: Int
4353− , cpuModel :: Text
4354− , cpuVendor :: Text
4355− } deriving (Eq, Show, Generic, Typeable)
4356−
4357−data NodeProcessInfo = NodeProcessInfo {
4358− nodeProcessMLockAll :: Bool
4359− -- ^ See <https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration.html>
4360− , nodeProcessMaxFileDescriptors :: Maybe Int
4361− , nodeProcessId :: PID
4362− , nodeProcessRefreshInterval :: NominalDiffTime
4363− } deriving (Eq, Show, Generic, Typeable)
4364−
4365−data SnapshotRepoUpdateSettings = SnapshotRepoUpdateSettings {
4366− repoUpdateVerify :: Bool
4367− -- ^ After creation/update, synchronously check that nodes can
4368− -- write to this repo. Defaults to True. You may use False if you
4369− -- need a faster response and plan on verifying manually later
4370− -- with 'verifySnapshotRepo'.
4371− } deriving (Eq, Show, Generic, Typeable)
4372−
4373−
4374−-- | Reasonable defaults for repo creation/update
4375−--
4376−-- * repoUpdateVerify True
4377−defaultSnapshotRepoUpdateSettings :: SnapshotRepoUpdateSettings
4378−defaultSnapshotRepoUpdateSettings = SnapshotRepoUpdateSettings True
4379−
4380−
4381−-- | A filesystem-based snapshot repo that ships with
4382−-- ElasticSearch. This is an instance of 'SnapshotRepo' so it can be
4383−-- used with 'updateSnapshotRepo'
4384−data FsSnapshotRepo = FsSnapshotRepo {
4385− fsrName :: SnapshotRepoName
4386− , fsrLocation :: FilePath
4387− , fsrCompressMetadata :: Bool
4388− , fsrChunkSize :: Maybe Bytes
4389− -- ^ Size by which to split large files during snapshotting.
4390− , fsrMaxRestoreBytesPerSec :: Maybe Bytes
4391− -- ^ Throttle node restore rate. If not supplied, defaults to 40mb/sec
4392− , fsrMaxSnapshotBytesPerSec :: Maybe Bytes
4393− -- ^ Throttle node snapshot rate. If not supplied, defaults to 40mb/sec
4394− } deriving (Eq, Generic, Show, Typeable)
4395−
4396−
4397−instance SnapshotRepo FsSnapshotRepo where
4398− toGSnapshotRepo FsSnapshotRepo {..} =
4399− GenericSnapshotRepo fsrName fsRepoType (GenericSnapshotRepoSettings settings)
4400− where
4401− Object settings = object $ [ "location" .= fsrLocation
4402− , "compress" .= fsrCompressMetadata
4403− ] ++ optionalPairs
4404− optionalPairs = catMaybes [ ("chunk_size" .=) <$> fsrChunkSize
4405− , ("max_restore_bytes_per_sec" .=) <$> fsrMaxRestoreBytesPerSec
4406− , ("max_snapshot_bytes_per_sec" .=) <$> fsrMaxSnapshotBytesPerSec
4407− ]
4408− fromGSnapshotRepo GenericSnapshotRepo {..}
4409− | gSnapshotRepoType == fsRepoType = do
4410− let o = gSnapshotRepoSettingsObject gSnapshotRepoSettings
4411− parseRepo $ do
4412− FsSnapshotRepo gSnapshotRepoName <$> o .: "location"
4413− <*> o .:? "compress" .!= False
4414− <*> o .:? "chunk_size"
4415− <*> o .:? "max_restore_bytes_per_sec"
4416− <*> o .:? "max_snapshot_bytes_per_sec"
4417− | otherwise = Left (RepoTypeMismatch fsRepoType gSnapshotRepoType)
4418−
4419−
4420−parseRepo :: Parser a -> Either SnapshotRepoConversionError a
4421−parseRepo parser = case parseEither (const parser) () of
4422− Left e -> Left (OtherRepoConversionError (T.pack e))
4423− Right a -> Right a
4424−
4425−
4426−fsRepoType :: SnapshotRepoType
4427−fsRepoType = SnapshotRepoType "fs"
4428−
4429−-- | Law: fromGSnapshotRepo (toGSnapshotRepo r) == Right r
4430−class SnapshotRepo r where
4431− toGSnapshotRepo :: r -> GenericSnapshotRepo
4432− fromGSnapshotRepo :: GenericSnapshotRepo -> Either SnapshotRepoConversionError r
4433−
4434−
4435−data SnapshotRepoConversionError = RepoTypeMismatch SnapshotRepoType SnapshotRepoType
4436− -- ^ Expected type and actual type
4437− | OtherRepoConversionError Text
4438− deriving (Show, Eq, Generic, Typeable)
4439−
4440−
4441−instance Exception SnapshotRepoConversionError
4442−
4443−
4444−data SnapshotCreateSettings = SnapshotCreateSettings {
4445− snapWaitForCompletion :: Bool
4446− -- ^ Should the API call return immediately after initializing
4447− -- the snapshot or wait until completed? Note that if this is
4448− -- enabled it could wait a long time, so you should adjust your
4449− -- 'ManagerSettings' accordingly to set long timeouts or
4450− -- explicitly handle timeouts.
4451− , snapIndices :: Maybe IndexSelection
4452− -- ^ Nothing will snapshot all indices. Just [] is permissable and
4453− -- will essentially be a no-op snapshot.
4454− , snapIgnoreUnavailable :: Bool
4455− -- ^ If set to True, any matched indices that don't exist will be
4456− -- ignored. Otherwise it will be an error and fail.
4457− , snapIncludeGlobalState :: Bool
4458− , snapPartial :: Bool
4459− -- ^ If some indices failed to snapshot (e.g. if not all primary
4460− -- shards are available), should the process proceed?
4461− } deriving (Eq, Generic, Show, Typeable)
4462−
4463−
4464−-- | Reasonable defaults for snapshot creation
4465−--
4466−-- * snapWaitForCompletion False
4467−-- * snapIndices Nothing
4468−-- * snapIgnoreUnavailable False
4469−-- * snapIncludeGlobalState True
4470−-- * snapPartial False
4471−defaultSnapshotCreateSettings :: SnapshotCreateSettings
4472−defaultSnapshotCreateSettings = SnapshotCreateSettings {
4473− snapWaitForCompletion = False
4474− , snapIndices = Nothing
4475− , snapIgnoreUnavailable = False
4476− , snapIncludeGlobalState = True
4477− , snapPartial = False
4478− }
4479−
4480−
4481−data SnapshotSelection = SnapshotList (NonEmpty SnapshotPattern)
4482− | AllSnapshots deriving (Eq, Generic, Show, Typeable)
4483−
4484−
4485−-- | Either specifies an exact snapshot name or one with globs in it,
4486−-- e.g. @SnapPattern "foo*"@ __NOTE__: Patterns are not supported on
4487−-- ES < 1.7
4488−data SnapshotPattern = ExactSnap SnapshotName
4489− | SnapPattern Text
4490− deriving (Eq, Generic, Show, Typeable)
4491−
4492−
4493−-- | General information about the state of a snapshot. Has some
4494−-- redundancies with 'SnapshotStatus'
4495−data SnapshotInfo = SnapshotInfo {
4496− snapInfoShards :: ShardResult
4497− , snapInfoFailures :: [SnapshotShardFailure]
4498− , snapInfoDuration :: NominalDiffTime
4499− , snapInfoEndTime :: UTCTime
4500− , snapInfoStartTime :: UTCTime
4501− , snapInfoState :: SnapshotState
4502− , snapInfoIndices :: [IndexName]
4503− , snapInfoName :: SnapshotName
4504− } deriving (Eq, Generic, Show, Typeable)
4505−
4506−
4507−instance FromJSON SnapshotInfo where
4508− parseJSON = withObject "SnapshotInfo" parse
4509− where
4510− parse o = SnapshotInfo <$> o .: "shards"
4511− <*> o .: "failures"
4512− <*> (unMS <$> o .: "duration_in_millis")
4513− <*> (posixMS <$> o .: "end_time_in_millis")
4514− <*> (posixMS <$> o .: "start_time_in_millis")
4515− <*> o .: "state"
4516− <*> o .: "indices"
4517− <*> o .: "snapshot"
4518−
4519−data SnapshotShardFailure = SnapshotShardFailure {
4520− snapShardFailureIndex :: IndexName
4521− , snapShardFailureNodeId :: Maybe NodeName -- I'm not 100% sure this isn't actually 'FullNodeId'
4522− , snapShardFailureReason :: Text
4523− , snapShardFailureShardId :: ShardId
4524− } deriving (Eq, Show, Generic, Typeable)
4525−
4526−
4527−instance FromJSON SnapshotShardFailure where
4528− parseJSON = withObject "SnapshotShardFailure" parse
4529− where
4530− parse o = SnapshotShardFailure <$> o .: "index"
4531− <*> o .:? "node_id"
4532− <*> o .: "reason"
4533− <*> o .: "shard_id"
4534−
4535−
4536−newtype ShardId = ShardId { shardId :: Int }
4537− deriving (Eq, Show, Generic, Typeable, FromJSON)
4538−
4539−-- | Milliseconds
4540−newtype MS = MS NominalDiffTime
4541−
4542−
4543−-- keeps the unexported constructor warnings at bay
4544−unMS :: MS -> NominalDiffTime
4545−unMS (MS t) = t
4546−
4547−
4548−instance FromJSON MS where
4549− parseJSON = withScientific "MS" (return . MS . parse)
4550− where
4551− parse n = fromInteger ((truncate n) * 1000)
4552−
4553−
4554−data SnapshotState = SnapshotInit
4555− | SnapshotStarted
4556− | SnapshotSuccess
4557− | SnapshotFailed
4558− | SnapshotAborted
4559− | SnapshotMissing
4560− | SnapshotWaiting
4561− deriving (Show, Eq, Generic, Typeable)
4562−
4563−instance FromJSON SnapshotState where
4564− parseJSON = withText "SnapshotState" parse
4565− where
4566− parse "INIT" = return SnapshotInit
4567− parse "STARTED" = return SnapshotStarted
4568− parse "SUCCESS" = return SnapshotSuccess
4569− parse "FAILED" = return SnapshotFailed
4570− parse "ABORTED" = return SnapshotAborted
4571− parse "MISSING" = return SnapshotMissing
4572− parse "WAITING" = return SnapshotWaiting
4573− parse t = fail ("Invalid snapshot state " <> T.unpack t)
4574−
4575−
4576−newtype SnapshotName = SnapshotName { snapshotName :: Text }
4577− deriving (Show, Eq, Ord, Generic, Typeable, ToJSON, FromJSON)
4578−
4579−
4580−data SnapshotRestoreSettings = SnapshotRestoreSettings {
4581− snapRestoreWaitForCompletion :: Bool
4582− -- ^ Should the API call return immediately after initializing
4583− -- the restore or wait until completed? Note that if this is
4584− -- enabled, it could wait a long time, so you should adjust your
4585− -- 'ManagerSettings' accordingly to set long timeouts or
4586− -- explicitly handle timeouts.
4587− , snapRestoreIndices :: Maybe IndexSelection
4588− -- ^ Nothing will restore all indices in the snapshot. Just [] is
4589− -- permissable and will essentially be a no-op restore.
4590− , snapRestoreIgnoreUnavailable :: Bool
4591− -- ^ If set to True, any indices that do not exist will be ignored
4592− -- during snapshot rather than failing the restore.
4593− , snapRestoreIncludeGlobalState :: Bool
4594− -- ^ If set to false, will ignore any global state in the snapshot
4595− -- and will not restore it.
4596− , snapRestoreRenamePattern :: Maybe RestoreRenamePattern
4597− -- ^ A regex pattern for matching indices. Used with
4598− -- 'snapRestoreRenameReplacement', the restore can reference the
4599− -- matched index and create a new index name upon restore.
4600− , snapRestoreRenameReplacement :: Maybe (NonEmpty RestoreRenameToken)
4601− -- ^ Expression of how index renames should be constructed.
4602− , snapRestorePartial :: Bool
4603− -- ^ If some indices fail to restore, should the process proceed?
4604− , snapRestoreIncludeAliases :: Bool
4605− -- ^ Should the restore also restore the aliases captured in the
4606− -- snapshot.
4607− , snapRestoreIndexSettingsOverrides :: Maybe RestoreIndexSettings
4608− -- ^ Settings to apply during the restore process. __NOTE:__ This
4609− -- option is not supported in ES < 1.5 and should be set to
4610− -- Nothing in that case.
4611− , snapRestoreIgnoreIndexSettings :: Maybe (NonEmpty Text)
4612− -- ^ This type could be more rich but it isn't clear which
4613− -- settings are allowed to be ignored during restore, so we're
4614− -- going with including this feature in a basic form rather than
4615− -- omitting it. One example here would be
4616− -- "index.refresh_interval". Any setting specified here will
4617− -- revert back to the server default during the restore process.
4618− } deriving (Eq, Generic, Show, Typeable)
4619−
4620−-- | Regex-stype pattern, e.g. "index_(.+)" to match index names
4621−newtype RestoreRenamePattern = RestoreRenamePattern { rrPattern :: Text }
4622− deriving (Show, Eq, Generic, Typeable, Ord, ToJSON)
4623−
4624−
4625−-- | A single token in a index renaming scheme for a restore. These
4626−-- are concatenated into a string before being sent to
4627−-- ElasticSearch. Check out these Java
4628−-- <https://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html docs> to find out more if you're into that sort of thing.
4629−data RestoreRenameToken = RRTLit Text
4630− -- ^ Just a literal string of characters
4631− | RRSubWholeMatch
4632− -- ^ Equivalent to $0. The entire matched pattern, not any subgroup
4633− | RRSubGroup RRGroupRefNum
4634− -- ^ A specific reference to a group number
4635− deriving (Show, Eq, Generic, Typeable)
4636−
4637−
4638−-- | A group number for regex matching. Only values from 1-9 are
4639−-- supported. Construct with 'mkRRGroupRefNum'
4640−newtype RRGroupRefNum = RRGroupRefNum { rrGroupRefNum :: Int }
4641− deriving (Show, Eq, Generic, Typeable, Ord)
4642−
4643−instance Bounded RRGroupRefNum where
4644− minBound = RRGroupRefNum 1
4645− maxBound = RRGroupRefNum 9
4646−
4647−
4648−-- | Only allows valid group number references (1-9).
4649−mkRRGroupRefNum :: Int -> Maybe RRGroupRefNum
4650−mkRRGroupRefNum i
4651− | i >= (rrGroupRefNum minBound) && i <= (rrGroupRefNum maxBound) =
4652− Just $ RRGroupRefNum i
4653− | otherwise = Nothing
4654−
4655−
4656−-- | Reasonable defaults for snapshot restores
4657−--
4658−-- * snapRestoreWaitForCompletion False
4659−-- * snapRestoreIndices Nothing
4660−-- * snapRestoreIgnoreUnavailable False
4661−-- * snapRestoreIncludeGlobalState True
4662−-- * snapRestoreRenamePattern Nothing
4663−-- * snapRestoreRenameReplacement Nothing
4664−-- * snapRestorePartial False
4665−-- * snapRestoreIncludeAliases True
4666−-- * snapRestoreIndexSettingsOverrides Nothing
4667−-- * snapRestoreIgnoreIndexSettings Nothing
4668−defaultSnapshotRestoreSettings :: SnapshotRestoreSettings
4669−defaultSnapshotRestoreSettings = SnapshotRestoreSettings {
4670− snapRestoreWaitForCompletion = False
4671− , snapRestoreIndices = Nothing
4672− , snapRestoreIgnoreUnavailable = False
4673− , snapRestoreIncludeGlobalState = True
4674− , snapRestoreRenamePattern = Nothing
4675− , snapRestoreRenameReplacement = Nothing
4676− , snapRestorePartial = False
4677− , snapRestoreIncludeAliases = True
4678− , snapRestoreIndexSettingsOverrides = Nothing
4679− , snapRestoreIgnoreIndexSettings = Nothing
4680− }
4681−
4682−
4683−-- | Index settings that can be overridden. The docs only mention you
4684−-- can update number of replicas, but there may be more. You
4685−-- definitely cannot override shard count.
4686−data RestoreIndexSettings = RestoreIndexSettings {
4687− restoreOverrideReplicas :: Maybe ReplicaCount
4688− } deriving (Show, Eq, Generic, Typeable)
4689−
4690−
4691−instance ToJSON RestoreIndexSettings where
4692− toJSON RestoreIndexSettings {..} = object prs
4693− where
4694− prs = catMaybes [("index.number_of_replicas" .=) <$> restoreOverrideReplicas]
4695−
4696−
4697−instance FromJSON NodesInfo where
4698− parseJSON = withObject "NodesInfo" parse
4699− where
4700− parse o = do
4701− nodes <- o .: "nodes"
4702− infos <- forM (HM.toList nodes) $ \(fullNID, v) -> do
4703− node <- parseJSON v
4704− parseNodeInfo (FullNodeId fullNID) node
4705− cn <- o .: "cluster_name"
4706− return (NodesInfo infos cn)
4707−
4708−instance FromJSON NodesStats where
4709− parseJSON = withObject "NodesStats" parse
4710− where
4711− parse o = do
4712− nodes <- o .: "nodes"
4713− stats <- forM (HM.toList nodes) $ \(fullNID, v) -> do
4714− node <- parseJSON v
4715− parseNodeStats (FullNodeId fullNID) node
4716− cn <- o .: "cluster_name"
4717− return (NodesStats stats cn)
4718−
4719−instance FromJSON NodeBreakerStats where
4720− parseJSON = withObject "NodeBreakerStats" parse
4721− where
4722− parse o = NodeBreakerStats <$> o .: "tripped"
4723− <*> o .: "overhead"
4724− <*> o .: "estimated_size_in_bytes"
4725− <*> o .: "limit_size_in_bytes"
4726−
4727−instance FromJSON NodeHTTPStats where
4728− parseJSON = withObject "NodeHTTPStats" parse
4729− where
4730− parse o = NodeHTTPStats <$> o .: "total_opened"
4731− <*> o .: "current_open"
4732−
4733−instance FromJSON NodeTransportStats where
4734− parseJSON = withObject "NodeTransportStats" parse
4735− where
4736− parse o = NodeTransportStats <$> o .: "tx_size_in_bytes"
4737− <*> o .: "tx_count"
4738− <*> o .: "rx_size_in_bytes"
4739− <*> o .: "rx_count"
4740− <*> o .: "server_open"
4741−
4742−instance FromJSON NodeFSStats where
4743− parseJSON = withObject "NodeFSStats" parse
4744− where
4745− parse o = NodeFSStats <$> o .: "data"
4746− <*> o .: "total"
4747− <*> (posixMS <$> o .: "timestamp")
4748−
4749−instance FromJSON NodeDataPathStats where
4750− parseJSON = withObject "NodeDataPathStats" parse
4751− where
4752− parse o =
4753− NodeDataPathStats <$> (fmap unStringlyTypedDouble <$> o .:? "disk_service_time")
4754− <*> (fmap unStringlyTypedDouble <$> o .:? "disk_queue")
4755− <*> o .:? "disk_io_size_in_bytes"
4756− <*> o .:? "disk_write_size_in_bytes"
4757− <*> o .:? "disk_read_size_in_bytes"
4758− <*> o .:? "disk_io_op"
4759− <*> o .:? "disk_writes"
4760− <*> o .:? "disk_reads"
4761− <*> o .: "available_in_bytes"
4762− <*> o .: "free_in_bytes"
4763− <*> o .: "total_in_bytes"
4764− <*> o .:? "type"
4765− <*> o .:? "dev"
4766− <*> o .: "mount"
4767− <*> o .: "path"
4768−
4769−newtype StringlyTypedDouble = StringlyTypedDouble { unStringlyTypedDouble :: Double }
4770−
4771−instance FromJSON StringlyTypedDouble where
4772− parseJSON = fmap StringlyTypedDouble . parseJSON . unStringlyTypeJSON
4773−
4774−newtype StringlyTypedInt = StringlyTypedInt { unStringlyTypedInt :: Int }
4775−
4776−instance FromJSON StringlyTypedInt where
4777− parseJSON = fmap StringlyTypedInt . parseJSON . unStringlyTypeJSON
4778−
4779−instance FromJSON NodeFSTotalStats where
4780− parseJSON = withObject "NodeFSTotalStats" parse
4781− where
4782− parse o = NodeFSTotalStats <$> (fmap unStringlyTypedDouble <$> o .:? "disk_service_time")
4783− <*> (fmap unStringlyTypedDouble <$> o .:? "disk_queue")
4784− <*> o .:? "disk_io_size_in_bytes"
4785− <*> o .:? "disk_write_size_in_bytes"
4786− <*> o .:? "disk_read_size_in_bytes"
4787− <*> o .:? "disk_io_op"
4788− <*> o .:? "disk_writes"
4789− <*> o .:? "disk_reads"
4790− <*> o .: "available_in_bytes"
4791− <*> o .: "free_in_bytes"
4792− <*> o .: "total_in_bytes"
4793−
4794−instance FromJSON NodeNetworkStats where
4795− parseJSON = withObject "NodeNetworkStats" parse
4796− where
4797− parse o = do
4798− tcp <- o .: "tcp"
4799− NodeNetworkStats <$> tcp .: "out_rsts"
4800− <*> tcp .: "in_errs"
4801− <*> tcp .: "attempt_fails"
4802− <*> tcp .: "estab_resets"
4803− <*> tcp .: "retrans_segs"
4804− <*> tcp .: "out_segs"
4805− <*> tcp .: "in_segs"
4806− <*> tcp .: "curr_estab"
4807− <*> tcp .: "passive_opens"
4808− <*> tcp .: "active_opens"
4809−
4810−instance FromJSON NodeThreadPoolsStats where
4811− parseJSON = withObject "NodeThreadPoolsStats" parse
4812− where
4813− parse o = NodeThreadPoolsStats <$> o .: "snapshot"
4814− <*> o .: "bulk"
4815− <*> o .: "force_merge"
4816− <*> o .: "get"
4817− <*> o .: "management"
4818− <*> o .:? "fetch_shard_store"
4819− <*> o .:? "optimize"
4820− <*> o .: "flush"
4821− <*> o .: "search"
4822− <*> o .: "warmer"
4823− <*> o .: "generic"
4824− <*> o .:? "suggest"
4825− <*> o .: "refresh"
4826− <*> o .: "index"
4827− <*> o .:? "listener"
4828− <*> o .:? "fetch_shard_started"
4829− <*> o .:? "percolate"
4830−instance FromJSON NodeThreadPoolStats where
4831− parseJSON = withObject "NodeThreadPoolStats" parse
4832− where
4833− parse o = NodeThreadPoolStats <$> o .: "completed"
4834− <*> o .: "largest"
4835− <*> o .: "rejected"
4836− <*> o .: "active"
4837− <*> o .: "queue"
4838− <*> o .: "threads"
4839−
4840−instance FromJSON NodeJVMStats where
4841− parseJSON = withObject "NodeJVMStats" parse
4842− where
4843− parse o = do
4844− bufferPools <- o .: "buffer_pools"
4845− mapped <- bufferPools .: "mapped"
4846− direct <- bufferPools .: "direct"
4847− gc <- o .: "gc"
4848− collectors <- gc .: "collectors"
4849− oldC <- collectors .: "old"
4850− youngC <- collectors .: "young"
4851− threads <- o .: "threads"
4852− mem <- o .: "mem"
4853− pools <- mem .: "pools"
4854− oldM <- pools .: "old"
4855− survivorM <- pools .: "survivor"
4856− youngM <- pools .: "young"
4857− NodeJVMStats <$> pure mapped
4858− <*> pure direct
4859− <*> pure oldC
4860− <*> pure youngC
4861− <*> threads .: "peak_count"
4862− <*> threads .: "count"
4863− <*> pure oldM
4864− <*> pure survivorM
4865− <*> pure youngM
4866− <*> mem .: "non_heap_committed_in_bytes"
4867− <*> mem .: "non_heap_used_in_bytes"
4868− <*> mem .: "heap_max_in_bytes"
4869− <*> mem .: "heap_committed_in_bytes"
4870− <*> mem .: "heap_used_percent"
4871− <*> mem .: "heap_used_in_bytes"
4872− <*> (unMS <$> o .: "uptime_in_millis")
4873− <*> (posixMS <$> o .: "timestamp")
4874−
4875−instance FromJSON JVMBufferPoolStats where
4876− parseJSON = withObject "JVMBufferPoolStats" parse
4877− where
4878− parse o = JVMBufferPoolStats <$> o .: "total_capacity_in_bytes"
4879− <*> o .: "used_in_bytes"
4880− <*> o .: "count"
4881−
4882−instance FromJSON JVMGCStats where
4883− parseJSON = withObject "JVMGCStats" parse
4884− where
4885− parse o = JVMGCStats <$> (unMS <$> o .: "collection_time_in_millis")
4886− <*> o .: "collection_count"
4887−
4888−instance FromJSON JVMPoolStats where
4889− parseJSON = withObject "JVMPoolStats" parse
4890− where
4891− parse o = JVMPoolStats <$> o .: "peak_max_in_bytes"
4892− <*> o .: "peak_used_in_bytes"
4893− <*> o .: "max_in_bytes"
4894− <*> o .: "used_in_bytes"
4895−
4896−instance FromJSON NodeProcessStats where
4897− parseJSON = withObject "NodeProcessStats" parse
4898− where
4899− parse o = do
4900− mem <- o .: "mem"
4901− cpu <- o .: "cpu"
4902− NodeProcessStats <$> (posixMS <$> o .: "timestamp")
4903− <*> o .: "open_file_descriptors"
4904− <*> o .: "max_file_descriptors"
4905− <*> cpu .: "percent"
4906− <*> (unMS <$> cpu .: "total_in_millis")
4907− <*> mem .: "total_virtual_in_bytes"
4908−
4909−instance FromJSON NodeOSStats where
4910− parseJSON = withObject "NodeOSStats" parse
4911− where
4912− parse o = do
4913− swap <- o .: "swap"
4914− mem <- o .: "mem"
4915− cpu <- o .: "cpu"
4916− load <- o .:? "load_average"
4917− NodeOSStats <$> (posixMS <$> o .: "timestamp")
4918− <*> cpu .: "percent"
4919− <*> pure load
4920− <*> mem .: "total_in_bytes"
4921− <*> mem .: "free_in_bytes"
4922− <*> mem .: "free_percent"
4923− <*> mem .: "used_in_bytes"
4924− <*> mem .: "used_percent"
4925− <*> swap .: "total_in_bytes"
4926− <*> swap .: "free_in_bytes"
4927− <*> swap .: "used_in_bytes"
4928−
4929−instance FromJSON LoadAvgs where
4930− parseJSON = withArray "LoadAvgs" parse
4931− where
4932− parse v = case V.toList v of
4933− [one, five, fifteen] -> LoadAvgs <$> parseJSON one
4934− <*> parseJSON five
4935− <*> parseJSON fifteen
4936− _ -> fail "Expecting a triple of Doubles"
4937−
4938−instance FromJSON NodeIndicesStats where
4939− parseJSON = withObject "NodeIndicesStats" parse
4940− where
4941− parse o = do
4942− let (.::) mv k = case mv of
4943− Just v -> Just <$> v .: k
4944− Nothing -> pure Nothing
4945− mRecovery <- o .:? "recovery"
4946− mQueryCache <- o .:? "query_cache"
4947− mSuggest <- o .:? "suggest"
4948− translog <- o .: "translog"
4949− segments <- o .: "segments"
4950− completion <- o .: "completion"
4951− mPercolate <- o .:? "percolate"
4952− fielddata <- o .: "fielddata"
4953− warmer <- o .: "warmer"
4954− flush <- o .: "flush"
4955− refresh <- o .: "refresh"
4956− merges <- o .: "merges"
4957− search <- o .: "search"
4958− getStats <- o .: "get"
4959− indexing <- o .: "indexing"
4960− store <- o .: "store"
4961− docs <- o .: "docs"
4962− NodeIndicesStats <$> (fmap unMS <$> mRecovery .:: "throttle_time_in_millis")
4963− <*> mRecovery .:: "current_as_target"
4964− <*> mRecovery .:: "current_as_source"
4965− <*> mQueryCache .:: "miss_count"
4966− <*> mQueryCache .:: "hit_count"
4967− <*> mQueryCache .:: "evictions"
4968− <*> mQueryCache .:: "memory_size_in_bytes"
4969− <*> mSuggest .:: "current"
4970− <*> (fmap unMS <$> mSuggest .:: "time_in_millis")
4971− <*> mSuggest .:: "total"
4972− <*> translog .: "size_in_bytes"
4973− <*> translog .: "operations"
4974− <*> segments .:? "fixed_bit_set_memory_in_bytes"
4975− <*> segments .: "version_map_memory_in_bytes"
4976− <*> segments .:? "index_writer_max_memory_in_bytes"
4977− <*> segments .: "index_writer_memory_in_bytes"
4978− <*> segments .: "memory_in_bytes"
4979− <*> segments .: "count"
4980− <*> completion .: "size_in_bytes"
4981− <*> mPercolate .:: "queries"
4982− <*> mPercolate .:: "memory_size_in_bytes"
4983− <*> mPercolate .:: "current"
4984− <*> (fmap unMS <$> mPercolate .:: "time_in_millis")
4985− <*> mPercolate .:: "total"
4986− <*> fielddata .: "evictions"
4987− <*> fielddata .: "memory_size_in_bytes"
4988− <*> (unMS <$> warmer .: "total_time_in_millis")
4989− <*> warmer .: "total"
4990− <*> warmer .: "current"
4991− <*> (unMS <$> flush .: "total_time_in_millis")
4992− <*> flush .: "total"
4993− <*> (unMS <$> refresh .: "total_time_in_millis")
4994− <*> refresh .: "total"
4995− <*> merges .: "total_size_in_bytes"
4996− <*> merges .: "total_docs"
4997− <*> (unMS <$> merges .: "total_time_in_millis")
4998− <*> merges .: "total"
4999− <*> merges .: "current_size_in_bytes"
5000− <*> merges .: "current_docs"
5001− <*> merges .: "current"
5002− <*> search .: "fetch_current"
5003− <*> (unMS <$> search .: "fetch_time_in_millis")
5004− <*> search .: "fetch_total"
5005− <*> search .: "query_current"
5006− <*> (unMS <$> search .: "query_time_in_millis")
5007− <*> search .: "query_total"
5008− <*> search .: "open_contexts"
5009− <*> getStats .: "current"
5010− <*> (unMS <$> getStats .: "missing_time_in_millis")
5011− <*> getStats .: "missing_total"
5012− <*> (unMS <$> getStats .: "exists_time_in_millis")
5013− <*> getStats .: "exists_total"
5014− <*> (unMS <$> getStats .: "time_in_millis")
5015− <*> getStats .: "total"
5016− <*> (fmap unMS <$> indexing .:? "throttle_time_in_millis")
5017− <*> indexing .:? "is_throttled"
5018− <*> indexing .:? "noop_update_total"
5019− <*> indexing .: "delete_current"
5020− <*> (unMS <$> indexing .: "delete_time_in_millis")
5021− <*> indexing .: "delete_total"
5022− <*> indexing .: "index_current"
5023− <*> (unMS <$> indexing .: "index_time_in_millis")
5024− <*> indexing .: "index_total"
5025− <*> (unMS <$> store .: "throttle_time_in_millis")
5026− <*> store .: "size_in_bytes"
5027− <*> docs .: "deleted"
5028− <*> docs .: "count"
5029−
5030−instance FromJSON NodeBreakersStats where
5031− parseJSON = withObject "NodeBreakersStats" parse
5032− where
5033− parse o = NodeBreakersStats <$> o .: "parent"
5034− <*> o .: "request"
5035− <*> o .: "fielddata"
5036−
5037−parseNodeStats :: FullNodeId -> Object -> Parser NodeStats
5038−parseNodeStats fnid o = do
5039− NodeStats <$> o .: "name"
5040− <*> pure fnid
5041− <*> o .:? "breakers"
5042− <*> o .: "http"
5043− <*> o .: "transport"
5044− <*> o .: "fs"
5045− <*> o .:? "network"
5046− <*> o .: "thread_pool"
5047− <*> o .: "jvm"
5048− <*> o .: "process"
5049− <*> o .: "os"
5050− <*> o .: "indices"
5051−
5052−parseNodeInfo :: FullNodeId -> Object -> Parser NodeInfo
5053−parseNodeInfo nid o =
5054− NodeInfo <$> o .:? "http_address"
5055− <*> o .: "build_hash"
5056− <*> o .: "version"
5057− <*> o .: "ip"
5058− <*> o .: "host"
5059− <*> o .: "transport_address"
5060− <*> o .: "name"
5061− <*> pure nid
5062− <*> o .: "plugins"
5063− <*> o .: "http"
5064− <*> o .: "transport"
5065− <*> o .:? "network"
5066− <*> o .: "thread_pool"
5067− <*> o .: "jvm"
5068− <*> o .: "process"
5069− <*> o .: "os"
5070− <*> o .: "settings"
5071−
5072−instance FromJSON NodePluginInfo where
5073− parseJSON = withObject "NodePluginInfo" parse
5074− where
5075− parse o = NodePluginInfo <$> o .:? "site"
5076− <*> o .:? "jvm"
5077− <*> o .: "description"
5078− <*> o .: "version"
5079− <*> o .: "name"
5080−
5081−instance FromJSON NodeHTTPInfo where
5082− parseJSON = withObject "NodeHTTPInfo" parse
5083− where
5084− parse o = NodeHTTPInfo <$> o .: "max_content_length_in_bytes"
5085− <*> parseJSON (Object o)
5086−
5087−instance FromJSON BoundTransportAddress where
5088− parseJSON = withObject "BoundTransportAddress" parse
5089− where
5090− parse o = BoundTransportAddress <$> o .: "publish_address"
5091− <*> o .: "bound_address"
5092−
5093−instance FromJSON NodeOSInfo where
5094− parseJSON = withObject "NodeOSInfo" parse
5095− where
5096− parse o = do
5097− NodeOSInfo <$> (unMS <$> o .: "refresh_interval_in_millis")
5098− <*> o .: "name"
5099− <*> o .: "arch"
5100− <*> o .: "version"
5101− <*> o .: "available_processors"
5102− <*> o .: "allocated_processors"
5103−
5104−
5105−instance FromJSON CPUInfo where
5106− parseJSON = withObject "CPUInfo" parse
5107− where
5108− parse o = CPUInfo <$> o .: "cache_size_in_bytes"
5109− <*> o .: "cores_per_socket"
5110− <*> o .: "total_sockets"
5111− <*> o .: "total_cores"
5112− <*> o .: "mhz"
5113− <*> o .: "model"
5114− <*> o .: "vendor"
5115−
5116−instance FromJSON NodeProcessInfo where
5117− parseJSON = withObject "NodeProcessInfo" parse
5118− where
5119− parse o = NodeProcessInfo <$> o .: "mlockall"
5120− <*> o .:? "max_file_descriptors"
5121− <*> o .: "id"
5122− <*> (unMS <$> o .: "refresh_interval_in_millis")
5123−
5124−instance FromJSON NodeJVMInfo where
5125− parseJSON = withObject "NodeJVMInfo" parse
5126− where
5127− parse o = NodeJVMInfo <$> o .: "memory_pools"
5128− <*> o .: "gc_collectors"
5129− <*> o .: "mem"
5130− <*> (posixMS <$> o .: "start_time_in_millis")
5131− <*> o .: "vm_vendor"
5132− <*> o .: "vm_version"
5133− <*> o .: "vm_name"
5134− <*> (unJVMVersion <$> o .: "version")
5135− <*> o .: "pid"
5136−
5137−instance FromJSON JVMVersion where
5138− parseJSON (String t) =
5139− JVMVersion <$> parseJSON (String (T.replace "_" "." t))
5140− parseJSON v = JVMVersion <$> parseJSON v
5141−
5142−instance FromJSON JVMMemoryInfo where
5143− parseJSON = withObject "JVMMemoryInfo" parse
5144− where
5145− parse o = JVMMemoryInfo <$> o .: "direct_max_in_bytes"
5146− <*> o .: "non_heap_max_in_bytes"
5147− <*> o .: "non_heap_init_in_bytes"
5148− <*> o .: "heap_max_in_bytes"
5149− <*> o .: "heap_init_in_bytes"
5150−
5151−instance FromJSON NodeThreadPoolsInfo where
5152− parseJSON = withObject "NodeThreadPoolsInfo" parse
5153− where
5154− parse o = NodeThreadPoolsInfo <$> o .: "refresh"
5155− <*> o .: "management"
5156− <*> o .:? "percolate"
5157− <*> o .:? "listener"
5158− <*> o .:? "fetch_shard_started"
5159− <*> o .: "search"
5160− <*> o .: "flush"
5161− <*> o .: "warmer"
5162− <*> o .:? "optimize"
5163− <*> o .: "bulk"
5164− <*> o .:? "suggest"
5165− <*> o .: "force_merge"
5166− <*> o .: "snapshot"
5167− <*> o .: "get"
5168− <*> o .:? "fetch_shard_store"
5169− <*> o .: "index"
5170− <*> o .: "generic"
5171−
5172−instance FromJSON NodeThreadPoolInfo where
5173− parseJSON = withObject "NodeThreadPoolInfo" parse
5174− where
5175− parse o = do
5176− ka <- maybe (return Nothing) (fmap Just . parseStringInterval) =<< o .:? "keep_alive"
5177− NodeThreadPoolInfo <$> (parseJSON . unStringlyTypeJSON =<< o .: "queue_size")
5178− <*> pure ka
5179− <*> o .:? "min"
5180− <*> o .:? "max"
5181− <*> o .: "type"
5182−
5183−parseStringInterval :: (Monad m) => String -> m NominalDiffTime
5184−parseStringInterval s = case span isNumber s of
5185− ("", _) -> fail "Invalid interval"
5186− (nS, unitS) -> case (readMay nS, readMay unitS) of
5187− (Just n, Just unit) -> return (fromInteger (n * unitNDT unit))
5188− (Nothing, _) -> fail "Invalid interval number"
5189− (_, Nothing) -> fail "Invalid interval unit"
5190− where
5191− unitNDT Seconds = 1
5192− unitNDT Minutes = 60
5193− unitNDT Hours = 60 * 60
5194− unitNDT Days = 24 * 60 * 60
5195− unitNDT Weeks = 7 * 24 * 60 * 60
5196−
5197−instance FromJSON ThreadPoolSize where
5198− parseJSON v = parseAsNumber v <|> parseAsString v
5199− where
5200− parseAsNumber = parseAsInt <=< parseJSON
5201− parseAsInt (-1) = return ThreadPoolUnbounded
5202− parseAsInt n
5203− | n >= 0 = return (ThreadPoolBounded n)
5204− | otherwise = fail "Thread pool size must be >= -1."
5205− parseAsString = withText "ThreadPoolSize" $ \t ->
5206− case first (readMay . T.unpack) (T.span isNumber t) of
5207− (Just n, "k") -> return (ThreadPoolBounded (n * 1000))
5208− (Just n, "") -> return (ThreadPoolBounded n)
5209− _ -> fail ("Invalid thread pool size " <> T.unpack t)
5210−
5211−instance FromJSON ThreadPoolType where
5212− parseJSON = withText "ThreadPoolType" parse
5213− where
5214− parse "scaling" = return ThreadPoolScaling
5215− parse "fixed" = return ThreadPoolFixed
5216− parse "cached" = return ThreadPoolCached
5217− parse e = fail ("Unexpected thread pool type" <> T.unpack e)
5218−
5219−instance FromJSON NodeTransportInfo where
5220− parseJSON = withObject "NodeTransportInfo" parse
5221− where
5222− parse o = NodeTransportInfo <$> (maybe (return mempty) parseProfiles =<< o .:? "profiles")
5223− <*> parseJSON (Object o)
5224− parseProfiles (Object o) | HM.null o = return []
5225− parseProfiles v@(Array _) = parseJSON v
5226− parseProfiles Null = return []
5227− parseProfiles _ = fail "Could not parse profiles"
5228−
5229−instance FromJSON NodeNetworkInfo where
5230− parseJSON = withObject "NodeNetworkInfo" parse
5231− where
5232− parse o = NodeNetworkInfo <$> o .: "primary_interface"
5233− <*> (unMS <$> o .: "refresh_interval_in_millis")
5234−
5235−
5236−instance FromJSON NodeNetworkInterface where
5237− parseJSON = withObject "NodeNetworkInterface" parse
5238− where
5239− parse o = NodeNetworkInterface <$> o .: "mac_address"
5240− <*> o .: "name"
5241− <*> o .: "address"
5242
1581
5243−newtype MaybeNA a = MaybeNA { unMaybeNA :: Maybe a }
5244− deriving (Show, Eq)
5245
1582
5246−instance FromJSON a => FromJSON (MaybeNA a) where
5247− parseJSON (String "NA") = pure $ MaybeNA Nothing
5248− parseJSON o = MaybeNA . Just <$> parseJSON o
5249
1583
5250data Suggest = Suggest { suggestText :: Text
1584data Suggest = Suggest { suggestText :: Text
5251 , suggestName :: Text
1585 , suggestName :: Text
5252 , suggestType :: SuggestType
1586 , suggestType :: SuggestType
5253 }
1587 }
5254− deriving (Show, Generic, Eq, Read)
1588+ deriving (Eq, Show)
5255
1589
5256instance ToJSON Suggest where
1590instance ToJSON Suggest where
5257 toJSON Suggest{..} = object [ "text" .= suggestText
1591 toJSON Suggest{..} = object [ "text" .= suggestText
@@ -5270,7 +1604,7 @@ instance FromJSON Suggest where
5270 parseJSON x = typeMismatch "Suggest" x
1604 parseJSON x = typeMismatch "Suggest" x
5271
1605
5272data SuggestType = SuggestTypePhraseSuggester PhraseSuggester
1606data SuggestType = SuggestTypePhraseSuggester PhraseSuggester
5273− deriving (Show, Generic, Eq, Read)
1607+ deriving (Eq, Show)
5274
1608
5275instance ToJSON SuggestType where
1609instance ToJSON SuggestType where
5276 toJSON (SuggestTypePhraseSuggester x) = object ["phrase" .= x]
1610 toJSON (SuggestTypePhraseSuggester x) = object ["phrase" .= x]
@@ -5294,7 +1628,7 @@ data PhraseSuggester =
5294 , phraseSuggesterHighlight :: Maybe PhraseSuggesterHighlighter
1628 , phraseSuggesterHighlight :: Maybe PhraseSuggesterHighlighter
5295 , phraseSuggesterCollate :: Maybe PhraseSuggesterCollate
1629 , phraseSuggesterCollate :: Maybe PhraseSuggesterCollate
5296 }
1630 }
5297− deriving (Show, Generic, Eq, Read)
1631+ deriving (Eq, Show)
5298
1632
5299instance ToJSON PhraseSuggester where
1633instance ToJSON PhraseSuggester where
5300 toJSON PhraseSuggester{..} = omitNulls [ "field" .= phraseSuggesterField
1634 toJSON PhraseSuggester{..} = omitNulls [ "field" .= phraseSuggesterField
@@ -5334,7 +1668,7 @@ data PhraseSuggesterHighlighter =
5334 PhraseSuggesterHighlighter { phraseSuggesterHighlighterPreTag :: Text
1668 PhraseSuggesterHighlighter { phraseSuggesterHighlighterPreTag :: Text
5335 , phraseSuggesterHighlighterPostTag :: Text
1669 , phraseSuggesterHighlighterPostTag :: Text
5336 }
1670 }
5337− deriving (Show, Generic, Eq, Read)
1671+ deriving (Eq, Show)
5338
1672
5339instance ToJSON PhraseSuggesterHighlighter where
1673instance ToJSON PhraseSuggesterHighlighter where
5340 toJSON PhraseSuggesterHighlighter{..} =
1674 toJSON PhraseSuggesterHighlighter{..} =
@@ -5352,7 +1686,7 @@ data PhraseSuggesterCollate =
5352 PhraseSuggesterCollate { phraseSuggesterCollateTemplateQuery :: TemplateQueryInline
1686 PhraseSuggesterCollate { phraseSuggesterCollateTemplateQuery :: TemplateQueryInline
5353 , phraseSuggesterCollatePrune :: Bool
1687 , phraseSuggesterCollatePrune :: Bool
5354 }
1688 }
5355− deriving (Show, Generic, Eq, Read)
1689+ deriving (Eq, Show)
5356
1690
5357instance ToJSON PhraseSuggesterCollate where
1691instance ToJSON PhraseSuggesterCollate where
5358 toJSON PhraseSuggesterCollate{..} = object [ "query" .= object
1692 toJSON PhraseSuggesterCollate{..} = object [ "query" .= object
src/Database/V5/Bloodhound/Types/Internal.hsdeleted−57
@@ -1,57 +0,0 @@
1−{-# LANGUAGE DeriveDataTypeable #-}
2−{-# LANGUAGE DeriveGeneric #-}
3−{-# LANGUAGE FlexibleInstances #-}
4−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5−
6−-------------------------------------------------------------------------------
7−-- |
8−-- Module : Database.Bloodhound.Types.Internal
9−-- Copyright : (C) 2014 Chris Allen
10−-- License : BSD-style (see the file LICENSE)
11−-- Maintainer : Chris Allen <cma@bitemyapp.com>
12−-- Stability : provisional
13−-- Portability : DeriveGeneric, RecordWildCards
14−--
15−-- Internal data types for Bloodhound. These types may change without
16−-- notice so import at your own risk.
17−-------------------------------------------------------------------------------
18−module Database.V5.Bloodhound.Types.Internal
19− ( BHEnv(..)
20− , Server(..)
21− , MonadBH(..)
22− ) where
23−
24−
25−import Control.Applicative as A
26−import Control.Monad.Reader
27−import Data.Aeson
28−import Data.Text (Text)
29−import Data.Typeable (Typeable)
30−import GHC.Generics (Generic)
31−import Network.HTTP.Client
32−
33−{-| Common environment for Elasticsearch calls. Connections will be
34− pipelined according to the provided HTTP connection manager.
35−-}
36−data BHEnv = BHEnv { bhServer :: Server
37− , bhManager :: Manager
38− , bhRequestHook :: Request -> IO Request
39− -- ^ Low-level hook that is run before every request is sent. Used to implement custom authentication strategies. Defaults to 'return' with 'mkBHEnv'.
40− }
41−
42−instance (Functor m, Applicative m, MonadIO m) => MonadBH (ReaderT BHEnv m) where
43− getBHEnv = ask
44−
45−{-| 'Server' is used with the client functions to point at the ES instance
46−-}
47−newtype Server = Server Text deriving (Eq, Show, Generic, Typeable, FromJSON)
48−
49−{-| All API calls to Elasticsearch operate within
50− MonadBH
51− . The idea is that it can be easily embedded in your
52− own monad transformer stack. A default instance for a ReaderT and
53− alias 'BH' is provided for the simple case.
54−-}
55−class (Functor m, A.Applicative m, MonadIO m) => MonadBH m where
56− getBHEnv :: m BHEnv
57−
src/Database/V5/Bloodhound/Types/Internal/Analysis.hsnew file+104
@@ -0,0 +1,104 @@
1+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+
4+module Database.V5.Bloodhound.Types.Internal.Analysis where
5+
6+import Data.Aeson
7+import Data.Aeson.Types ( Pair, Parser,
8+ emptyObject,
9+ parseEither, parseMaybe,
10+ typeMismatch
11+ )
12+import qualified Data.Map.Strict as M
13+import Data.Maybe (catMaybes)
14+import Data.Text (Text)
15+
16+import Database.V5.Bloodhound.Types.Internal.StringlyTyped
17+
18+data Analysis = Analysis
19+ { analysisAnalyzer :: M.Map Text AnalyzerDefinition
20+ , analysisTokenizer :: M.Map Text TokenizerDefinition
21+ } deriving (Eq, Show)
22+
23+instance ToJSON Analysis where
24+ toJSON (Analysis analyzer tokenizer) = object
25+ [ "analyzer" .= analyzer
26+ , "tokenizer" .= tokenizer
27+ ]
28+
29+instance FromJSON Analysis where
30+ parseJSON = withObject "Analysis" $ \m -> Analysis
31+ <$> m .: "analyzer"
32+ <*> m .: "tokenizer"
33+
34+newtype Tokenizer =
35+ Tokenizer Text
36+ deriving (Eq, Show, ToJSON, FromJSON)
37+
38+data AnalyzerDefinition = AnalyzerDefinition
39+ { analyzerDefinitionTokenizer :: Maybe Tokenizer
40+ } deriving (Eq,Show)
41+
42+instance ToJSON AnalyzerDefinition where
43+ toJSON (AnalyzerDefinition tokenizer) = object $ catMaybes
44+ [ fmap ("tokenizer" .=) tokenizer
45+ ]
46+
47+instance FromJSON AnalyzerDefinition where
48+ parseJSON = withObject "AnalyzerDefinition" $ \m -> AnalyzerDefinition
49+ <$> m .:? "tokenizer"
50+
51+
52+data TokenizerDefinition
53+ = TokenizerDefinitionNgram Ngram
54+ deriving (Eq,Show)
55+
56+instance ToJSON TokenizerDefinition where
57+ toJSON x = case x of
58+ TokenizerDefinitionNgram (Ngram minGram maxGram tokenChars) -> object
59+ [ "type" .= ("ngram" :: Text)
60+ , "min_gram" .= minGram
61+ , "max_gram" .= maxGram
62+ , "token_chars" .= tokenChars
63+ ]
64+
65+instance FromJSON TokenizerDefinition where
66+ parseJSON = withObject "TokenizerDefinition" $ \m -> do
67+ typ <- m .: "type" :: Parser Text
68+ case typ of
69+ "ngram" -> fmap TokenizerDefinitionNgram $ Ngram
70+ <$> (fmap unStringlyTypedInt (m .: "min_gram"))
71+ <*> (fmap unStringlyTypedInt (m .: "max_gram"))
72+ <*> m .: "token_chars"
73+ _ -> fail "invalid TokenizerDefinition"
74+
75+data Ngram = Ngram
76+ { ngramMinGram :: Int
77+ , ngramMaxGram :: Int
78+ , ngramTokenChars :: [TokenChar]
79+ } deriving (Eq,Show)
80+
81+data TokenChar =
82+ TokenLetter
83+ | TokenDigit
84+ | TokenWhitespace
85+ | TokenPunctuation
86+ | TokenSymbol
87+ deriving (Eq,Show)
88+
89+instance ToJSON TokenChar where
90+ toJSON t = String $ case t of
91+ TokenLetter -> "letter"
92+ TokenDigit -> "digit"
93+ TokenWhitespace -> "whitespace"
94+ TokenPunctuation -> "punctuation"
95+ TokenSymbol -> "symbol"
96+
97+instance FromJSON TokenChar where
98+ parseJSON = withText "TokenChar" $ \t -> case t of
99+ "letter" -> return TokenLetter
100+ "digit" -> return TokenDigit
101+ "whitespace" -> return TokenWhitespace
102+ "punctuation" -> return TokenPunctuation
103+ "symbol" -> return TokenSymbol
104+ _ -> fail "invalid TokenChar"
src/Database/V5/Bloodhound/Types/Internal/Client.hsnew file+2062
@@ -0,0 +1,2062 @@
1+{-# LANGUAGE FlexibleInstances #-}
2+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3+{-# LANGUAGE MultiParamTypeClasses #-}
4+{-# LANGUAGE OverloadedStrings #-}
5+{-# LANGUAGE RecordWildCards #-}
6+{-# LANGUAGE UndecidableInstances #-}
7+
8+module Database.V5.Bloodhound.Types.Internal.Client where
9+
10+import Bloodhound.Import
11+
12+import qualified Data.Text as T
13+import qualified Data.HashMap.Strict as HM
14+import qualified Data.Vector as V
15+import qualified Data.Version as Vers
16+import GHC.Enum
17+import Network.HTTP.Client
18+import qualified Text.ParserCombinators.ReadP as RP
19+import Text.Read (Read(..))
20+import qualified Text.Read as TR
21+
22+import Database.V5.Bloodhound.Types.Internal.Analysis
23+import Database.V5.Bloodhound.Types.Internal.Newtypes
24+import Database.V5.Bloodhound.Types.Internal.Query
25+import Database.V5.Bloodhound.Types.Internal.StringlyTyped
26+
27+{-| Common environment for Elasticsearch calls. Connections will be
28+ pipelined according to the provided HTTP connection manager.
29+-}
30+data BHEnv = BHEnv { bhServer :: Server
31+ , bhManager :: Manager
32+ , bhRequestHook :: Request -> IO Request
33+ -- ^ Low-level hook that is run before every request is sent. Used to implement custom authentication strategies. Defaults to 'return' with 'mkBHEnv'.
34+ }
35+
36+instance (Functor m, Applicative m, MonadIO m) => MonadBH (ReaderT BHEnv m) where
37+ getBHEnv = ask
38+
39+{-| 'Server' is used with the client functions to point at the ES instance
40+-}
41+newtype Server = Server Text deriving (Eq, Show, FromJSON)
42+
43+{-| All API calls to Elasticsearch operate within
44+ MonadBH
45+ . The idea is that it can be easily embedded in your
46+ own monad transformer stack. A default instance for a ReaderT and
47+ alias 'BH' is provided for the simple case.
48+-}
49+class (Functor m, Applicative m, MonadIO m) => MonadBH m where
50+ getBHEnv :: m BHEnv
51+
52+-- | Create a 'BHEnv' with all optional fields defaulted. HTTP hook
53+-- will be a noop. You can use the exported fields to customize
54+-- it further, e.g.:
55+--
56+-- >> (mkBHEnv myServer myManager) { bhRequestHook = customHook }
57+mkBHEnv :: Server -> Manager -> BHEnv
58+mkBHEnv s m = BHEnv s m return
59+
60+newtype BH m a = BH {
61+ unBH :: ReaderT BHEnv m a
62+ } deriving ( Functor
63+ , Applicative
64+ , Monad
65+ , MonadIO
66+ , MonadState s
67+ , MonadWriter w
68+ , MonadError e
69+ , Alternative
70+ , MonadPlus
71+ , MonadFix
72+ , MonadThrow
73+ , MonadCatch
74+ , MonadMask)
75+
76+instance MonadTrans BH where
77+ lift = BH . lift
78+
79+instance (MonadReader r m) => MonadReader r (BH m) where
80+ ask = lift ask
81+ local f (BH (ReaderT m)) = BH $ ReaderT $ \r ->
82+ local f (m r)
83+
84+instance (Functor m, Applicative m, MonadIO m) => MonadBH (BH m) where
85+ getBHEnv = BH getBHEnv
86+
87+runBH :: BHEnv -> BH m a -> m a
88+runBH e f = runReaderT (unBH f) e
89+
90+{-| 'Version' is embedded in 'Status' -}
91+data Version = Version { number :: VersionNumber
92+ , build_hash :: BuildHash
93+ , build_date :: UTCTime
94+ , build_snapshot :: Bool
95+ , lucene_version :: VersionNumber }
96+ deriving (Eq, Show)
97+
98+-- | Traditional software versioning number
99+newtype VersionNumber = VersionNumber
100+ { versionNumber :: Vers.Version }
101+ deriving (Eq, Ord, Show)
102+
103+{-| 'Status' is a data type for describing the JSON body returned by
104+ Elasticsearch when you query its status. This was deprecated in 1.2.0.
105+
106+ <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-status.html#indices-status>
107+-}
108+
109+data Status = Status
110+ { name :: Text
111+ , cluster_name :: Text
112+ , cluster_uuid :: Text
113+ , version :: Version
114+ , tagline :: Text }
115+ deriving (Eq, Show)
116+
117+{-| 'IndexSettings' is used to configure the shards and replicas when
118+ you create an Elasticsearch Index.
119+
120+ <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html>
121+-}
122+
123+data IndexSettings = IndexSettings
124+ { indexShards :: ShardCount
125+ , indexReplicas :: ReplicaCount }
126+ deriving (Eq, Show)
127+
128+{-| 'defaultIndexSettings' is an 'IndexSettings' with 3 shards and
129+ 2 replicas. -}
130+defaultIndexSettings :: IndexSettings
131+defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
132+-- defaultIndexSettings is exported by Database.Bloodhound as well
133+-- no trailing slashes in servers, library handles building the path.
134+
135+
136+{-| 'ForceMergeIndexSettings' is used to configure index optimization. See
137+ <https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-forcemerge.html>
138+ for more info.
139+-}
140+data ForceMergeIndexSettings =
141+ ForceMergeIndexSettings { maxNumSegments :: Maybe Int
142+ -- ^ Number of segments to optimize to. 1 will fully optimize the index. If omitted, the default behavior is to only optimize if the server deems it necessary.
143+ , onlyExpungeDeletes :: Bool
144+ -- ^ Should the optimize process only expunge segments with deletes in them? If the purpose of the optimization is to free disk space, this should be set to True.
145+ , flushAfterOptimize :: Bool
146+ -- ^ Should a flush be performed after the optimize.
147+ } deriving (Eq, Show)
148+
149+
150+{-| 'defaultForceMergeIndexSettings' implements the default settings that
151+ ElasticSearch uses for index optimization. 'maxNumSegments' is Nothing,
152+ 'onlyExpungeDeletes' is False, and flushAfterOptimize is True.
153+-}
154+defaultForceMergeIndexSettings :: ForceMergeIndexSettings
155+defaultForceMergeIndexSettings = ForceMergeIndexSettings Nothing False True
156+
157+{-| 'UpdatableIndexSetting' are settings which may be updated after an index is created.
158+
159+ <https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html>
160+-}
161+data UpdatableIndexSetting = NumberOfReplicas ReplicaCount
162+ -- ^ The number of replicas each shard has.
163+ | AutoExpandReplicas ReplicaBounds
164+ | BlocksReadOnly Bool
165+ -- ^ Set to True to have the index read only. False to allow writes and metadata changes.
166+ | BlocksRead Bool
167+ -- ^ Set to True to disable read operations against the index.
168+ | BlocksWrite Bool
169+ -- ^ Set to True to disable write operations against the index.
170+ | BlocksMetaData Bool
171+ -- ^ Set to True to disable metadata operations against the index.
172+ | RefreshInterval NominalDiffTime
173+ -- ^ The async refresh interval of a shard
174+ | IndexConcurrency Int
175+ | FailOnMergeFailure Bool
176+ | TranslogFlushThresholdOps Int
177+ -- ^ When to flush on operations.
178+ | TranslogFlushThresholdSize Bytes
179+ -- ^ When to flush based on translog (bytes) size.
180+ | TranslogFlushThresholdPeriod NominalDiffTime
181+ -- ^ When to flush based on a period of not flushing.
182+ | TranslogDisableFlush Bool
183+ -- ^ Disables flushing. Note, should be set for a short interval and then enabled.
184+ | CacheFilterMaxSize (Maybe Bytes)
185+ -- ^ The maximum size of filter cache (per segment in shard).
186+ | CacheFilterExpire (Maybe NominalDiffTime)
187+ -- ^ The expire after access time for filter cache.
188+ | GatewaySnapshotInterval NominalDiffTime
189+ -- ^ The gateway snapshot interval (only applies to shared gateways).
190+ | RoutingAllocationInclude (NonEmpty NodeAttrFilter)
191+ -- ^ A node matching any rule will be allowed to host shards from the index.
192+ | RoutingAllocationExclude (NonEmpty NodeAttrFilter)
193+ -- ^ A node matching any rule will NOT be allowed to host shards from the index.
194+ | RoutingAllocationRequire (NonEmpty NodeAttrFilter)
195+ -- ^ Only nodes matching all rules will be allowed to host shards from the index.
196+ | RoutingAllocationEnable AllocationPolicy
197+ -- ^ Enables shard allocation for a specific index.
198+ | RoutingAllocationShardsPerNode ShardCount
199+ -- ^ Controls the total number of shards (replicas and primaries) allowed to be allocated on a single node.
200+ | RecoveryInitialShards InitialShardCount
201+ -- ^ When using local gateway a particular shard is recovered only if there can be allocated quorum shards in the cluster.
202+ | GCDeletes NominalDiffTime
203+ | TTLDisablePurge Bool
204+ -- ^ Disables temporarily the purge of expired docs.
205+ | TranslogFSType FSType
206+ | CompressionSetting Compression
207+ | IndexCompoundFormat CompoundFormat
208+ | IndexCompoundOnFlush Bool
209+ | WarmerEnabled Bool
210+ | MappingTotalFieldsLimit Int
211+ | AnalysisSetting Analysis
212+ -- ^ Analysis is not a dynamic setting and can only be performed on a closed index.
213+ deriving (Eq, Show)
214+
215+data ReplicaBounds = ReplicasBounded Int Int
216+ | ReplicasLowerBounded Int
217+ | ReplicasUnbounded
218+ deriving (Eq, Show)
219+
220+data Compression
221+ = CompressionDefault
222+ -- ^ Compress with LZ4
223+ | CompressionBest
224+ -- ^ Compress with DEFLATE. Elastic
225+ -- <https://www.elastic.co/blog/elasticsearch-storage-the-true-story-2.0 blogs>
226+ -- that this can reduce disk use by 15%-25%.
227+ deriving (Eq,Show)
228+
229+instance ToJSON Compression where
230+ toJSON x = case x of
231+ CompressionDefault -> toJSON ("default" :: Text)
232+ CompressionBest -> toJSON ("best_compression" :: Text)
233+
234+instance FromJSON Compression where
235+ parseJSON = withText "Compression" $ \t -> case t of
236+ "default" -> return CompressionDefault
237+ "best_compression" -> return CompressionBest
238+ _ -> fail "invalid compression codec"
239+
240+-- | A measure of bytes used for various configurations. You may want
241+-- to use smart constructors like 'gigabytes' for larger values.
242+--
243+-- >>> gigabytes 9
244+-- Bytes 9000000000
245+--
246+-- >>> megabytes 9
247+-- Bytes 9000000
248+--
249+-- >>> kilobytes 9
250+-- Bytes 9000
251+newtype Bytes =
252+ Bytes Int
253+ deriving (Eq, Show, Ord, ToJSON, FromJSON)
254+
255+gigabytes :: Int -> Bytes
256+gigabytes n = megabytes (1000 * n)
257+
258+
259+megabytes :: Int -> Bytes
260+megabytes n = kilobytes (1000 * n)
261+
262+
263+kilobytes :: Int -> Bytes
264+kilobytes n = Bytes (1000 * n)
265+
266+
267+data FSType = FSSimple
268+ | FSBuffered deriving (Eq, Show)
269+
270+data InitialShardCount = QuorumShards
271+ | QuorumMinus1Shards
272+ | FullShards
273+ | FullMinus1Shards
274+ | ExplicitShards Int
275+ deriving (Eq, Show)
276+
277+data NodeAttrFilter = NodeAttrFilter
278+ { nodeAttrFilterName :: NodeAttrName
279+ , nodeAttrFilterValues :: NonEmpty Text }
280+ deriving (Eq, Show)
281+
282+newtype NodeAttrName = NodeAttrName Text deriving (Eq, Show)
283+
284+data CompoundFormat = CompoundFileFormat Bool
285+ | MergeSegmentVsTotalIndex Double
286+ -- ^ percentage between 0 and 1 where 0 is false, 1 is true
287+ deriving (Eq, Show)
288+
289+newtype NominalDiffTimeJSON = NominalDiffTimeJSON { ndtJSON :: NominalDiffTime }
290+
291+data IndexSettingsSummary = IndexSettingsSummary { sSummaryIndexName :: IndexName
292+ , sSummaryFixedSettings :: IndexSettings
293+ , sSummaryUpdateable :: [UpdatableIndexSetting]}
294+ deriving (Eq, Show)
295+
296+{-| 'Reply' and 'Method' are type synonyms from 'Network.HTTP.Types.Method.Method' -}
297+type Reply = Network.HTTP.Client.Response LByteString
298+
299+{-| 'OpenCloseIndex' is a sum type for opening and closing indices.
300+
301+ <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-open-close.html>
302+-}
303+data OpenCloseIndex = OpenIndex | CloseIndex deriving (Eq, Show)
304+
305+data FieldType = GeoPointType
306+ | GeoShapeType
307+ | FloatType
308+ | IntegerType
309+ | LongType
310+ | ShortType
311+ | ByteType deriving (Eq, Show)
312+
313+data FieldDefinition =
314+ FieldDefinition { fieldType :: FieldType } deriving (Eq, Show)
315+
316+{-| An 'IndexTemplate' defines a template that will automatically be
317+ applied to new indices created. The templates include both
318+ 'IndexSettings' and mappings, and a simple 'TemplatePattern' that
319+ controls if the template will be applied to the index created.
320+ Specify mappings as follows: @[toJSON TweetMapping, ...]@
321+
322+ https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-templates.html
323+-}
324+data IndexTemplate =
325+ IndexTemplate { templatePattern :: TemplatePattern
326+ , templateSettings :: Maybe IndexSettings
327+ , templateMappings :: [Value]
328+ }
329+
330+data MappingField =
331+ MappingField { mappingFieldName :: FieldName
332+ , fieldDefinition :: FieldDefinition }
333+ deriving (Eq, Show)
334+
335+{-| Support for type reification of 'Mapping's is currently incomplete, for
336+ now the mapping API verbiage expects a 'ToJSON'able blob.
337+
338+ Indexes have mappings, mappings are schemas for the documents contained
339+ in the index. I'd recommend having only one mapping per index, always
340+ having a mapping, and keeping different kinds of documents separated
341+ if possible.
342+-}
343+data Mapping =
344+ Mapping { typeName :: TypeName
345+ , mappingFields :: [MappingField] }
346+ deriving (Eq, Show)
347+
348+data AllocationPolicy = AllocAll
349+ -- ^ Allows shard allocation for all shards.
350+ | AllocPrimaries
351+ -- ^ Allows shard allocation only for primary shards.
352+ | AllocNewPrimaries
353+ -- ^ Allows shard allocation only for primary shards for new indices.
354+ | AllocNone
355+ -- ^ No shard allocation is allowed
356+ deriving (Eq, Show)
357+
358+{-| 'BulkOperation' is a sum type for expressing the four kinds of bulk
359+ operation index, create, delete, and update. 'BulkIndex' behaves like an
360+ "upsert", 'BulkCreate' will fail if a document already exists at the DocId.
361+
362+ <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-bulk.html#docs-bulk>
363+-}
364+data BulkOperation =
365+ BulkIndex IndexName MappingName DocId Value
366+ | BulkCreate IndexName MappingName DocId Value
367+ | BulkCreateEncoding IndexName MappingName DocId Encoding
368+ | BulkDelete IndexName MappingName DocId
369+ | BulkUpdate IndexName MappingName DocId Value deriving (Eq, Show)
370+
371+{-| 'EsResult' describes the standard wrapper JSON document that you see in
372+ successful Elasticsearch lookups or lookups that couldn't find the document.
373+-}
374+data EsResult a = EsResult { _index :: Text
375+ , _type :: Text
376+ , _id :: Text
377+ , foundResult :: Maybe (EsResultFound a)} deriving (Eq, Show)
378+
379+{-| 'EsResultFound' contains the document and its metadata inside of an
380+ 'EsResult' when the document was successfully found.
381+-}
382+data EsResultFound a =
383+ EsResultFound { _version :: DocVersion
384+ , _source :: a }
385+ deriving (Eq, Show)
386+
387+{-| 'EsError' is the generic type that will be returned when there was a
388+ problem. If you can't parse the expected response, its a good idea to
389+ try parsing this.
390+-}
391+data EsError =
392+ EsError { errorStatus :: Int
393+ , errorMessage :: Text }
394+ deriving (Eq, Show)
395+
396+{-| 'EsProtocolException' will be thrown if Bloodhound cannot parse a response
397+returned by the ElasticSearch server. If you encounter this error, please
398+verify that your domain data types and FromJSON instances are working properly
399+(for example, the 'a' of '[Hit a]' in 'SearchResult.searchHits.hits'). If you're
400+sure that your mappings are correct, then this error may be an indication of an
401+incompatibility between Bloodhound and ElasticSearch. Please open a bug report
402+and be sure to include the exception body.
403+-}
404+data EsProtocolException = EsProtocolException { esProtoExBody :: LByteString }
405+ deriving (Eq, Show)
406+
407+instance Exception EsProtocolException
408+
409+data IndexAlias = IndexAlias { srcIndex :: IndexName
410+ , indexAlias :: IndexAliasName } deriving (Eq, Show)
411+
412+data IndexAliasAction =
413+ AddAlias IndexAlias IndexAliasCreate
414+ | RemoveAlias IndexAlias
415+ deriving (Eq, Show)
416+
417+data IndexAliasCreate =
418+ IndexAliasCreate { aliasCreateRouting :: Maybe AliasRouting
419+ , aliasCreateFilter :: Maybe Filter}
420+ deriving (Eq, Show)
421+
422+data AliasRouting =
423+ AllAliasRouting RoutingValue
424+ | GranularAliasRouting (Maybe SearchAliasRouting) (Maybe IndexAliasRouting)
425+ deriving (Eq, Show)
426+
427+newtype SearchAliasRouting =
428+ SearchAliasRouting (NonEmpty RoutingValue)
429+ deriving (Eq, Show)
430+
431+newtype IndexAliasRouting =
432+ IndexAliasRouting RoutingValue
433+ deriving (Eq, Show, ToJSON, FromJSON)
434+
435+newtype RoutingValue =
436+ RoutingValue { routingValue :: Text }
437+ deriving (Eq, Show, ToJSON, FromJSON)
438+
439+newtype IndexAliasesSummary =
440+ IndexAliasesSummary { indexAliasesSummary :: [IndexAliasSummary] }
441+ deriving (Eq, Show)
442+
443+{-| 'IndexAliasSummary' is a summary of an index alias configured for a server. -}
444+data IndexAliasSummary = IndexAliasSummary
445+ { indexAliasSummaryAlias :: IndexAlias
446+ , indexAliasSummaryCreate :: IndexAliasCreate }
447+ deriving (Eq, Show)
448+
449+{-| 'DocVersion' is an integer version number for a document between 1
450+and 9.2e+18 used for <<https://www.elastic.co/guide/en/elasticsearch/guide/current/optimistic-concurrency-control.html optimistic concurrency control>>.
451+-}
452+newtype DocVersion = DocVersion {
453+ docVersionNumber :: Int
454+ } deriving (Eq, Show, Ord, ToJSON)
455+
456+-- | Smart constructor for in-range doc version
457+mkDocVersion :: Int -> Maybe DocVersion
458+mkDocVersion i
459+ | i >= (docVersionNumber minBound) && i <= (docVersionNumber maxBound) =
460+ Just $ DocVersion i
461+ | otherwise = Nothing
462+
463+
464+{-| 'ExternalDocVersion' is a convenience wrapper if your code uses its
465+own version numbers instead of ones from ES.
466+-}
467+newtype ExternalDocVersion = ExternalDocVersion DocVersion
468+ deriving (Eq, Show, Ord, Bounded, Enum, ToJSON)
469+
470+{-| 'VersionControl' is specified when indexing documents as a
471+optimistic concurrency control.
472+-}
473+data VersionControl = NoVersionControl
474+ -- ^ Don't send a version. This is a pure overwrite.
475+ | InternalVersion DocVersion
476+ -- ^ Use the default ES versioning scheme. Only
477+ -- index the document if the version is the same
478+ -- as the one specified. Only applicable to
479+ -- updates, as you should be getting Version from
480+ -- a search result.
481+ | ExternalGT ExternalDocVersion
482+ -- ^ Use your own version numbering. Only index
483+ -- the document if the version is strictly higher
484+ -- OR the document doesn't exist. The given
485+ -- version will be used as the new version number
486+ -- for the stored document. N.B. All updates must
487+ -- increment this number, meaning there is some
488+ -- global, external ordering of updates.
489+ | ExternalGTE ExternalDocVersion
490+ -- ^ Use your own version numbering. Only index
491+ -- the document if the version is equal or higher
492+ -- than the stored version. Will succeed if there
493+ -- is no existing document. The given version will
494+ -- be used as the new version number for the
495+ -- stored document. Use with care, as this could
496+ -- result in data loss.
497+ | ForceVersion ExternalDocVersion
498+ -- ^ The document will always be indexed and the
499+ -- given version will be the new version. This is
500+ -- typically used for correcting errors. Use with
501+ -- care, as this could result in data loss.
502+ deriving (Eq, Show, Ord)
503+
504+{-| 'DocumentParent' is used to specify a parent document.
505+-}
506+newtype DocumentParent = DocumentParent DocId
507+ deriving (Eq, Show)
508+
509+{-| 'IndexDocumentSettings' are special settings supplied when indexing
510+a document. For the best backwards compatiblity when new fields are
511+added, you should probably prefer to start with 'defaultIndexDocumentSettings'
512+-}
513+data IndexDocumentSettings =
514+ IndexDocumentSettings { idsVersionControl :: VersionControl
515+ , idsParent :: Maybe DocumentParent
516+ } deriving (Eq, Show)
517+
518+{-| Reasonable default settings. Chooses no version control and no parent.
519+-}
520+defaultIndexDocumentSettings :: IndexDocumentSettings
521+defaultIndexDocumentSettings = IndexDocumentSettings NoVersionControl Nothing
522+
523+{-| 'IndexSelection' is used for APIs which take a single index, a list of
524+ indexes, or the special @_all@ index.
525+-}
526+--TODO: this does not fully support <https://www.elastic.co/guide/en/elasticsearch/reference/1.7/multi-index.html multi-index syntax>. It wouldn't be too hard to implement but you'd have to add the optional parameters (ignore_unavailable, allow_no_indices, expand_wildcards) to any APIs using it. Also would be a breaking API.
527+data IndexSelection =
528+ IndexList (NonEmpty IndexName)
529+ | AllIndexes
530+ deriving (Eq, Show)
531+
532+{-| 'NodeSelection' is used for most cluster APIs. See <https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster.html#cluster-nodes here> for more details.
533+-}
534+data NodeSelection =
535+ LocalNode
536+ -- ^ Whatever node receives this request
537+ | NodeList (NonEmpty NodeSelector)
538+ | AllNodes
539+ deriving (Eq, Show)
540+
541+
542+-- | An exact match or pattern to identify a node. Note that All of
543+-- these options support wildcarding, so your node name, server, attr
544+-- name can all contain * characters to be a fuzzy match.
545+data NodeSelector =
546+ NodeByName NodeName
547+ | NodeByFullNodeId FullNodeId
548+ | NodeByHost Server
549+ -- ^ e.g. 10.0.0.1 or even 10.0.0.*
550+ | NodeByAttribute NodeAttrName Text
551+ -- ^ NodeAttrName can be a pattern, e.g. rack*. The value can too.
552+ deriving (Eq, Show)
553+
554+{-| 'TemplateName' is used to describe which template to query/create/delete
555+-}
556+newtype TemplateName = TemplateName Text deriving (Eq, Show, ToJSON, FromJSON)
557+
558+{-| 'TemplatePattern' represents a pattern which is matched against index names
559+-}
560+newtype TemplatePattern = TemplatePattern Text deriving (Eq, Show, ToJSON, FromJSON)
561+
562+-- This insanity is because ES *sometimes* returns Replica/Shard counts as strings
563+instance FromJSON ReplicaCount where
564+ parseJSON v = parseAsInt v
565+ <|> parseAsString v
566+ where parseAsInt = fmap ReplicaCount . parseJSON
567+ parseAsString = withText "ReplicaCount" (fmap ReplicaCount . parseReadText)
568+
569+instance FromJSON ShardCount where
570+ parseJSON v = parseAsInt v
571+ <|> parseAsString v
572+ where parseAsInt = fmap ShardCount . parseJSON
573+ parseAsString = withText "ShardCount" (fmap ShardCount . parseReadText)
574+
575+instance Bounded DocVersion where
576+ minBound = DocVersion 1
577+ maxBound = DocVersion 9200000000000000000 -- 9.2e+18
578+
579+instance Enum DocVersion where
580+ succ x
581+ | x /= maxBound = DocVersion (succ $ docVersionNumber x)
582+ | otherwise = succError "DocVersion"
583+ pred x
584+ | x /= minBound = DocVersion (pred $ docVersionNumber x)
585+ | otherwise = predError "DocVersion"
586+ toEnum i =
587+ fromMaybe (error $ show i ++ " out of DocVersion range") $ mkDocVersion i
588+ fromEnum = docVersionNumber
589+ enumFrom = boundedEnumFrom
590+ enumFromThen = boundedEnumFromThen
591+
592+-- | Username type used for HTTP Basic authentication. See 'basicAuthHook'.
593+newtype EsUsername = EsUsername { esUsername :: Text } deriving (Read, Show, Eq)
594+
595+-- | Password type used for HTTP Basic authentication. See 'basicAuthHook'.
596+newtype EsPassword = EsPassword { esPassword :: Text } deriving (Read, Show, Eq)
597+
598+
599+data SnapshotRepoSelection =
600+ SnapshotRepoList (NonEmpty SnapshotRepoPattern)
601+ | AllSnapshotRepos
602+ deriving (Eq, Show)
603+
604+
605+-- | Either specifies an exact repo name or one with globs in it,
606+-- e.g. @RepoPattern "foo*"@ __NOTE__: Patterns are not supported on ES < 1.7
607+data SnapshotRepoPattern =
608+ ExactRepo SnapshotRepoName
609+ | RepoPattern Text
610+ deriving (Eq, Show)
611+
612+-- | The unique name of a snapshot repository.
613+newtype SnapshotRepoName =
614+ SnapshotRepoName { snapshotRepoName :: Text }
615+ deriving (Eq, Ord, Show, ToJSON, FromJSON)
616+
617+
618+-- | A generic representation of a snapshot repo. This is what gets
619+-- sent to and parsed from the server. For repo types enabled by
620+-- plugins that aren't exported by this library, consider making a
621+-- custom type which implements 'SnapshotRepo'. If it is a common repo
622+-- type, consider submitting a pull request to have it included in the
623+-- library proper
624+data GenericSnapshotRepo = GenericSnapshotRepo {
625+ gSnapshotRepoName :: SnapshotRepoName
626+ , gSnapshotRepoType :: SnapshotRepoType
627+ , gSnapshotRepoSettings :: GenericSnapshotRepoSettings
628+ } deriving (Eq, Show)
629+
630+
631+instance SnapshotRepo GenericSnapshotRepo where
632+ toGSnapshotRepo = id
633+ fromGSnapshotRepo = Right
634+
635+
636+newtype SnapshotRepoType =
637+ SnapshotRepoType { snapshotRepoType :: Text }
638+ deriving (Eq, Ord, Show, ToJSON, FromJSON)
639+
640+
641+-- | Opaque representation of snapshot repo settings. Instances of
642+-- 'SnapshotRepo' will produce this.
643+newtype GenericSnapshotRepoSettings =
644+ GenericSnapshotRepoSettings { gSnapshotRepoSettingsObject :: Object }
645+ deriving (Eq, Show, ToJSON)
646+
647+
648+ -- Regardless of whether you send strongly typed json, my version of
649+ -- ES sends back stringly typed json in the settings, e.g. booleans
650+ -- as strings, so we'll try to convert them.
651+instance FromJSON GenericSnapshotRepoSettings where
652+ parseJSON = fmap (GenericSnapshotRepoSettings . fmap unStringlyTypeJSON). parseJSON
653+
654+-- | The result of running 'verifySnapshotRepo'.
655+newtype SnapshotVerification =
656+ SnapshotVerification {
657+ snapshotNodeVerifications :: [SnapshotNodeVerification]
658+ } deriving (Eq, Show)
659+
660+
661+instance FromJSON SnapshotVerification where
662+ parseJSON = withObject "SnapshotVerification" parse
663+ where
664+ parse o = do
665+ o2 <- o .: "nodes"
666+ SnapshotVerification <$> mapM (uncurry parse') (HM.toList o2)
667+ parse' rawFullId = withObject "SnapshotNodeVerification" $ \o ->
668+ SnapshotNodeVerification (FullNodeId rawFullId) <$> o .: "name"
669+
670+
671+-- | A node that has verified a snapshot
672+data SnapshotNodeVerification = SnapshotNodeVerification {
673+ snvFullId :: FullNodeId
674+ , snvNodeName :: NodeName
675+ } deriving (Eq, Show)
676+
677+
678+-- | Unique, automatically-generated name assigned to nodes that are
679+-- usually returned in node-oriented APIs.
680+newtype FullNodeId = FullNodeId { fullNodeId :: Text }
681+ deriving (Eq, Ord, Show, FromJSON)
682+
683+
684+-- | A human-readable node name that is supplied by the user in the
685+-- node config or automatically generated by ElasticSearch.
686+newtype NodeName = NodeName { nodeName :: Text }
687+ deriving (Eq, Ord, Show, FromJSON)
688+
689+newtype ClusterName = ClusterName { clusterName :: Text }
690+ deriving (Eq, Ord, Show, FromJSON)
691+
692+data NodesInfo = NodesInfo {
693+ nodesInfo :: [NodeInfo]
694+ , nodesClusterName :: ClusterName
695+ } deriving (Eq, Show)
696+
697+data NodesStats = NodesStats {
698+ nodesStats :: [NodeStats]
699+ , nodesStatsClusterName :: ClusterName
700+ } deriving (Eq, Show)
701+
702+data NodeStats = NodeStats {
703+ nodeStatsName :: NodeName
704+ , nodeStatsFullId :: FullNodeId
705+ , nodeStatsBreakersStats :: Maybe NodeBreakersStats
706+ , nodeStatsHTTP :: NodeHTTPStats
707+ , nodeStatsTransport :: NodeTransportStats
708+ , nodeStatsFS :: NodeFSStats
709+ , nodeStatsNetwork :: Maybe NodeNetworkStats
710+ , nodeStatsThreadPool :: NodeThreadPoolsStats
711+ , nodeStatsJVM :: NodeJVMStats
712+ , nodeStatsProcess :: NodeProcessStats
713+ , nodeStatsOS :: NodeOSStats
714+ , nodeStatsIndices :: NodeIndicesStats
715+ } deriving (Eq, Show)
716+
717+data NodeBreakersStats = NodeBreakersStats {
718+ nodeStatsParentBreaker :: NodeBreakerStats
719+ , nodeStatsRequestBreaker :: NodeBreakerStats
720+ , nodeStatsFieldDataBreaker :: NodeBreakerStats
721+ } deriving (Eq, Show)
722+
723+data NodeBreakerStats = NodeBreakerStats {
724+ nodeBreakersTripped :: Int
725+ , nodeBreakersOverhead :: Double
726+ , nodeBreakersEstSize :: Bytes
727+ , nodeBreakersLimitSize :: Bytes
728+ } deriving (Eq, Show)
729+
730+data NodeHTTPStats = NodeHTTPStats {
731+ nodeHTTPTotalOpened :: Int
732+ , nodeHTTPCurrentOpen :: Int
733+ } deriving (Eq, Show)
734+
735+data NodeTransportStats = NodeTransportStats {
736+ nodeTransportTXSize :: Bytes
737+ , nodeTransportCount :: Int
738+ , nodeTransportRXSize :: Bytes
739+ , nodeTransportRXCount :: Int
740+ , nodeTransportServerOpen :: Int
741+ } deriving (Eq, Show)
742+
743+data NodeFSStats = NodeFSStats {
744+ nodeFSDataPaths :: [NodeDataPathStats]
745+ , nodeFSTotal :: NodeFSTotalStats
746+ , nodeFSTimestamp :: UTCTime
747+ } deriving (Eq, Show)
748+
749+data NodeDataPathStats = NodeDataPathStats {
750+ nodeDataPathDiskServiceTime :: Maybe Double
751+ , nodeDataPathDiskQueue :: Maybe Double
752+ , nodeDataPathIOSize :: Maybe Bytes
753+ , nodeDataPathWriteSize :: Maybe Bytes
754+ , nodeDataPathReadSize :: Maybe Bytes
755+ , nodeDataPathIOOps :: Maybe Int
756+ , nodeDataPathWrites :: Maybe Int
757+ , nodeDataPathReads :: Maybe Int
758+ , nodeDataPathAvailable :: Bytes
759+ , nodeDataPathFree :: Bytes
760+ , nodeDataPathTotal :: Bytes
761+ , nodeDataPathType :: Maybe Text
762+ , nodeDataPathDevice :: Maybe Text
763+ , nodeDataPathMount :: Text
764+ , nodeDataPathPath :: Text
765+ } deriving (Eq, Show)
766+
767+data NodeFSTotalStats = NodeFSTotalStats {
768+ nodeFSTotalDiskServiceTime :: Maybe Double
769+ , nodeFSTotalDiskQueue :: Maybe Double
770+ , nodeFSTotalIOSize :: Maybe Bytes
771+ , nodeFSTotalWriteSize :: Maybe Bytes
772+ , nodeFSTotalReadSize :: Maybe Bytes
773+ , nodeFSTotalIOOps :: Maybe Int
774+ , nodeFSTotalWrites :: Maybe Int
775+ , nodeFSTotalReads :: Maybe Int
776+ , nodeFSTotalAvailable :: Bytes
777+ , nodeFSTotalFree :: Bytes
778+ , nodeFSTotalTotal :: Bytes
779+ } deriving (Eq, Show)
780+
781+data NodeNetworkStats = NodeNetworkStats {
782+ nodeNetTCPOutRSTs :: Int
783+ , nodeNetTCPInErrs :: Int
784+ , nodeNetTCPAttemptFails :: Int
785+ , nodeNetTCPEstabResets :: Int
786+ , nodeNetTCPRetransSegs :: Int
787+ , nodeNetTCPOutSegs :: Int
788+ , nodeNetTCPInSegs :: Int
789+ , nodeNetTCPCurrEstab :: Int
790+ , nodeNetTCPPassiveOpens :: Int
791+ , nodeNetTCPActiveOpens :: Int
792+ } deriving (Eq, Show)
793+
794+data NodeThreadPoolsStats = NodeThreadPoolsStats {
795+ nodeThreadPoolsStatsSnapshot :: NodeThreadPoolStats
796+ , nodeThreadPoolsStatsBulk :: NodeThreadPoolStats
797+ , nodeThreadPoolsStatsMerge :: NodeThreadPoolStats
798+ , nodeThreadPoolsStatsGet :: NodeThreadPoolStats
799+ , nodeThreadPoolsStatsManagement :: NodeThreadPoolStats
800+ , nodeThreadPoolsStatsFetchShardStore :: Maybe NodeThreadPoolStats
801+ , nodeThreadPoolsStatsOptimize :: Maybe NodeThreadPoolStats
802+ , nodeThreadPoolsStatsFlush :: NodeThreadPoolStats
803+ , nodeThreadPoolsStatsSearch :: NodeThreadPoolStats
804+ , nodeThreadPoolsStatsWarmer :: NodeThreadPoolStats
805+ , nodeThreadPoolsStatsGeneric :: NodeThreadPoolStats
806+ , nodeThreadPoolsStatsSuggest :: Maybe NodeThreadPoolStats
807+ , nodeThreadPoolsStatsRefresh :: NodeThreadPoolStats
808+ , nodeThreadPoolsStatsIndex :: NodeThreadPoolStats
809+ , nodeThreadPoolsStatsListener :: Maybe NodeThreadPoolStats
810+ , nodeThreadPoolsStatsFetchShardStarted :: Maybe NodeThreadPoolStats
811+ , nodeThreadPoolsStatsPercolate :: Maybe NodeThreadPoolStats
812+ } deriving (Eq, Show)
813+
814+data NodeThreadPoolStats = NodeThreadPoolStats {
815+ nodeThreadPoolCompleted :: Int
816+ , nodeThreadPoolLargest :: Int
817+ , nodeThreadPoolRejected :: Int
818+ , nodeThreadPoolActive :: Int
819+ , nodeThreadPoolQueue :: Int
820+ , nodeThreadPoolThreads :: Int
821+ } deriving (Eq, Show)
822+
823+data NodeJVMStats = NodeJVMStats {
824+ nodeJVMStatsMappedBufferPool :: JVMBufferPoolStats
825+ , nodeJVMStatsDirectBufferPool :: JVMBufferPoolStats
826+ , nodeJVMStatsGCOldCollector :: JVMGCStats
827+ , nodeJVMStatsGCYoungCollector :: JVMGCStats
828+ , nodeJVMStatsPeakThreadsCount :: Int
829+ , nodeJVMStatsThreadsCount :: Int
830+ , nodeJVMStatsOldPool :: JVMPoolStats
831+ , nodeJVMStatsSurvivorPool :: JVMPoolStats
832+ , nodeJVMStatsYoungPool :: JVMPoolStats
833+ , nodeJVMStatsNonHeapCommitted :: Bytes
834+ , nodeJVMStatsNonHeapUsed :: Bytes
835+ , nodeJVMStatsHeapMax :: Bytes
836+ , nodeJVMStatsHeapCommitted :: Bytes
837+ , nodeJVMStatsHeapUsedPercent :: Int
838+ , nodeJVMStatsHeapUsed :: Bytes
839+ , nodeJVMStatsUptime :: NominalDiffTime
840+ , nodeJVMStatsTimestamp :: UTCTime
841+ } deriving (Eq, Show)
842+
843+data JVMBufferPoolStats = JVMBufferPoolStats {
844+ jvmBufferPoolStatsTotalCapacity :: Bytes
845+ , jvmBufferPoolStatsUsed :: Bytes
846+ , jvmBufferPoolStatsCount :: Int
847+ } deriving (Eq, Show)
848+
849+data JVMGCStats = JVMGCStats {
850+ jvmGCStatsCollectionTime :: NominalDiffTime
851+ , jvmGCStatsCollectionCount :: Int
852+ } deriving (Eq, Show)
853+
854+data JVMPoolStats = JVMPoolStats {
855+ jvmPoolStatsPeakMax :: Bytes
856+ , jvmPoolStatsPeakUsed :: Bytes
857+ , jvmPoolStatsMax :: Bytes
858+ , jvmPoolStatsUsed :: Bytes
859+ } deriving (Eq, Show)
860+
861+data NodeProcessStats = NodeProcessStats {
862+ nodeProcessTimestamp :: UTCTime
863+ , nodeProcessOpenFDs :: Int
864+ , nodeProcessMaxFDs :: Int
865+ , nodeProcessCPUPercent :: Int
866+ , nodeProcessCPUTotal :: NominalDiffTime
867+ , nodeProcessMemTotalVirtual :: Bytes
868+ } deriving (Eq, Show)
869+
870+data NodeOSStats = NodeOSStats {
871+ nodeOSTimestamp :: UTCTime
872+ , nodeOSCPUPercent :: Int
873+ , nodeOSLoad :: Maybe LoadAvgs
874+ , nodeOSMemTotal :: Bytes
875+ , nodeOSMemFree :: Bytes
876+ , nodeOSMemFreePercent :: Int
877+ , nodeOSMemUsed :: Bytes
878+ , nodeOSMemUsedPercent :: Int
879+ , nodeOSSwapTotal :: Bytes
880+ , nodeOSSwapFree :: Bytes
881+ , nodeOSSwapUsed :: Bytes
882+ } deriving (Eq, Show)
883+
884+data LoadAvgs = LoadAvgs {
885+ loadAvg1Min :: Double
886+ , loadAvg5Min :: Double
887+ , loadAvg15Min :: Double
888+ } deriving (Eq, Show)
889+
890+data NodeIndicesStats = NodeIndicesStats {
891+ nodeIndicesStatsRecoveryThrottleTime :: Maybe NominalDiffTime
892+ , nodeIndicesStatsRecoveryCurrentAsTarget :: Maybe Int
893+ , nodeIndicesStatsRecoveryCurrentAsSource :: Maybe Int
894+ , nodeIndicesStatsQueryCacheMisses :: Maybe Int
895+ , nodeIndicesStatsQueryCacheHits :: Maybe Int
896+ , nodeIndicesStatsQueryCacheEvictions :: Maybe Int
897+ , nodeIndicesStatsQueryCacheSize :: Maybe Bytes
898+ , nodeIndicesStatsSuggestCurrent :: Maybe Int
899+ , nodeIndicesStatsSuggestTime :: Maybe NominalDiffTime
900+ , nodeIndicesStatsSuggestTotal :: Maybe Int
901+ , nodeIndicesStatsTranslogSize :: Bytes
902+ , nodeIndicesStatsTranslogOps :: Int
903+ , nodeIndicesStatsSegFixedBitSetMemory :: Maybe Bytes
904+ , nodeIndicesStatsSegVersionMapMemory :: Bytes
905+ , nodeIndicesStatsSegIndexWriterMaxMemory :: Maybe Bytes
906+ , nodeIndicesStatsSegIndexWriterMemory :: Bytes
907+ , nodeIndicesStatsSegMemory :: Bytes
908+ , nodeIndicesStatsSegCount :: Int
909+ , nodeIndicesStatsCompletionSize :: Bytes
910+ , nodeIndicesStatsPercolateQueries :: Maybe Int
911+ , nodeIndicesStatsPercolateMemory :: Maybe Bytes
912+ , nodeIndicesStatsPercolateCurrent :: Maybe Int
913+ , nodeIndicesStatsPercolateTime :: Maybe NominalDiffTime
914+ , nodeIndicesStatsPercolateTotal :: Maybe Int
915+ , nodeIndicesStatsFieldDataEvictions :: Int
916+ , nodeIndicesStatsFieldDataMemory :: Bytes
917+ , nodeIndicesStatsWarmerTotalTime :: NominalDiffTime
918+ , nodeIndicesStatsWarmerTotal :: Int
919+ , nodeIndicesStatsWarmerCurrent :: Int
920+ , nodeIndicesStatsFlushTotalTime :: NominalDiffTime
921+ , nodeIndicesStatsFlushTotal :: Int
922+ , nodeIndicesStatsRefreshTotalTime :: NominalDiffTime
923+ , nodeIndicesStatsRefreshTotal :: Int
924+ , nodeIndicesStatsMergesTotalSize :: Bytes
925+ , nodeIndicesStatsMergesTotalDocs :: Int
926+ , nodeIndicesStatsMergesTotalTime :: NominalDiffTime
927+ , nodeIndicesStatsMergesTotal :: Int
928+ , nodeIndicesStatsMergesCurrentSize :: Bytes
929+ , nodeIndicesStatsMergesCurrentDocs :: Int
930+ , nodeIndicesStatsMergesCurrent :: Int
931+ , nodeIndicesStatsSearchFetchCurrent :: Int
932+ , nodeIndicesStatsSearchFetchTime :: NominalDiffTime
933+ , nodeIndicesStatsSearchFetchTotal :: Int
934+ , nodeIndicesStatsSearchQueryCurrent :: Int
935+ , nodeIndicesStatsSearchQueryTime :: NominalDiffTime
936+ , nodeIndicesStatsSearchQueryTotal :: Int
937+ , nodeIndicesStatsSearchOpenContexts :: Int
938+ , nodeIndicesStatsGetCurrent :: Int
939+ , nodeIndicesStatsGetMissingTime :: NominalDiffTime
940+ , nodeIndicesStatsGetMissingTotal :: Int
941+ , nodeIndicesStatsGetExistsTime :: NominalDiffTime
942+ , nodeIndicesStatsGetExistsTotal :: Int
943+ , nodeIndicesStatsGetTime :: NominalDiffTime
944+ , nodeIndicesStatsGetTotal :: Int
945+ , nodeIndicesStatsIndexingThrottleTime :: Maybe NominalDiffTime
946+ , nodeIndicesStatsIndexingIsThrottled :: Maybe Bool
947+ , nodeIndicesStatsIndexingNoopUpdateTotal :: Maybe Int
948+ , nodeIndicesStatsIndexingDeleteCurrent :: Int
949+ , nodeIndicesStatsIndexingDeleteTime :: NominalDiffTime
950+ , nodeIndicesStatsIndexingDeleteTotal :: Int
951+ , nodeIndicesStatsIndexingIndexCurrent :: Int
952+ , nodeIndicesStatsIndexingIndexTime :: NominalDiffTime
953+ , nodeIndicesStatsIndexingTotal :: Int
954+ , nodeIndicesStatsStoreThrottleTime :: NominalDiffTime
955+ , nodeIndicesStatsStoreSize :: Bytes
956+ , nodeIndicesStatsDocsDeleted :: Int
957+ , nodeIndicesStatsDocsCount :: Int
958+ } deriving (Eq, Show)
959+
960+-- | A quirky address format used throughout ElasticSearch. An example
961+-- would be inet[/1.1.1.1:9200]. inet may be a placeholder for a
962+-- <https://en.wikipedia.org/wiki/Fully_qualified_domain_name FQDN>.
963+newtype EsAddress = EsAddress { esAddress :: Text }
964+ deriving (Eq, Ord, Show, FromJSON)
965+
966+-- | Typically a 7 character hex string.
967+newtype BuildHash = BuildHash { buildHash :: Text }
968+ deriving (Eq, Ord, Show, FromJSON, ToJSON)
969+
970+newtype PluginName = PluginName { pluginName :: Text }
971+ deriving (Eq, Ord, Show, FromJSON)
972+
973+data NodeInfo = NodeInfo {
974+ nodeInfoHTTPAddress :: Maybe EsAddress
975+ , nodeInfoBuild :: BuildHash
976+ , nodeInfoESVersion :: VersionNumber
977+ , nodeInfoIP :: Server
978+ , nodeInfoHost :: Server
979+ , nodeInfoTransportAddress :: EsAddress
980+ , nodeInfoName :: NodeName
981+ , nodeInfoFullId :: FullNodeId
982+ , nodeInfoPlugins :: [NodePluginInfo]
983+ , nodeInfoHTTP :: NodeHTTPInfo
984+ , nodeInfoTransport :: NodeTransportInfo
985+ , nodeInfoNetwork :: Maybe NodeNetworkInfo
986+ , nodeInfoThreadPool :: NodeThreadPoolsInfo
987+ , nodeInfoJVM :: NodeJVMInfo
988+ , nodeInfoProcess :: NodeProcessInfo
989+ , nodeInfoOS :: NodeOSInfo
990+ , nodeInfoSettings :: Object
991+ -- ^ The members of the settings objects are not consistent,
992+ -- dependent on plugins, etc.
993+ } deriving (Eq, Show)
994+
995+data NodePluginInfo = NodePluginInfo {
996+ nodePluginSite :: Maybe Bool
997+ -- ^ Is this a site plugin?
998+ , nodePluginJVM :: Maybe Bool
999+ -- ^ Is this plugin running on the JVM
1000+ , nodePluginDescription :: Text
1001+ , nodePluginVersion :: MaybeNA VersionNumber
1002+ , nodePluginName :: PluginName
1003+ } deriving (Eq, Show)
1004+
1005+data NodeHTTPInfo = NodeHTTPInfo {
1006+ nodeHTTPMaxContentLength :: Bytes
1007+ , nodeHTTPTransportAddress :: BoundTransportAddress
1008+ } deriving (Eq, Show)
1009+
1010+data NodeTransportInfo = NodeTransportInfo {
1011+ nodeTransportProfiles :: [BoundTransportAddress]
1012+ , nodeTransportAddress :: BoundTransportAddress
1013+ } deriving (Eq, Show)
1014+
1015+data BoundTransportAddress = BoundTransportAddress {
1016+ publishAddress :: EsAddress
1017+ , boundAddress :: [EsAddress]
1018+ } deriving (Eq, Show)
1019+
1020+data NodeNetworkInfo = NodeNetworkInfo {
1021+ nodeNetworkPrimaryInterface :: NodeNetworkInterface
1022+ , nodeNetworkRefreshInterval :: NominalDiffTime
1023+ } deriving (Eq, Show)
1024+
1025+newtype MacAddress = MacAddress { macAddress :: Text }
1026+ deriving (Eq, Ord, Show, FromJSON)
1027+
1028+newtype NetworkInterfaceName = NetworkInterfaceName { networkInterfaceName :: Text }
1029+ deriving (Eq, Ord, Show, FromJSON)
1030+
1031+data NodeNetworkInterface = NodeNetworkInterface {
1032+ nodeNetIfaceMacAddress :: MacAddress
1033+ , nodeNetIfaceName :: NetworkInterfaceName
1034+ , nodeNetIfaceAddress :: Server
1035+ } deriving (Eq, Show)
1036+
1037+data NodeThreadPoolsInfo = NodeThreadPoolsInfo {
1038+ nodeThreadPoolsRefresh :: NodeThreadPoolInfo
1039+ , nodeThreadPoolsManagement :: NodeThreadPoolInfo
1040+ , nodeThreadPoolsPercolate :: Maybe NodeThreadPoolInfo
1041+ , nodeThreadPoolsListener :: Maybe NodeThreadPoolInfo
1042+ , nodeThreadPoolsFetchShardStarted :: Maybe NodeThreadPoolInfo
1043+ , nodeThreadPoolsSearch :: NodeThreadPoolInfo
1044+ , nodeThreadPoolsFlush :: NodeThreadPoolInfo
1045+ , nodeThreadPoolsWarmer :: NodeThreadPoolInfo
1046+ , nodeThreadPoolsOptimize :: Maybe NodeThreadPoolInfo
1047+ , nodeThreadPoolsBulk :: NodeThreadPoolInfo
1048+ , nodeThreadPoolsSuggest :: Maybe NodeThreadPoolInfo
1049+ , nodeThreadPoolsMerge :: NodeThreadPoolInfo
1050+ , nodeThreadPoolsSnapshot :: NodeThreadPoolInfo
1051+ , nodeThreadPoolsGet :: NodeThreadPoolInfo
1052+ , nodeThreadPoolsFetchShardStore :: Maybe NodeThreadPoolInfo
1053+ , nodeThreadPoolsIndex :: NodeThreadPoolInfo
1054+ , nodeThreadPoolsGeneric :: NodeThreadPoolInfo
1055+ } deriving (Eq, Show)
1056+
1057+data NodeThreadPoolInfo = NodeThreadPoolInfo {
1058+ nodeThreadPoolQueueSize :: ThreadPoolSize
1059+ , nodeThreadPoolKeepalive :: Maybe NominalDiffTime
1060+ , nodeThreadPoolMin :: Maybe Int
1061+ , nodeThreadPoolMax :: Maybe Int
1062+ , nodeThreadPoolType :: ThreadPoolType
1063+ } deriving (Eq, Show)
1064+
1065+data ThreadPoolSize = ThreadPoolBounded Int
1066+ | ThreadPoolUnbounded
1067+ deriving (Eq, Show)
1068+
1069+data ThreadPoolType = ThreadPoolScaling
1070+ | ThreadPoolFixed
1071+ | ThreadPoolCached
1072+ deriving (Eq, Show)
1073+
1074+data NodeJVMInfo = NodeJVMInfo {
1075+ nodeJVMInfoMemoryPools :: [JVMMemoryPool]
1076+ , nodeJVMInfoMemoryPoolsGCCollectors :: [JVMGCCollector]
1077+ , nodeJVMInfoMemoryInfo :: JVMMemoryInfo
1078+ , nodeJVMInfoStartTime :: UTCTime
1079+ , nodeJVMInfoVMVendor :: Text
1080+ , nodeJVMVMVersion :: VersionNumber
1081+ -- ^ JVM doesn't seme to follow normal version conventions
1082+ , nodeJVMVMName :: Text
1083+ , nodeJVMVersion :: VersionNumber
1084+ , nodeJVMPID :: PID
1085+ } deriving (Eq, Show)
1086+
1087+-- | Handles quirks in the way JVM versions are rendered (1.7.0_101 -> 1.7.0.101)
1088+newtype JVMVersion = JVMVersion { unJVMVersion :: VersionNumber }
1089+
1090+data JVMMemoryInfo = JVMMemoryInfo {
1091+ jvmMemoryInfoDirectMax :: Bytes
1092+ , jvmMemoryInfoNonHeapMax :: Bytes
1093+ , jvmMemoryInfoNonHeapInit :: Bytes
1094+ , jvmMemoryInfoHeapMax :: Bytes
1095+ , jvmMemoryInfoHeapInit :: Bytes
1096+ } deriving (Eq, Show)
1097+
1098+newtype JVMMemoryPool = JVMMemoryPool {
1099+ jvmMemoryPool :: Text
1100+ } deriving (Eq, Show, FromJSON)
1101+
1102+newtype JVMGCCollector = JVMGCCollector {
1103+ jvmGCCollector :: Text
1104+ } deriving (Eq, Show, FromJSON)
1105+
1106+newtype PID = PID {
1107+ pid :: Int
1108+ } deriving (Eq, Show, FromJSON)
1109+
1110+data NodeOSInfo = NodeOSInfo {
1111+ nodeOSRefreshInterval :: NominalDiffTime
1112+ , nodeOSName :: Text
1113+ , nodeOSArch :: Text
1114+ , nodeOSVersion :: VersionNumber
1115+ , nodeOSAvailableProcessors :: Int
1116+ , nodeOSAllocatedProcessors :: Int
1117+ } deriving (Eq, Show)
1118+
1119+data CPUInfo = CPUInfo {
1120+ cpuCacheSize :: Bytes
1121+ , cpuCoresPerSocket :: Int
1122+ , cpuTotalSockets :: Int
1123+ , cpuTotalCores :: Int
1124+ , cpuMHZ :: Int
1125+ , cpuModel :: Text
1126+ , cpuVendor :: Text
1127+ } deriving (Eq, Show)
1128+
1129+data NodeProcessInfo = NodeProcessInfo {
1130+ nodeProcessMLockAll :: Bool
1131+ -- ^ See <https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration.html>
1132+ , nodeProcessMaxFileDescriptors :: Maybe Int
1133+ , nodeProcessId :: PID
1134+ , nodeProcessRefreshInterval :: NominalDiffTime
1135+ } deriving (Eq, Show)
1136+
1137+data ShardResult =
1138+ ShardResult { shardTotal :: Int
1139+ , shardsSuccessful :: Int
1140+ , shardsFailed :: Int } deriving (Eq, Show)
1141+
1142+instance FromJSON ShardResult where
1143+ parseJSON (Object v) = ShardResult <$>
1144+ v .: "total" <*>
1145+ v .: "successful" <*>
1146+ v .: "failed"
1147+ parseJSON _ = empty
1148+
1149+data SnapshotState = SnapshotInit
1150+ | SnapshotStarted
1151+ | SnapshotSuccess
1152+ | SnapshotFailed
1153+ | SnapshotAborted
1154+ | SnapshotMissing
1155+ | SnapshotWaiting
1156+ deriving (Eq, Show)
1157+
1158+instance FromJSON SnapshotState where
1159+ parseJSON = withText "SnapshotState" parse
1160+ where
1161+ parse "INIT" = return SnapshotInit
1162+ parse "STARTED" = return SnapshotStarted
1163+ parse "SUCCESS" = return SnapshotSuccess
1164+ parse "FAILED" = return SnapshotFailed
1165+ parse "ABORTED" = return SnapshotAborted
1166+ parse "MISSING" = return SnapshotMissing
1167+ parse "WAITING" = return SnapshotWaiting
1168+ parse t = fail ("Invalid snapshot state " <> T.unpack t)
1169+
1170+
1171+data SnapshotRestoreSettings = SnapshotRestoreSettings {
1172+ snapRestoreWaitForCompletion :: Bool
1173+ -- ^ Should the API call return immediately after initializing
1174+ -- the restore or wait until completed? Note that if this is
1175+ -- enabled, it could wait a long time, so you should adjust your
1176+ -- 'ManagerSettings' accordingly to set long timeouts or
1177+ -- explicitly handle timeouts.
1178+ , snapRestoreIndices :: Maybe IndexSelection
1179+ -- ^ Nothing will restore all indices in the snapshot. Just [] is
1180+ -- permissable and will essentially be a no-op restore.
1181+ , snapRestoreIgnoreUnavailable :: Bool
1182+ -- ^ If set to True, any indices that do not exist will be ignored
1183+ -- during snapshot rather than failing the restore.
1184+ , snapRestoreIncludeGlobalState :: Bool
1185+ -- ^ If set to false, will ignore any global state in the snapshot
1186+ -- and will not restore it.
1187+ , snapRestoreRenamePattern :: Maybe RestoreRenamePattern
1188+ -- ^ A regex pattern for matching indices. Used with
1189+ -- 'snapRestoreRenameReplacement', the restore can reference the
1190+ -- matched index and create a new index name upon restore.
1191+ , snapRestoreRenameReplacement :: Maybe (NonEmpty RestoreRenameToken)
1192+ -- ^ Expression of how index renames should be constructed.
1193+ , snapRestorePartial :: Bool
1194+ -- ^ If some indices fail to restore, should the process proceed?
1195+ , snapRestoreIncludeAliases :: Bool
1196+ -- ^ Should the restore also restore the aliases captured in the
1197+ -- snapshot.
1198+ , snapRestoreIndexSettingsOverrides :: Maybe RestoreIndexSettings
1199+ -- ^ Settings to apply during the restore process. __NOTE:__ This
1200+ -- option is not supported in ES < 1.5 and should be set to
1201+ -- Nothing in that case.
1202+ , snapRestoreIgnoreIndexSettings :: Maybe (NonEmpty Text)
1203+ -- ^ This type could be more rich but it isn't clear which
1204+ -- settings are allowed to be ignored during restore, so we're
1205+ -- going with including this feature in a basic form rather than
1206+ -- omitting it. One example here would be
1207+ -- "index.refresh_interval". Any setting specified here will
1208+ -- revert back to the server default during the restore process.
1209+ } deriving (Eq, Show)
1210+
1211+data SnapshotRepoUpdateSettings = SnapshotRepoUpdateSettings {
1212+ repoUpdateVerify :: Bool
1213+ -- ^ After creation/update, synchronously check that nodes can
1214+ -- write to this repo. Defaults to True. You may use False if you
1215+ -- need a faster response and plan on verifying manually later
1216+ -- with 'verifySnapshotRepo'.
1217+ } deriving (Eq, Show)
1218+
1219+
1220+-- | Reasonable defaults for repo creation/update
1221+--
1222+-- * repoUpdateVerify True
1223+defaultSnapshotRepoUpdateSettings :: SnapshotRepoUpdateSettings
1224+defaultSnapshotRepoUpdateSettings = SnapshotRepoUpdateSettings True
1225+
1226+
1227+-- | A filesystem-based snapshot repo that ships with
1228+-- ElasticSearch. This is an instance of 'SnapshotRepo' so it can be
1229+-- used with 'updateSnapshotRepo'
1230+data FsSnapshotRepo = FsSnapshotRepo {
1231+ fsrName :: SnapshotRepoName
1232+ , fsrLocation :: FilePath
1233+ , fsrCompressMetadata :: Bool
1234+ , fsrChunkSize :: Maybe Bytes
1235+ -- ^ Size by which to split large files during snapshotting.
1236+ , fsrMaxRestoreBytesPerSec :: Maybe Bytes
1237+ -- ^ Throttle node restore rate. If not supplied, defaults to 40mb/sec
1238+ , fsrMaxSnapshotBytesPerSec :: Maybe Bytes
1239+ -- ^ Throttle node snapshot rate. If not supplied, defaults to 40mb/sec
1240+ } deriving (Eq, Show)
1241+
1242+
1243+instance SnapshotRepo FsSnapshotRepo where
1244+ toGSnapshotRepo FsSnapshotRepo {..} =
1245+ GenericSnapshotRepo fsrName fsRepoType (GenericSnapshotRepoSettings settings)
1246+ where
1247+ Object settings = object $ [ "location" .= fsrLocation
1248+ , "compress" .= fsrCompressMetadata
1249+ ] ++ optionalPairs
1250+ optionalPairs = catMaybes [ ("chunk_size" .=) <$> fsrChunkSize
1251+ , ("max_restore_bytes_per_sec" .=) <$> fsrMaxRestoreBytesPerSec
1252+ , ("max_snapshot_bytes_per_sec" .=) <$> fsrMaxSnapshotBytesPerSec
1253+ ]
1254+ fromGSnapshotRepo GenericSnapshotRepo {..}
1255+ | gSnapshotRepoType == fsRepoType = do
1256+ let o = gSnapshotRepoSettingsObject gSnapshotRepoSettings
1257+ parseRepo $ do
1258+ FsSnapshotRepo gSnapshotRepoName <$> o .: "location"
1259+ <*> o .:? "compress" .!= False
1260+ <*> o .:? "chunk_size"
1261+ <*> o .:? "max_restore_bytes_per_sec"
1262+ <*> o .:? "max_snapshot_bytes_per_sec"
1263+ | otherwise = Left (RepoTypeMismatch fsRepoType gSnapshotRepoType)
1264+
1265+
1266+parseRepo :: Parser a -> Either SnapshotRepoConversionError a
1267+parseRepo parser = case parseEither (const parser) () of
1268+ Left e -> Left (OtherRepoConversionError (T.pack e))
1269+ Right a -> Right a
1270+
1271+
1272+fsRepoType :: SnapshotRepoType
1273+fsRepoType = SnapshotRepoType "fs"
1274+
1275+-- | Law: fromGSnapshotRepo (toGSnapshotRepo r) == Right r
1276+class SnapshotRepo r where
1277+ toGSnapshotRepo :: r -> GenericSnapshotRepo
1278+ fromGSnapshotRepo :: GenericSnapshotRepo -> Either SnapshotRepoConversionError r
1279+
1280+
1281+data SnapshotRepoConversionError = RepoTypeMismatch SnapshotRepoType SnapshotRepoType
1282+ -- ^ Expected type and actual type
1283+ | OtherRepoConversionError Text
1284+ deriving (Show, Eq)
1285+
1286+
1287+instance Exception SnapshotRepoConversionError
1288+
1289+
1290+data SnapshotCreateSettings = SnapshotCreateSettings {
1291+ snapWaitForCompletion :: Bool
1292+ -- ^ Should the API call return immediately after initializing
1293+ -- the snapshot or wait until completed? Note that if this is
1294+ -- enabled it could wait a long time, so you should adjust your
1295+ -- 'ManagerSettings' accordingly to set long timeouts or
1296+ -- explicitly handle timeouts.
1297+ , snapIndices :: Maybe IndexSelection
1298+ -- ^ Nothing will snapshot all indices. Just [] is permissable and
1299+ -- will essentially be a no-op snapshot.
1300+ , snapIgnoreUnavailable :: Bool
1301+ -- ^ If set to True, any matched indices that don't exist will be
1302+ -- ignored. Otherwise it will be an error and fail.
1303+ , snapIncludeGlobalState :: Bool
1304+ , snapPartial :: Bool
1305+ -- ^ If some indices failed to snapshot (e.g. if not all primary
1306+ -- shards are available), should the process proceed?
1307+ } deriving (Eq, Show)
1308+
1309+
1310+-- | Reasonable defaults for snapshot creation
1311+--
1312+-- * snapWaitForCompletion False
1313+-- * snapIndices Nothing
1314+-- * snapIgnoreUnavailable False
1315+-- * snapIncludeGlobalState True
1316+-- * snapPartial False
1317+defaultSnapshotCreateSettings :: SnapshotCreateSettings
1318+defaultSnapshotCreateSettings = SnapshotCreateSettings {
1319+ snapWaitForCompletion = False
1320+ , snapIndices = Nothing
1321+ , snapIgnoreUnavailable = False
1322+ , snapIncludeGlobalState = True
1323+ , snapPartial = False
1324+ }
1325+
1326+
1327+data SnapshotSelection =
1328+ SnapshotList (NonEmpty SnapshotPattern)
1329+ | AllSnapshots
1330+ deriving (Eq, Show)
1331+
1332+
1333+-- | Either specifies an exact snapshot name or one with globs in it,
1334+-- e.g. @SnapPattern "foo*"@ __NOTE__: Patterns are not supported on
1335+-- ES < 1.7
1336+data SnapshotPattern =
1337+ ExactSnap SnapshotName
1338+ | SnapPattern Text
1339+ deriving (Eq, Show)
1340+
1341+
1342+-- | General information about the state of a snapshot. Has some
1343+-- redundancies with 'SnapshotStatus'
1344+data SnapshotInfo = SnapshotInfo {
1345+ snapInfoShards :: ShardResult
1346+ , snapInfoFailures :: [SnapshotShardFailure]
1347+ , snapInfoDuration :: NominalDiffTime
1348+ , snapInfoEndTime :: UTCTime
1349+ , snapInfoStartTime :: UTCTime
1350+ , snapInfoState :: SnapshotState
1351+ , snapInfoIndices :: [IndexName]
1352+ , snapInfoName :: SnapshotName
1353+ } deriving (Eq, Show)
1354+
1355+
1356+instance FromJSON POSIXMS where
1357+ parseJSON = withScientific "POSIXMS" (return . parse)
1358+ where parse n =
1359+ let n' = truncate n :: Integer
1360+ in POSIXMS (posixSecondsToUTCTime (fromInteger (n' `div` 1000)))
1361+
1362+instance FromJSON SnapshotInfo where
1363+ parseJSON = withObject "SnapshotInfo" parse
1364+ where
1365+ parse o = SnapshotInfo <$> o .: "shards"
1366+ <*> o .: "failures"
1367+ <*> (unMS <$> o .: "duration_in_millis")
1368+ <*> (posixMS <$> o .: "end_time_in_millis")
1369+ <*> (posixMS <$> o .: "start_time_in_millis")
1370+ <*> o .: "state"
1371+ <*> o .: "indices"
1372+ <*> o .: "snapshot"
1373+
1374+data SnapshotShardFailure = SnapshotShardFailure {
1375+ snapShardFailureIndex :: IndexName
1376+ , snapShardFailureNodeId :: Maybe NodeName -- I'm not 100% sure this isn't actually 'FullNodeId'
1377+ , snapShardFailureReason :: Text
1378+ , snapShardFailureShardId :: ShardId
1379+ } deriving (Eq, Show)
1380+
1381+
1382+instance FromJSON SnapshotShardFailure where
1383+ parseJSON = withObject "SnapshotShardFailure" parse
1384+ where
1385+ parse o = SnapshotShardFailure <$> o .: "index"
1386+ <*> o .:? "node_id"
1387+ <*> o .: "reason"
1388+ <*> o .: "shard_id"
1389+
1390+-- | Regex-stype pattern, e.g. "index_(.+)" to match index names
1391+newtype RestoreRenamePattern =
1392+ RestoreRenamePattern { rrPattern :: Text }
1393+ deriving (Eq, Show, Ord, ToJSON)
1394+
1395+
1396+-- | A single token in a index renaming scheme for a restore. These
1397+-- are concatenated into a string before being sent to
1398+-- ElasticSearch. Check out these Java
1399+-- <https://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html docs> to find out more if you're into that sort of thing.
1400+data RestoreRenameToken = RRTLit Text
1401+ -- ^ Just a literal string of characters
1402+ | RRSubWholeMatch
1403+ -- ^ Equivalent to $0. The entire matched pattern, not any subgroup
1404+ | RRSubGroup RRGroupRefNum
1405+ -- ^ A specific reference to a group number
1406+ deriving (Eq, Show)
1407+
1408+
1409+-- | A group number for regex matching. Only values from 1-9 are
1410+-- supported. Construct with 'mkRRGroupRefNum'
1411+newtype RRGroupRefNum =
1412+ RRGroupRefNum { rrGroupRefNum :: Int }
1413+ deriving (Eq, Ord, Show)
1414+
1415+instance Bounded RRGroupRefNum where
1416+ minBound = RRGroupRefNum 1
1417+ maxBound = RRGroupRefNum 9
1418+
1419+
1420+-- | Only allows valid group number references (1-9).
1421+mkRRGroupRefNum :: Int -> Maybe RRGroupRefNum
1422+mkRRGroupRefNum i
1423+ | i >= (rrGroupRefNum minBound) && i <= (rrGroupRefNum maxBound) =
1424+ Just $ RRGroupRefNum i
1425+ | otherwise = Nothing
1426+
1427+-- | Reasonable defaults for snapshot restores
1428+--
1429+-- * snapRestoreWaitForCompletion False
1430+-- * snapRestoreIndices Nothing
1431+-- * snapRestoreIgnoreUnavailable False
1432+-- * snapRestoreIncludeGlobalState True
1433+-- * snapRestoreRenamePattern Nothing
1434+-- * snapRestoreRenameReplacement Nothing
1435+-- * snapRestorePartial False
1436+-- * snapRestoreIncludeAliases True
1437+-- * snapRestoreIndexSettingsOverrides Nothing
1438+-- * snapRestoreIgnoreIndexSettings Nothing
1439+defaultSnapshotRestoreSettings :: SnapshotRestoreSettings
1440+defaultSnapshotRestoreSettings = SnapshotRestoreSettings {
1441+ snapRestoreWaitForCompletion = False
1442+ , snapRestoreIndices = Nothing
1443+ , snapRestoreIgnoreUnavailable = False
1444+ , snapRestoreIncludeGlobalState = True
1445+ , snapRestoreRenamePattern = Nothing
1446+ , snapRestoreRenameReplacement = Nothing
1447+ , snapRestorePartial = False
1448+ , snapRestoreIncludeAliases = True
1449+ , snapRestoreIndexSettingsOverrides = Nothing
1450+ , snapRestoreIgnoreIndexSettings = Nothing
1451+ }
1452+
1453+
1454+-- | Index settings that can be overridden. The docs only mention you
1455+-- can update number of replicas, but there may be more. You
1456+-- definitely cannot override shard count.
1457+data RestoreIndexSettings = RestoreIndexSettings {
1458+ restoreOverrideReplicas :: Maybe ReplicaCount
1459+ } deriving (Eq, Show)
1460+
1461+
1462+instance ToJSON RestoreIndexSettings where
1463+ toJSON RestoreIndexSettings {..} = object prs
1464+ where
1465+ prs = catMaybes [("index.number_of_replicas" .=) <$> restoreOverrideReplicas]
1466+
1467+
1468+instance FromJSON NodesInfo where
1469+ parseJSON = withObject "NodesInfo" parse
1470+ where
1471+ parse o = do
1472+ nodes <- o .: "nodes"
1473+ infos <- forM (HM.toList nodes) $ \(fullNID, v) -> do
1474+ node <- parseJSON v
1475+ parseNodeInfo (FullNodeId fullNID) node
1476+ cn <- o .: "cluster_name"
1477+ return (NodesInfo infos cn)
1478+
1479+instance FromJSON NodesStats where
1480+ parseJSON = withObject "NodesStats" parse
1481+ where
1482+ parse o = do
1483+ nodes <- o .: "nodes"
1484+ stats <- forM (HM.toList nodes) $ \(fullNID, v) -> do
1485+ node <- parseJSON v
1486+ parseNodeStats (FullNodeId fullNID) node
1487+ cn <- o .: "cluster_name"
1488+ return (NodesStats stats cn)
1489+
1490+instance FromJSON NodeBreakerStats where
1491+ parseJSON = withObject "NodeBreakerStats" parse
1492+ where
1493+ parse o = NodeBreakerStats <$> o .: "tripped"
1494+ <*> o .: "overhead"
1495+ <*> o .: "estimated_size_in_bytes"
1496+ <*> o .: "limit_size_in_bytes"
1497+
1498+instance FromJSON NodeHTTPStats where
1499+ parseJSON = withObject "NodeHTTPStats" parse
1500+ where
1501+ parse o = NodeHTTPStats <$> o .: "total_opened"
1502+ <*> o .: "current_open"
1503+
1504+instance FromJSON NodeTransportStats where
1505+ parseJSON = withObject "NodeTransportStats" parse
1506+ where
1507+ parse o = NodeTransportStats <$> o .: "tx_size_in_bytes"
1508+ <*> o .: "tx_count"
1509+ <*> o .: "rx_size_in_bytes"
1510+ <*> o .: "rx_count"
1511+ <*> o .: "server_open"
1512+
1513+instance FromJSON NodeFSStats where
1514+ parseJSON = withObject "NodeFSStats" parse
1515+ where
1516+ parse o = NodeFSStats <$> o .: "data"
1517+ <*> o .: "total"
1518+ <*> (posixMS <$> o .: "timestamp")
1519+
1520+instance FromJSON NodeDataPathStats where
1521+ parseJSON = withObject "NodeDataPathStats" parse
1522+ where
1523+ parse o =
1524+ NodeDataPathStats <$> (fmap unStringlyTypedDouble <$> o .:? "disk_service_time")
1525+ <*> (fmap unStringlyTypedDouble <$> o .:? "disk_queue")
1526+ <*> o .:? "disk_io_size_in_bytes"
1527+ <*> o .:? "disk_write_size_in_bytes"
1528+ <*> o .:? "disk_read_size_in_bytes"
1529+ <*> o .:? "disk_io_op"
1530+ <*> o .:? "disk_writes"
1531+ <*> o .:? "disk_reads"
1532+ <*> o .: "available_in_bytes"
1533+ <*> o .: "free_in_bytes"
1534+ <*> o .: "total_in_bytes"
1535+ <*> o .:? "type"
1536+ <*> o .:? "dev"
1537+ <*> o .: "mount"
1538+ <*> o .: "path"
1539+
1540+instance FromJSON NodeFSTotalStats where
1541+ parseJSON = withObject "NodeFSTotalStats" parse
1542+ where
1543+ parse o = NodeFSTotalStats <$> (fmap unStringlyTypedDouble <$> o .:? "disk_service_time")
1544+ <*> (fmap unStringlyTypedDouble <$> o .:? "disk_queue")
1545+ <*> o .:? "disk_io_size_in_bytes"
1546+ <*> o .:? "disk_write_size_in_bytes"
1547+ <*> o .:? "disk_read_size_in_bytes"
1548+ <*> o .:? "disk_io_op"
1549+ <*> o .:? "disk_writes"
1550+ <*> o .:? "disk_reads"
1551+ <*> o .: "available_in_bytes"
1552+ <*> o .: "free_in_bytes"
1553+ <*> o .: "total_in_bytes"
1554+
1555+instance FromJSON NodeNetworkStats where
1556+ parseJSON = withObject "NodeNetworkStats" parse
1557+ where
1558+ parse o = do
1559+ tcp <- o .: "tcp"
1560+ NodeNetworkStats <$> tcp .: "out_rsts"
1561+ <*> tcp .: "in_errs"
1562+ <*> tcp .: "attempt_fails"
1563+ <*> tcp .: "estab_resets"
1564+ <*> tcp .: "retrans_segs"
1565+ <*> tcp .: "out_segs"
1566+ <*> tcp .: "in_segs"
1567+ <*> tcp .: "curr_estab"
1568+ <*> tcp .: "passive_opens"
1569+ <*> tcp .: "active_opens"
1570+
1571+instance FromJSON NodeThreadPoolsStats where
1572+ parseJSON = withObject "NodeThreadPoolsStats" parse
1573+ where
1574+ parse o = NodeThreadPoolsStats <$> o .: "snapshot"
1575+ <*> o .: "bulk"
1576+ <*> o .: "force_merge"
1577+ <*> o .: "get"
1578+ <*> o .: "management"
1579+ <*> o .:? "fetch_shard_store"
1580+ <*> o .:? "optimize"
1581+ <*> o .: "flush"
1582+ <*> o .: "search"
1583+ <*> o .: "warmer"
1584+ <*> o .: "generic"
1585+ <*> o .:? "suggest"
1586+ <*> o .: "refresh"
1587+ <*> o .: "index"
1588+ <*> o .:? "listener"
1589+ <*> o .:? "fetch_shard_started"
1590+ <*> o .:? "percolate"
1591+instance FromJSON NodeThreadPoolStats where
1592+ parseJSON = withObject "NodeThreadPoolStats" parse
1593+ where
1594+ parse o = NodeThreadPoolStats <$> o .: "completed"
1595+ <*> o .: "largest"
1596+ <*> o .: "rejected"
1597+ <*> o .: "active"
1598+ <*> o .: "queue"
1599+ <*> o .: "threads"
1600+
1601+instance FromJSON NodeJVMStats where
1602+ parseJSON = withObject "NodeJVMStats" parse
1603+ where
1604+ parse o = do
1605+ bufferPools <- o .: "buffer_pools"
1606+ mapped <- bufferPools .: "mapped"
1607+ direct <- bufferPools .: "direct"
1608+ gc <- o .: "gc"
1609+ collectors <- gc .: "collectors"
1610+ oldC <- collectors .: "old"
1611+ youngC <- collectors .: "young"
1612+ threads <- o .: "threads"
1613+ mem <- o .: "mem"
1614+ pools <- mem .: "pools"
1615+ oldM <- pools .: "old"
1616+ survivorM <- pools .: "survivor"
1617+ youngM <- pools .: "young"
1618+ NodeJVMStats <$> pure mapped
1619+ <*> pure direct
1620+ <*> pure oldC
1621+ <*> pure youngC
1622+ <*> threads .: "peak_count"
1623+ <*> threads .: "count"
1624+ <*> pure oldM
1625+ <*> pure survivorM
1626+ <*> pure youngM
1627+ <*> mem .: "non_heap_committed_in_bytes"
1628+ <*> mem .: "non_heap_used_in_bytes"
1629+ <*> mem .: "heap_max_in_bytes"
1630+ <*> mem .: "heap_committed_in_bytes"
1631+ <*> mem .: "heap_used_percent"
1632+ <*> mem .: "heap_used_in_bytes"
1633+ <*> (unMS <$> o .: "uptime_in_millis")
1634+ <*> (posixMS <$> o .: "timestamp")
1635+
1636+instance FromJSON JVMBufferPoolStats where
1637+ parseJSON = withObject "JVMBufferPoolStats" parse
1638+ where
1639+ parse o = JVMBufferPoolStats <$> o .: "total_capacity_in_bytes"
1640+ <*> o .: "used_in_bytes"
1641+ <*> o .: "count"
1642+
1643+instance FromJSON JVMGCStats where
1644+ parseJSON = withObject "JVMGCStats" parse
1645+ where
1646+ parse o = JVMGCStats <$> (unMS <$> o .: "collection_time_in_millis")
1647+ <*> o .: "collection_count"
1648+
1649+instance FromJSON JVMPoolStats where
1650+ parseJSON = withObject "JVMPoolStats" parse
1651+ where
1652+ parse o = JVMPoolStats <$> o .: "peak_max_in_bytes"
1653+ <*> o .: "peak_used_in_bytes"
1654+ <*> o .: "max_in_bytes"
1655+ <*> o .: "used_in_bytes"
1656+
1657+instance FromJSON NodeProcessStats where
1658+ parseJSON = withObject "NodeProcessStats" parse
1659+ where
1660+ parse o = do
1661+ mem <- o .: "mem"
1662+ cpu <- o .: "cpu"
1663+ NodeProcessStats <$> (posixMS <$> o .: "timestamp")
1664+ <*> o .: "open_file_descriptors"
1665+ <*> o .: "max_file_descriptors"
1666+ <*> cpu .: "percent"
1667+ <*> (unMS <$> cpu .: "total_in_millis")
1668+ <*> mem .: "total_virtual_in_bytes"
1669+
1670+instance FromJSON NodeOSStats where
1671+ parseJSON = withObject "NodeOSStats" parse
1672+ where
1673+ parse o = do
1674+ swap <- o .: "swap"
1675+ mem <- o .: "mem"
1676+ cpu <- o .: "cpu"
1677+ load <- o .:? "load_average"
1678+ NodeOSStats <$> (posixMS <$> o .: "timestamp")
1679+ <*> cpu .: "percent"
1680+ <*> pure load
1681+ <*> mem .: "total_in_bytes"
1682+ <*> mem .: "free_in_bytes"
1683+ <*> mem .: "free_percent"
1684+ <*> mem .: "used_in_bytes"
1685+ <*> mem .: "used_percent"
1686+ <*> swap .: "total_in_bytes"
1687+ <*> swap .: "free_in_bytes"
1688+ <*> swap .: "used_in_bytes"
1689+
1690+instance FromJSON LoadAvgs where
1691+ parseJSON = withArray "LoadAvgs" parse
1692+ where
1693+ parse v = case V.toList v of
1694+ [one, five, fifteen] -> LoadAvgs <$> parseJSON one
1695+ <*> parseJSON five
1696+ <*> parseJSON fifteen
1697+ _ -> fail "Expecting a triple of Doubles"
1698+
1699+instance FromJSON NodeIndicesStats where
1700+ parseJSON = withObject "NodeIndicesStats" parse
1701+ where
1702+ parse o = do
1703+ let (.::) mv k = case mv of
1704+ Just v -> Just <$> v .: k
1705+ Nothing -> pure Nothing
1706+ mRecovery <- o .:? "recovery"
1707+ mQueryCache <- o .:? "query_cache"
1708+ mSuggest <- o .:? "suggest"
1709+ translog <- o .: "translog"
1710+ segments <- o .: "segments"
1711+ completion <- o .: "completion"
1712+ mPercolate <- o .:? "percolate"
1713+ fielddata <- o .: "fielddata"
1714+ warmer <- o .: "warmer"
1715+ flush <- o .: "flush"
1716+ refresh <- o .: "refresh"
1717+ merges <- o .: "merges"
1718+ search <- o .: "search"
1719+ getStats <- o .: "get"
1720+ indexing <- o .: "indexing"
1721+ store <- o .: "store"
1722+ docs <- o .: "docs"
1723+ NodeIndicesStats <$> (fmap unMS <$> mRecovery .:: "throttle_time_in_millis")
1724+ <*> mRecovery .:: "current_as_target"
1725+ <*> mRecovery .:: "current_as_source"
1726+ <*> mQueryCache .:: "miss_count"
1727+ <*> mQueryCache .:: "hit_count"
1728+ <*> mQueryCache .:: "evictions"
1729+ <*> mQueryCache .:: "memory_size_in_bytes"
1730+ <*> mSuggest .:: "current"
1731+ <*> (fmap unMS <$> mSuggest .:: "time_in_millis")
1732+ <*> mSuggest .:: "total"
1733+ <*> translog .: "size_in_bytes"
1734+ <*> translog .: "operations"
1735+ <*> segments .:? "fixed_bit_set_memory_in_bytes"
1736+ <*> segments .: "version_map_memory_in_bytes"
1737+ <*> segments .:? "index_writer_max_memory_in_bytes"
1738+ <*> segments .: "index_writer_memory_in_bytes"
1739+ <*> segments .: "memory_in_bytes"
1740+ <*> segments .: "count"
1741+ <*> completion .: "size_in_bytes"
1742+ <*> mPercolate .:: "queries"
1743+ <*> mPercolate .:: "memory_size_in_bytes"
1744+ <*> mPercolate .:: "current"
1745+ <*> (fmap unMS <$> mPercolate .:: "time_in_millis")
1746+ <*> mPercolate .:: "total"
1747+ <*> fielddata .: "evictions"
1748+ <*> fielddata .: "memory_size_in_bytes"
1749+ <*> (unMS <$> warmer .: "total_time_in_millis")
1750+ <*> warmer .: "total"
1751+ <*> warmer .: "current"
1752+ <*> (unMS <$> flush .: "total_time_in_millis")
1753+ <*> flush .: "total"
1754+ <*> (unMS <$> refresh .: "total_time_in_millis")
1755+ <*> refresh .: "total"
1756+ <*> merges .: "total_size_in_bytes"
1757+ <*> merges .: "total_docs"
1758+ <*> (unMS <$> merges .: "total_time_in_millis")
1759+ <*> merges .: "total"
1760+ <*> merges .: "current_size_in_bytes"
1761+ <*> merges .: "current_docs"
1762+ <*> merges .: "current"
1763+ <*> search .: "fetch_current"
1764+ <*> (unMS <$> search .: "fetch_time_in_millis")
1765+ <*> search .: "fetch_total"
1766+ <*> search .: "query_current"
1767+ <*> (unMS <$> search .: "query_time_in_millis")
1768+ <*> search .: "query_total"
1769+ <*> search .: "open_contexts"
1770+ <*> getStats .: "current"
1771+ <*> (unMS <$> getStats .: "missing_time_in_millis")
1772+ <*> getStats .: "missing_total"
1773+ <*> (unMS <$> getStats .: "exists_time_in_millis")
1774+ <*> getStats .: "exists_total"
1775+ <*> (unMS <$> getStats .: "time_in_millis")
1776+ <*> getStats .: "total"
1777+ <*> (fmap unMS <$> indexing .:? "throttle_time_in_millis")
1778+ <*> indexing .:? "is_throttled"
1779+ <*> indexing .:? "noop_update_total"
1780+ <*> indexing .: "delete_current"
1781+ <*> (unMS <$> indexing .: "delete_time_in_millis")
1782+ <*> indexing .: "delete_total"
1783+ <*> indexing .: "index_current"
1784+ <*> (unMS <$> indexing .: "index_time_in_millis")
1785+ <*> indexing .: "index_total"
1786+ <*> (unMS <$> store .: "throttle_time_in_millis")
1787+ <*> store .: "size_in_bytes"
1788+ <*> docs .: "deleted"
1789+ <*> docs .: "count"
1790+
1791+instance FromJSON NodeBreakersStats where
1792+ parseJSON = withObject "NodeBreakersStats" parse
1793+ where
1794+ parse o = NodeBreakersStats <$> o .: "parent"
1795+ <*> o .: "request"
1796+ <*> o .: "fielddata"
1797+
1798+parseNodeStats :: FullNodeId -> Object -> Parser NodeStats
1799+parseNodeStats fnid o = do
1800+ NodeStats <$> o .: "name"
1801+ <*> pure fnid
1802+ <*> o .:? "breakers"
1803+ <*> o .: "http"
1804+ <*> o .: "transport"
1805+ <*> o .: "fs"
1806+ <*> o .:? "network"
1807+ <*> o .: "thread_pool"
1808+ <*> o .: "jvm"
1809+ <*> o .: "process"
1810+ <*> o .: "os"
1811+ <*> o .: "indices"
1812+
1813+parseNodeInfo :: FullNodeId -> Object -> Parser NodeInfo
1814+parseNodeInfo nid o =
1815+ NodeInfo <$> o .:? "http_address"
1816+ <*> o .: "build_hash"
1817+ <*> o .: "version"
1818+ <*> o .: "ip"
1819+ <*> o .: "host"
1820+ <*> o .: "transport_address"
1821+ <*> o .: "name"
1822+ <*> pure nid
1823+ <*> o .: "plugins"
1824+ <*> o .: "http"
1825+ <*> o .: "transport"
1826+ <*> o .:? "network"
1827+ <*> o .: "thread_pool"
1828+ <*> o .: "jvm"
1829+ <*> o .: "process"
1830+ <*> o .: "os"
1831+ <*> o .: "settings"
1832+
1833+instance FromJSON NodePluginInfo where
1834+ parseJSON = withObject "NodePluginInfo" parse
1835+ where
1836+ parse o = NodePluginInfo <$> o .:? "site"
1837+ <*> o .:? "jvm"
1838+ <*> o .: "description"
1839+ <*> o .: "version"
1840+ <*> o .: "name"
1841+
1842+instance FromJSON NodeHTTPInfo where
1843+ parseJSON = withObject "NodeHTTPInfo" parse
1844+ where
1845+ parse o = NodeHTTPInfo <$> o .: "max_content_length_in_bytes"
1846+ <*> parseJSON (Object o)
1847+
1848+instance FromJSON BoundTransportAddress where
1849+ parseJSON = withObject "BoundTransportAddress" parse
1850+ where
1851+ parse o = BoundTransportAddress <$> o .: "publish_address"
1852+ <*> o .: "bound_address"
1853+
1854+instance FromJSON NodeOSInfo where
1855+ parseJSON = withObject "NodeOSInfo" parse
1856+ where
1857+ parse o = do
1858+ NodeOSInfo <$> (unMS <$> o .: "refresh_interval_in_millis")
1859+ <*> o .: "name"
1860+ <*> o .: "arch"
1861+ <*> o .: "version"
1862+ <*> o .: "available_processors"
1863+ <*> o .: "allocated_processors"
1864+
1865+
1866+instance FromJSON CPUInfo where
1867+ parseJSON = withObject "CPUInfo" parse
1868+ where
1869+ parse o = CPUInfo <$> o .: "cache_size_in_bytes"
1870+ <*> o .: "cores_per_socket"
1871+ <*> o .: "total_sockets"
1872+ <*> o .: "total_cores"
1873+ <*> o .: "mhz"
1874+ <*> o .: "model"
1875+ <*> o .: "vendor"
1876+
1877+instance FromJSON NodeProcessInfo where
1878+ parseJSON = withObject "NodeProcessInfo" parse
1879+ where
1880+ parse o = NodeProcessInfo <$> o .: "mlockall"
1881+ <*> o .:? "max_file_descriptors"
1882+ <*> o .: "id"
1883+ <*> (unMS <$> o .: "refresh_interval_in_millis")
1884+
1885+instance FromJSON NodeJVMInfo where
1886+ parseJSON = withObject "NodeJVMInfo" parse
1887+ where
1888+ parse o = NodeJVMInfo <$> o .: "memory_pools"
1889+ <*> o .: "gc_collectors"
1890+ <*> o .: "mem"
1891+ <*> (posixMS <$> o .: "start_time_in_millis")
1892+ <*> o .: "vm_vendor"
1893+ <*> o .: "vm_version"
1894+ <*> o .: "vm_name"
1895+ <*> (unJVMVersion <$> o .: "version")
1896+ <*> o .: "pid"
1897+
1898+instance FromJSON JVMVersion where
1899+ parseJSON (String t) =
1900+ JVMVersion <$> parseJSON (String (T.replace "_" "." t))
1901+ parseJSON v = JVMVersion <$> parseJSON v
1902+
1903+instance FromJSON JVMMemoryInfo where
1904+ parseJSON = withObject "JVMMemoryInfo" parse
1905+ where
1906+ parse o = JVMMemoryInfo <$> o .: "direct_max_in_bytes"
1907+ <*> o .: "non_heap_max_in_bytes"
1908+ <*> o .: "non_heap_init_in_bytes"
1909+ <*> o .: "heap_max_in_bytes"
1910+ <*> o .: "heap_init_in_bytes"
1911+
1912+instance FromJSON NodeThreadPoolsInfo where
1913+ parseJSON = withObject "NodeThreadPoolsInfo" parse
1914+ where
1915+ parse o = NodeThreadPoolsInfo <$> o .: "refresh"
1916+ <*> o .: "management"
1917+ <*> o .:? "percolate"
1918+ <*> o .:? "listener"
1919+ <*> o .:? "fetch_shard_started"
1920+ <*> o .: "search"
1921+ <*> o .: "flush"
1922+ <*> o .: "warmer"
1923+ <*> o .:? "optimize"
1924+ <*> o .: "bulk"
1925+ <*> o .:? "suggest"
1926+ <*> o .: "force_merge"
1927+ <*> o .: "snapshot"
1928+ <*> o .: "get"
1929+ <*> o .:? "fetch_shard_store"
1930+ <*> o .: "index"
1931+ <*> o .: "generic"
1932+
1933+instance FromJSON NodeThreadPoolInfo where
1934+ parseJSON = withObject "NodeThreadPoolInfo" parse
1935+ where
1936+ parse o = do
1937+ ka <- maybe (return Nothing) (fmap Just . parseStringInterval) =<< o .:? "keep_alive"
1938+ NodeThreadPoolInfo <$> (parseJSON . unStringlyTypeJSON =<< o .: "queue_size")
1939+ <*> pure ka
1940+ <*> o .:? "min"
1941+ <*> o .:? "max"
1942+ <*> o .: "type"
1943+
1944+data TimeInterval = Weeks
1945+ | Days
1946+ | Hours
1947+ | Minutes
1948+ | Seconds deriving Eq
1949+
1950+instance Show TimeInterval where
1951+ show Weeks = "w"
1952+ show Days = "d"
1953+ show Hours = "h"
1954+ show Minutes = "m"
1955+ show Seconds = "s"
1956+
1957+instance Read TimeInterval where
1958+ readPrec = f =<< TR.get
1959+ where
1960+ f 'w' = return Weeks
1961+ f 'd' = return Days
1962+ f 'h' = return Hours
1963+ f 'm' = return Minutes
1964+ f 's' = return Seconds
1965+ f _ = fail "TimeInterval expected one of w, d, h, m, s"
1966+
1967+data Interval = Year
1968+ | Quarter
1969+ | Month
1970+ | Week
1971+ | Day
1972+ | Hour
1973+ | Minute
1974+ | Second deriving (Eq, Show)
1975+
1976+parseStringInterval :: (Monad m) => String -> m NominalDiffTime
1977+parseStringInterval s = case span isNumber s of
1978+ ("", _) -> fail "Invalid interval"
1979+ (nS, unitS) -> case (readMay nS, readMay unitS) of
1980+ (Just n, Just unit) -> return (fromInteger (n * unitNDT unit))
1981+ (Nothing, _) -> fail "Invalid interval number"
1982+ (_, Nothing) -> fail "Invalid interval unit"
1983+ where
1984+ unitNDT Seconds = 1
1985+ unitNDT Minutes = 60
1986+ unitNDT Hours = 60 * 60
1987+ unitNDT Days = 24 * 60 * 60
1988+ unitNDT Weeks = 7 * 24 * 60 * 60
1989+
1990+instance FromJSON ThreadPoolSize where
1991+ parseJSON v = parseAsNumber v <|> parseAsString v
1992+ where
1993+ parseAsNumber = parseAsInt <=< parseJSON
1994+ parseAsInt (-1) = return ThreadPoolUnbounded
1995+ parseAsInt n
1996+ | n >= 0 = return (ThreadPoolBounded n)
1997+ | otherwise = fail "Thread pool size must be >= -1."
1998+ parseAsString = withText "ThreadPoolSize" $ \t ->
1999+ case first (readMay . T.unpack) (T.span isNumber t) of
2000+ (Just n, "k") -> return (ThreadPoolBounded (n * 1000))
2001+ (Just n, "") -> return (ThreadPoolBounded n)
2002+ _ -> fail ("Invalid thread pool size " <> T.unpack t)
2003+
2004+instance FromJSON ThreadPoolType where
2005+ parseJSON = withText "ThreadPoolType" parse
2006+ where
2007+ parse "scaling" = return ThreadPoolScaling
2008+ parse "fixed" = return ThreadPoolFixed
2009+ parse "cached" = return ThreadPoolCached
2010+ parse e = fail ("Unexpected thread pool type" <> T.unpack e)
2011+
2012+instance FromJSON NodeTransportInfo where
2013+ parseJSON = withObject "NodeTransportInfo" parse
2014+ where
2015+ parse o = NodeTransportInfo <$> (maybe (return mempty) parseProfiles =<< o .:? "profiles")
2016+ <*> parseJSON (Object o)
2017+ parseProfiles (Object o) | HM.null o = return []
2018+ parseProfiles v@(Array _) = parseJSON v
2019+ parseProfiles Null = return []
2020+ parseProfiles _ = fail "Could not parse profiles"
2021+
2022+instance FromJSON NodeNetworkInfo where
2023+ parseJSON = withObject "NodeNetworkInfo" parse
2024+ where
2025+ parse o = NodeNetworkInfo <$> o .: "primary_interface"
2026+ <*> (unMS <$> o .: "refresh_interval_in_millis")
2027+
2028+
2029+instance FromJSON NodeNetworkInterface where
2030+ parseJSON = withObject "NodeNetworkInterface" parse
2031+ where
2032+ parse o = NodeNetworkInterface <$> o .: "mac_address"
2033+ <*> o .: "name"
2034+ <*> o .: "address"
2035+
2036+
2037+instance ToJSON Version where
2038+ toJSON Version {..} = object ["number" .= number
2039+ ,"build_hash" .= build_hash
2040+ ,"build_date" .= build_date
2041+ ,"build_snapshot" .= build_snapshot
2042+ ,"lucene_version" .= lucene_version]
2043+
2044+instance FromJSON Version where
2045+ parseJSON = withObject "Version" parse
2046+ where parse o = Version
2047+ <$> o .: "number"
2048+ <*> o .: "build_hash"
2049+ <*> o .: "build_date"
2050+ <*> o .: "build_snapshot"
2051+ <*> o .: "lucene_version"
2052+
2053+instance ToJSON VersionNumber where
2054+ toJSON = toJSON . Vers.showVersion . versionNumber
2055+
2056+instance FromJSON VersionNumber where
2057+ parseJSON = withText "VersionNumber" (parse . T.unpack)
2058+ where
2059+ parse s = case filter (null . snd)(RP.readP_to_S Vers.parseVersion s) of
2060+ [(v, _)] -> pure (VersionNumber v)
2061+ [] -> fail ("Invalid version string " ++ s)
2062+ xs -> fail ("Ambiguous version string " ++ s ++ " (" ++ intercalate ", " (Vers.showVersion . fst <$> xs) ++ ")")
src/Database/V5/Bloodhound/Types/Internal/Newtypes.hsnew file+195
@@ -0,0 +1,195 @@
1+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+
4+module Database.V5.Bloodhound.Types.Internal.Newtypes where
5+
6+import Bloodhound.Import
7+
8+{-| 'MappingName' is part of mappings which are how ES describes and schematizes
9+ the data in the indices.
10+-}
11+newtype MappingName =
12+ MappingName Text
13+ deriving (Eq, Show, ToJSON, FromJSON)
14+
15+newtype ShardId = ShardId { shardId :: Int }
16+ deriving (Eq, Show, FromJSON)
17+
18+{-| 'DocId' is a generic wrapper value for expressing unique Document IDs.
19+ Can be set by the user or created by ES itself. Often used in client
20+ functions for poking at specific documents.
21+-}
22+newtype DocId =
23+ DocId Text
24+ deriving (Eq, Show, ToJSON, FromJSON)
25+
26+{-| 'FieldName' is used all over the place wherever a specific field within
27+ a document needs to be specified, usually in 'Query's or 'Filter's.
28+-}
29+newtype FieldName =
30+ FieldName Text
31+ deriving (Eq, Read, Show, ToJSON, FromJSON)
32+
33+newtype TypeName =
34+ TypeName Text
35+ deriving (Eq, Show, ToJSON, FromJSON)
36+
37+{-| 'QueryString' is used to wrap query text bodies, be they human written or not.
38+-}
39+newtype QueryString =
40+ QueryString Text
41+ deriving (Eq, Show, ToJSON, FromJSON)
42+
43+
44+{-| 'Script' is often used in place of 'FieldName' to specify more
45+complex ways of extracting a value from a document.
46+-}
47+newtype Script =
48+ Script { scriptText :: Text }
49+ deriving (Eq, Show)
50+
51+{-| 'CacheName' is used in 'RegexpFilter' for describing the
52+ 'CacheKey' keyed caching behavior.
53+-}
54+newtype CacheName =
55+ CacheName Text
56+ deriving (Eq, Show, FromJSON, ToJSON)
57+
58+{-| 'CacheKey' is used in 'RegexpFilter' to key regex caching.
59+-}
60+newtype CacheKey =
61+ CacheKey Text deriving (Eq, Show, FromJSON, ToJSON)
62+newtype Existence =
63+ Existence Bool deriving (Eq, Show, FromJSON, ToJSON)
64+newtype NullValue =
65+ NullValue Bool deriving (Eq, Show, FromJSON, ToJSON)
66+newtype CutoffFrequency =
67+ CutoffFrequency Double deriving (Eq, Show, FromJSON, ToJSON)
68+newtype Analyzer =
69+ Analyzer Text deriving (Eq, Show, FromJSON, ToJSON)
70+newtype MaxExpansions =
71+ MaxExpansions Int deriving (Eq, Show, FromJSON, ToJSON)
72+
73+{-| 'Lenient', if set to true, will cause format based failures to be
74+ ignored. I don't know what the bloody default is, Elasticsearch
75+ documentation didn't say what it was. Let me know if you figure it out.
76+-}
77+newtype Lenient =
78+ Lenient Bool deriving (Eq, Show, FromJSON, ToJSON)
79+newtype Tiebreaker =
80+ Tiebreaker Double deriving (Eq, Show, FromJSON, ToJSON)
81+
82+{-| 'MinimumMatch' controls how many should clauses in the bool query should
83+ match. Can be an absolute value (2) or a percentage (30%) or a
84+ combination of both.
85+-}
86+newtype MinimumMatch =
87+ MinimumMatch Int deriving (Eq, Show, FromJSON, ToJSON)
88+newtype DisableCoord =
89+ DisableCoord Bool deriving (Eq, Show, FromJSON, ToJSON)
90+newtype IgnoreTermFrequency =
91+ IgnoreTermFrequency Bool deriving (Eq, Show, FromJSON, ToJSON)
92+newtype MinimumTermFrequency =
93+ MinimumTermFrequency Int deriving (Eq, Show, FromJSON, ToJSON)
94+newtype MaxQueryTerms =
95+ MaxQueryTerms Int deriving (Eq, Show, FromJSON, ToJSON)
96+newtype Fuzziness =
97+ Fuzziness Double deriving (Eq, Show, FromJSON, ToJSON)
98+
99+{-| 'PrefixLength' is the prefix length used in queries, defaults to 0. -}
100+newtype PrefixLength =
101+ PrefixLength Int deriving (Eq, Show, FromJSON, ToJSON)
102+newtype PercentMatch =
103+ PercentMatch Double deriving (Eq, Show, FromJSON, ToJSON)
104+newtype StopWord =
105+ StopWord Text deriving (Eq, Show, FromJSON, ToJSON)
106+newtype QueryPath =
107+ QueryPath Text deriving (Eq, Show, FromJSON, ToJSON)
108+
109+{-| Allowing a wildcard at the beginning of a word (eg "*ing") is particularly
110+ heavy, because all terms in the index need to be examined, just in case
111+ they match. Leading wildcards can be disabled by setting
112+ 'AllowLeadingWildcard' to false. -}
113+newtype AllowLeadingWildcard =
114+ AllowLeadingWildcard Bool deriving (Eq, Show, FromJSON, ToJSON)
115+newtype LowercaseExpanded =
116+ LowercaseExpanded Bool deriving (Eq, Show, FromJSON, ToJSON)
117+newtype EnablePositionIncrements =
118+ EnablePositionIncrements Bool deriving (Eq, Show, FromJSON, ToJSON)
119+
120+{-| By default, wildcard terms in a query are not analyzed.
121+ Setting 'AnalyzeWildcard' to true enables best-effort analysis.
122+-}
123+newtype AnalyzeWildcard = AnalyzeWildcard Bool deriving (Eq, Show, FromJSON, ToJSON)
124+
125+{-| 'GeneratePhraseQueries' defaults to false.
126+-}
127+newtype GeneratePhraseQueries =
128+ GeneratePhraseQueries Bool deriving (Eq, Show, FromJSON, ToJSON)
129+
130+{-| 'Locale' is used for string conversions - defaults to ROOT.
131+-}
132+newtype Locale = Locale Text deriving (Eq, Show, FromJSON, ToJSON)
133+newtype MaxWordLength = MaxWordLength Int deriving (Eq, Show, FromJSON, ToJSON)
134+newtype MinWordLength = MinWordLength Int deriving (Eq, Show, FromJSON, ToJSON)
135+
136+{-| 'PhraseSlop' sets the default slop for phrases, 0 means exact
137+ phrase matches. Default is 0.
138+-}
139+newtype PhraseSlop = PhraseSlop Int deriving (Eq, Show, FromJSON, ToJSON)
140+newtype MinDocFrequency = MinDocFrequency Int deriving (Eq, Show, FromJSON, ToJSON)
141+newtype MaxDocFrequency = MaxDocFrequency Int deriving (Eq, Show, FromJSON, ToJSON)
142+
143+-- | Newtype wrapper to parse ES's concerning tendency to in some APIs return a floating point number of milliseconds since epoch ಠ_ಠ
144+newtype POSIXMS = POSIXMS { posixMS :: UTCTime }
145+
146+newtype Boost =
147+ Boost Double
148+ deriving (Eq, Show, ToJSON, FromJSON)
149+
150+newtype BoostTerms =
151+ BoostTerms Double
152+ deriving (Eq, Show, ToJSON, FromJSON)
153+
154+{-| 'ShardCount' is part of 'IndexSettings' -}
155+newtype ShardCount =
156+ ShardCount Int
157+ deriving (Eq, Show, ToJSON)
158+
159+{-| 'ReplicaCount' is part of 'IndexSettings' -}
160+newtype ReplicaCount =
161+ ReplicaCount Int
162+ deriving (Eq, Show, ToJSON)
163+
164+{-| 'IndexName' is used to describe which index to query/create/delete -}
165+newtype IndexName =
166+ IndexName Text
167+ deriving (Eq, Show, ToJSON, FromJSON)
168+
169+newtype IndexAliasName =
170+ IndexAliasName { indexAliasName :: IndexName }
171+ deriving (Eq, Show, ToJSON)
172+
173+newtype MaybeNA a = MaybeNA { unMaybeNA :: Maybe a }
174+ deriving (Show, Eq)
175+
176+instance FromJSON a => FromJSON (MaybeNA a) where
177+ parseJSON (String "NA") = pure $ MaybeNA Nothing
178+ parseJSON o = MaybeNA . Just <$> parseJSON o
179+
180+newtype SnapshotName =
181+ SnapshotName { snapshotName :: Text }
182+ deriving (Eq, Show, ToJSON, FromJSON)
183+
184+-- | Milliseconds
185+newtype MS = MS NominalDiffTime
186+
187+-- keeps the unexported constructor warnings at bay
188+unMS :: MS -> NominalDiffTime
189+unMS (MS t) = t
190+
191+
192+instance FromJSON MS where
193+ parseJSON = withScientific "MS" (return . MS . parse)
194+ where
195+ parse n = fromInteger ((truncate n) * 1000)
src/Database/V5/Bloodhound/Types/Internal/Query.hsnew file+1477
@@ -0,0 +1,1477 @@
1+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE RecordWildCards #-}
4+
5+module Database.V5.Bloodhound.Types.Internal.Query where
6+
7+import Bloodhound.Import
8+
9+import Control.Applicative
10+import Data.Char (isNumber)
11+import qualified Data.HashMap.Strict as HM
12+import Data.List (nub)
13+import qualified Data.Text as T
14+import qualified Data.Traversable as DT
15+import qualified Data.Vector as V
16+
17+import Database.V5.Bloodhound.Types.Internal.Newtypes
18+
19+data Query =
20+ TermQuery Term (Maybe Boost)
21+ | TermsQuery Text (NonEmpty Text)
22+ | QueryMatchQuery MatchQuery
23+ | QueryMultiMatchQuery MultiMatchQuery
24+ | QueryBoolQuery BoolQuery
25+ | QueryBoostingQuery BoostingQuery
26+ | QueryCommonTermsQuery CommonTermsQuery
27+ | ConstantScoreQuery Query Boost
28+ | QueryDisMaxQuery DisMaxQuery
29+ | QueryFuzzyLikeThisQuery FuzzyLikeThisQuery
30+ | QueryFuzzyLikeFieldQuery FuzzyLikeFieldQuery
31+ | QueryFuzzyQuery FuzzyQuery
32+ | QueryHasChildQuery HasChildQuery
33+ | QueryHasParentQuery HasParentQuery
34+ | IdsQuery MappingName [DocId]
35+ | QueryIndicesQuery IndicesQuery
36+ | MatchAllQuery (Maybe Boost)
37+ | QueryMoreLikeThisQuery MoreLikeThisQuery
38+ | QueryMoreLikeThisFieldQuery MoreLikeThisFieldQuery
39+ | QueryNestedQuery NestedQuery
40+ | QueryPrefixQuery PrefixQuery
41+ | QueryQueryStringQuery QueryStringQuery
42+ | QuerySimpleQueryStringQuery SimpleQueryStringQuery
43+ | QueryRangeQuery RangeQuery
44+ | QueryRegexpQuery RegexpQuery
45+ | QueryExistsQuery FieldName
46+ | QueryMatchNoneQuery
47+ | QueryTemplateQueryInline TemplateQueryInline
48+ deriving (Eq, Show)
49+
50+-- | As of Elastic 2.0, 'Filters' are just 'Queries' housed in a
51+-- Bool Query, and flagged in a different context.
52+newtype Filter = Filter { unFilter :: Query }
53+ deriving (Eq, Show)
54+
55+instance ToJSON Filter where
56+ toJSON = toJSON . unFilter
57+
58+instance FromJSON Filter where
59+ parseJSON v = Filter <$> parseJSON v
60+
61+data RegexpQuery =
62+ RegexpQuery { regexpQueryField :: FieldName
63+ , regexpQuery :: Regexp
64+ , regexpQueryFlags :: RegexpFlags
65+ , regexpQueryBoost :: Maybe Boost
66+ } deriving (Eq, Show)
67+
68+data RangeQuery =
69+ RangeQuery { rangeQueryField :: FieldName
70+ , rangeQueryRange :: RangeValue
71+ , rangeQueryBoost :: Boost } deriving (Eq, Show)
72+
73+mkRangeQuery :: FieldName -> RangeValue -> RangeQuery
74+mkRangeQuery f r = RangeQuery f r (Boost 1.0)
75+
76+data SimpleQueryStringQuery =
77+ SimpleQueryStringQuery
78+ { simpleQueryStringQuery :: QueryString
79+ , simpleQueryStringField :: Maybe FieldOrFields
80+ , simpleQueryStringOperator :: Maybe BooleanOperator
81+ , simpleQueryStringAnalyzer :: Maybe Analyzer
82+ , simpleQueryStringFlags :: Maybe (NonEmpty SimpleQueryFlag)
83+ , simpleQueryStringLowercaseExpanded :: Maybe LowercaseExpanded
84+ , simpleQueryStringLocale :: Maybe Locale
85+ } deriving (Eq, Show)
86+
87+data SimpleQueryFlag =
88+ SimpleQueryAll
89+ | SimpleQueryNone
90+ | SimpleQueryAnd
91+ | SimpleQueryOr
92+ | SimpleQueryPrefix
93+ | SimpleQueryPhrase
94+ | SimpleQueryPrecedence
95+ | SimpleQueryEscape
96+ | SimpleQueryWhitespace
97+ | SimpleQueryFuzzy
98+ | SimpleQueryNear
99+ | SimpleQuerySlop deriving (Eq, Show)
100+
101+-- use_dis_max and tie_breaker when fields are plural?
102+data QueryStringQuery =
103+ QueryStringQuery
104+ { queryStringQuery :: QueryString
105+ , queryStringDefaultField :: Maybe FieldName
106+ , queryStringOperator :: Maybe BooleanOperator
107+ , queryStringAnalyzer :: Maybe Analyzer
108+ , queryStringAllowLeadingWildcard :: Maybe AllowLeadingWildcard
109+ , queryStringLowercaseExpanded :: Maybe LowercaseExpanded
110+ , queryStringEnablePositionIncrements :: Maybe EnablePositionIncrements
111+ , queryStringFuzzyMaxExpansions :: Maybe MaxExpansions
112+ , queryStringFuzziness :: Maybe Fuzziness
113+ , queryStringFuzzyPrefixLength :: Maybe PrefixLength
114+ , queryStringPhraseSlop :: Maybe PhraseSlop
115+ , queryStringBoost :: Maybe Boost
116+ , queryStringAnalyzeWildcard :: Maybe AnalyzeWildcard
117+ , queryStringGeneratePhraseQueries :: Maybe GeneratePhraseQueries
118+ , queryStringMinimumShouldMatch :: Maybe MinimumMatch
119+ , queryStringLenient :: Maybe Lenient
120+ , queryStringLocale :: Maybe Locale
121+ } deriving (Eq, Show)
122+
123+mkQueryStringQuery :: QueryString -> QueryStringQuery
124+mkQueryStringQuery qs =
125+ QueryStringQuery qs Nothing Nothing
126+ Nothing Nothing Nothing Nothing
127+ Nothing Nothing Nothing Nothing
128+ Nothing Nothing Nothing Nothing
129+ Nothing Nothing
130+
131+data FieldOrFields = FofField FieldName
132+ | FofFields (NonEmpty FieldName) deriving (Eq, Show)
133+
134+data PrefixQuery =
135+ PrefixQuery
136+ { prefixQueryField :: FieldName
137+ , prefixQueryPrefixValue :: Text
138+ , prefixQueryBoost :: Maybe Boost } deriving (Eq, Show)
139+
140+data NestedQuery =
141+ NestedQuery
142+ { nestedQueryPath :: QueryPath
143+ , nestedQueryScoreType :: ScoreType
144+ , nestedQuery :: Query } deriving (Eq, Show)
145+
146+data MoreLikeThisFieldQuery =
147+ MoreLikeThisFieldQuery
148+ { moreLikeThisFieldText :: Text
149+ , moreLikeThisFieldFields :: FieldName
150+ -- default 0.3 (30%)
151+ , moreLikeThisFieldPercentMatch :: Maybe PercentMatch
152+ , moreLikeThisFieldMinimumTermFreq :: Maybe MinimumTermFrequency
153+ , moreLikeThisFieldMaxQueryTerms :: Maybe MaxQueryTerms
154+ , moreLikeThisFieldStopWords :: Maybe (NonEmpty StopWord)
155+ , moreLikeThisFieldMinDocFrequency :: Maybe MinDocFrequency
156+ , moreLikeThisFieldMaxDocFrequency :: Maybe MaxDocFrequency
157+ , moreLikeThisFieldMinWordLength :: Maybe MinWordLength
158+ , moreLikeThisFieldMaxWordLength :: Maybe MaxWordLength
159+ , moreLikeThisFieldBoostTerms :: Maybe BoostTerms
160+ , moreLikeThisFieldBoost :: Maybe Boost
161+ , moreLikeThisFieldAnalyzer :: Maybe Analyzer
162+ } deriving (Eq, Show)
163+
164+data MoreLikeThisQuery =
165+ MoreLikeThisQuery
166+ { moreLikeThisText :: Text
167+ , moreLikeThisFields :: Maybe (NonEmpty FieldName)
168+ -- default 0.3 (30%)
169+ , moreLikeThisPercentMatch :: Maybe PercentMatch
170+ , moreLikeThisMinimumTermFreq :: Maybe MinimumTermFrequency
171+ , moreLikeThisMaxQueryTerms :: Maybe MaxQueryTerms
172+ , moreLikeThisStopWords :: Maybe (NonEmpty StopWord)
173+ , moreLikeThisMinDocFrequency :: Maybe MinDocFrequency
174+ , moreLikeThisMaxDocFrequency :: Maybe MaxDocFrequency
175+ , moreLikeThisMinWordLength :: Maybe MinWordLength
176+ , moreLikeThisMaxWordLength :: Maybe MaxWordLength
177+ , moreLikeThisBoostTerms :: Maybe BoostTerms
178+ , moreLikeThisBoost :: Maybe Boost
179+ , moreLikeThisAnalyzer :: Maybe Analyzer
180+ } deriving (Eq, Show)
181+
182+data IndicesQuery =
183+ IndicesQuery
184+ { indicesQueryIndices :: [IndexName]
185+ , indicesQuery :: Query
186+ -- default "all"
187+ , indicesQueryNoMatch :: Maybe Query } deriving (Eq, Show)
188+
189+data HasParentQuery =
190+ HasParentQuery
191+ { hasParentQueryType :: TypeName
192+ , hasParentQuery :: Query
193+ , hasParentQueryScoreType :: Maybe ScoreType } deriving (Eq, Show)
194+
195+data HasChildQuery =
196+ HasChildQuery
197+ { hasChildQueryType :: TypeName
198+ , hasChildQuery :: Query
199+ , hasChildQueryScoreType :: Maybe ScoreType } deriving (Eq, Show)
200+
201+data ScoreType =
202+ ScoreTypeMax
203+ | ScoreTypeSum
204+ | ScoreTypeAvg
205+ | ScoreTypeNone deriving (Eq, Show)
206+
207+data FuzzyQuery =
208+ FuzzyQuery { fuzzyQueryField :: FieldName
209+ , fuzzyQueryValue :: Text
210+ , fuzzyQueryPrefixLength :: PrefixLength
211+ , fuzzyQueryMaxExpansions :: MaxExpansions
212+ , fuzzyQueryFuzziness :: Fuzziness
213+ , fuzzyQueryBoost :: Maybe Boost
214+ } deriving (Eq, Show)
215+
216+data FuzzyLikeFieldQuery =
217+ FuzzyLikeFieldQuery
218+ { fuzzyLikeField :: FieldName
219+ -- anaphora is good for the soul.
220+ , fuzzyLikeFieldText :: Text
221+ , fuzzyLikeFieldMaxQueryTerms :: MaxQueryTerms
222+ , fuzzyLikeFieldIgnoreTermFrequency :: IgnoreTermFrequency
223+ , fuzzyLikeFieldFuzziness :: Fuzziness
224+ , fuzzyLikeFieldPrefixLength :: PrefixLength
225+ , fuzzyLikeFieldBoost :: Boost
226+ , fuzzyLikeFieldAnalyzer :: Maybe Analyzer
227+ } deriving (Eq, Show)
228+
229+data FuzzyLikeThisQuery =
230+ FuzzyLikeThisQuery
231+ { fuzzyLikeFields :: [FieldName]
232+ , fuzzyLikeText :: Text
233+ , fuzzyLikeMaxQueryTerms :: MaxQueryTerms
234+ , fuzzyLikeIgnoreTermFrequency :: IgnoreTermFrequency
235+ , fuzzyLikeFuzziness :: Fuzziness
236+ , fuzzyLikePrefixLength :: PrefixLength
237+ , fuzzyLikeBoost :: Boost
238+ , fuzzyLikeAnalyzer :: Maybe Analyzer
239+ } deriving (Eq, Show)
240+
241+data DisMaxQuery =
242+ DisMaxQuery { disMaxQueries :: [Query]
243+ -- default 0.0
244+ , disMaxTiebreaker :: Tiebreaker
245+ , disMaxBoost :: Maybe Boost
246+ } deriving (Eq, Show)
247+
248+data MatchQuery =
249+ MatchQuery { matchQueryField :: FieldName
250+ , matchQueryQueryString :: QueryString
251+ , matchQueryOperator :: BooleanOperator
252+ , matchQueryZeroTerms :: ZeroTermsQuery
253+ , matchQueryCutoffFrequency :: Maybe CutoffFrequency
254+ , matchQueryMatchType :: Maybe MatchQueryType
255+ , matchQueryAnalyzer :: Maybe Analyzer
256+ , matchQueryMaxExpansions :: Maybe MaxExpansions
257+ , matchQueryLenient :: Maybe Lenient
258+ , matchQueryBoost :: Maybe Boost
259+ , matchQueryMinimumShouldMatch :: Maybe Text
260+ } deriving (Eq, Show)
261+
262+{-| 'mkMatchQuery' is a convenience function that defaults the less common parameters,
263+ enabling you to provide only the 'FieldName' and 'QueryString' to make a 'MatchQuery'
264+-}
265+mkMatchQuery :: FieldName -> QueryString -> MatchQuery
266+mkMatchQuery field query = MatchQuery field query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing Nothing
267+
268+data MatchQueryType =
269+ MatchPhrase
270+ | MatchPhrasePrefix deriving (Eq, Show)
271+
272+data MultiMatchQuery =
273+ MultiMatchQuery { multiMatchQueryFields :: [FieldName]
274+ , multiMatchQueryString :: QueryString
275+ , multiMatchQueryOperator :: BooleanOperator
276+ , multiMatchQueryZeroTerms :: ZeroTermsQuery
277+ , multiMatchQueryTiebreaker :: Maybe Tiebreaker
278+ , multiMatchQueryType :: Maybe MultiMatchQueryType
279+ , multiMatchQueryCutoffFrequency :: Maybe CutoffFrequency
280+ , multiMatchQueryAnalyzer :: Maybe Analyzer
281+ , multiMatchQueryMaxExpansions :: Maybe MaxExpansions
282+ , multiMatchQueryLenient :: Maybe Lenient } deriving (Eq, Show)
283+
284+{-| 'mkMultiMatchQuery' is a convenience function that defaults the less common parameters,
285+ enabling you to provide only the list of 'FieldName's and 'QueryString' to
286+ make a 'MultiMatchQuery'.
287+-}
288+
289+mkMultiMatchQuery :: [FieldName] -> QueryString -> MultiMatchQuery
290+mkMultiMatchQuery matchFields query =
291+ MultiMatchQuery matchFields query
292+ Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
293+
294+data MultiMatchQueryType =
295+ MultiMatchBestFields
296+ | MultiMatchMostFields
297+ | MultiMatchCrossFields
298+ | MultiMatchPhrase
299+ | MultiMatchPhrasePrefix deriving (Eq, Show)
300+
301+data BoolQuery =
302+ BoolQuery { boolQueryMustMatch :: [Query]
303+ , boolQueryFilter :: [Filter]
304+ , boolQueryMustNotMatch :: [Query]
305+ , boolQueryShouldMatch :: [Query]
306+ , boolQueryMinimumShouldMatch :: Maybe MinimumMatch
307+ , boolQueryBoost :: Maybe Boost
308+ , boolQueryDisableCoord :: Maybe DisableCoord
309+ } deriving (Eq, Show)
310+
311+mkBoolQuery :: [Query] -> [Filter] -> [Query] -> [Query] -> BoolQuery
312+mkBoolQuery must filt mustNot should =
313+ BoolQuery must filt mustNot should Nothing Nothing Nothing
314+
315+data BoostingQuery =
316+ BoostingQuery { positiveQuery :: Query
317+ , negativeQuery :: Query
318+ , negativeBoost :: Boost } deriving (Eq, Show)
319+
320+data CommonTermsQuery =
321+ CommonTermsQuery { commonField :: FieldName
322+ , commonQuery :: QueryString
323+ , commonCutoffFrequency :: CutoffFrequency
324+ , commonLowFreqOperator :: BooleanOperator
325+ , commonHighFreqOperator :: BooleanOperator
326+ , commonMinimumShouldMatch :: Maybe CommonMinimumMatch
327+ , commonBoost :: Maybe Boost
328+ , commonAnalyzer :: Maybe Analyzer
329+ , commonDisableCoord :: Maybe DisableCoord
330+ } deriving (Eq, Show)
331+
332+data CommonMinimumMatch =
333+ CommonMinimumMatchHighLow MinimumMatchHighLow
334+ | CommonMinimumMatch MinimumMatch
335+ deriving (Eq, Show)
336+
337+data MinimumMatchHighLow =
338+ MinimumMatchHighLow { lowFreq :: MinimumMatch
339+ , highFreq :: MinimumMatch } deriving (Eq, Show)
340+
341+data ZeroTermsQuery = ZeroTermsNone
342+ | ZeroTermsAll deriving (Eq, Show)
343+
344+data RangeExecution = RangeExecutionIndex
345+ | RangeExecutionFielddata deriving (Eq, Show)
346+
347+newtype Regexp = Regexp Text deriving (Eq, Show, FromJSON)
348+
349+data RegexpFlags = AllRegexpFlags
350+ | NoRegexpFlags
351+ | SomeRegexpFlags (NonEmpty RegexpFlag) deriving (Eq, Show)
352+
353+data RegexpFlag = AnyString
354+ | Automaton
355+ | Complement
356+ | Empty
357+ | Intersection
358+ | Interval deriving (Eq, Show)
359+
360+newtype LessThan = LessThan Double deriving (Eq, Show)
361+newtype LessThanEq = LessThanEq Double deriving (Eq, Show)
362+newtype GreaterThan = GreaterThan Double deriving (Eq, Show)
363+newtype GreaterThanEq = GreaterThanEq Double deriving (Eq, Show)
364+
365+newtype LessThanD = LessThanD UTCTime deriving (Eq, Show)
366+newtype LessThanEqD = LessThanEqD UTCTime deriving (Eq, Show)
367+newtype GreaterThanD = GreaterThanD UTCTime deriving (Eq, Show)
368+newtype GreaterThanEqD = GreaterThanEqD UTCTime deriving (Eq, Show)
369+
370+data RangeValue = RangeDateLte LessThanEqD
371+ | RangeDateLt LessThanD
372+ | RangeDateGte GreaterThanEqD
373+ | RangeDateGt GreaterThanD
374+ | RangeDateGtLt GreaterThanD LessThanD
375+ | RangeDateGteLte GreaterThanEqD LessThanEqD
376+ | RangeDateGteLt GreaterThanEqD LessThanD
377+ | RangeDateGtLte GreaterThanD LessThanEqD
378+ | RangeDoubleLte LessThanEq
379+ | RangeDoubleLt LessThan
380+ | RangeDoubleGte GreaterThanEq
381+ | RangeDoubleGt GreaterThan
382+ | RangeDoubleGtLt GreaterThan LessThan
383+ | RangeDoubleGteLte GreaterThanEq LessThanEq
384+ | RangeDoubleGteLt GreaterThanEq LessThan
385+ | RangeDoubleGtLte GreaterThan LessThanEq
386+ deriving (Eq, Show)
387+
388+rangeValueToPair :: RangeValue -> [Pair]
389+rangeValueToPair rv = case rv of
390+ RangeDateLte (LessThanEqD t) -> ["lte" .= t]
391+ RangeDateGte (GreaterThanEqD t) -> ["gte" .= t]
392+ RangeDateLt (LessThanD t) -> ["lt" .= t]
393+ RangeDateGt (GreaterThanD t) -> ["gt" .= t]
394+ RangeDateGteLte (GreaterThanEqD l) (LessThanEqD g) -> ["gte" .= l, "lte" .= g]
395+ RangeDateGtLte (GreaterThanD l) (LessThanEqD g) -> ["gt" .= l, "lte" .= g]
396+ RangeDateGteLt (GreaterThanEqD l) (LessThanD g) -> ["gte" .= l, "lt" .= g]
397+ RangeDateGtLt (GreaterThanD l) (LessThanD g) -> ["gt" .= l, "lt" .= g]
398+ RangeDoubleLte (LessThanEq t) -> ["lte" .= t]
399+ RangeDoubleGte (GreaterThanEq t) -> ["gte" .= t]
400+ RangeDoubleLt (LessThan t) -> ["lt" .= t]
401+ RangeDoubleGt (GreaterThan t) -> ["gt" .= t]
402+ RangeDoubleGteLte (GreaterThanEq l) (LessThanEq g) -> ["gte" .= l, "lte" .= g]
403+ RangeDoubleGtLte (GreaterThan l) (LessThanEq g) -> ["gt" .= l, "lte" .= g]
404+ RangeDoubleGteLt (GreaterThanEq l) (LessThan g) -> ["gte" .= l, "lt" .= g]
405+ RangeDoubleGtLt (GreaterThan l) (LessThan g) -> ["gt" .= l, "lt" .= g]
406+
407+data Term = Term { termField :: Text
408+ , termValue :: Text } deriving (Eq, Show)
409+
410+data BoolMatch = MustMatch Term Cache
411+ | MustNotMatch Term Cache
412+ | ShouldMatch [Term] Cache deriving (Eq, Show)
413+
414+-- "memory" or "indexed"
415+data GeoFilterType = GeoFilterMemory
416+ | GeoFilterIndexed deriving (Eq, Show)
417+
418+data LatLon = LatLon { lat :: Double
419+ , lon :: Double } deriving (Eq, Show)
420+
421+data GeoBoundingBox =
422+ GeoBoundingBox { topLeft :: LatLon
423+ , bottomRight :: LatLon } deriving (Eq, Show)
424+
425+data GeoBoundingBoxConstraint =
426+ GeoBoundingBoxConstraint { geoBBField :: FieldName
427+ , constraintBox :: GeoBoundingBox
428+ , bbConstraintcache :: Cache
429+ , geoType :: GeoFilterType
430+ } deriving (Eq, Show)
431+
432+data GeoPoint =
433+ GeoPoint { geoField :: FieldName
434+ , latLon :: LatLon} deriving (Eq, Show)
435+
436+data DistanceUnit = Miles
437+ | Yards
438+ | Feet
439+ | Inches
440+ | Kilometers
441+ | Meters
442+ | Centimeters
443+ | Millimeters
444+ | NauticalMiles deriving (Eq, Show)
445+
446+data DistanceType = Arc
447+ | SloppyArc -- doesn't exist <1.0
448+ | Plane deriving (Eq, Show)
449+
450+data OptimizeBbox = OptimizeGeoFilterType GeoFilterType
451+ | NoOptimizeBbox deriving (Eq, Show)
452+
453+data Distance =
454+ Distance { coefficient :: Double
455+ , unit :: DistanceUnit } deriving (Eq, Show)
456+
457+data DistanceRange =
458+ DistanceRange { distanceFrom :: Distance
459+ , distanceTo :: Distance } deriving (Eq, Show)
460+
461+type TemplateQueryKey = Text
462+type TemplateQueryValue = Text
463+
464+newtype TemplateQueryKeyValuePairs =
465+ TemplateQueryKeyValuePairs (HM.HashMap TemplateQueryKey TemplateQueryValue)
466+ deriving (Eq, Show)
467+
468+instance ToJSON TemplateQueryKeyValuePairs where
469+ toJSON (TemplateQueryKeyValuePairs x) =
470+ Object $ HM.map toJSON x
471+
472+instance FromJSON TemplateQueryKeyValuePairs where
473+ parseJSON (Object o) =
474+ pure . TemplateQueryKeyValuePairs $ HM.mapMaybe getValue o
475+ where getValue (String x) = Just x
476+ getValue _ = Nothing
477+ parseJSON _ =
478+ fail "error parsing TemplateQueryKeyValuePairs"
479+
480+data TemplateQueryInline =
481+ TemplateQueryInline { inline :: Query
482+ , params :: TemplateQueryKeyValuePairs
483+ }
484+ deriving (Eq, Show)
485+
486+instance ToJSON TemplateQueryInline where
487+ toJSON TemplateQueryInline{..} = object [ "inline" .= inline
488+ , "params" .= params
489+ ]
490+
491+instance FromJSON TemplateQueryInline where
492+ parseJSON = withObject "TemplateQueryInline" parse
493+ where parse o = TemplateQueryInline
494+ <$> o .: "inline"
495+ <*> o .: "params"
496+
497+{-| 'BooleanOperator' is the usual And/Or operators with an ES compatible
498+ JSON encoding baked in. Used all over the place.
499+-}
500+data BooleanOperator = And | Or deriving (Eq, Show)
501+
502+{-| 'Cache' is for telling ES whether it should cache a 'Filter' not.
503+ 'Query's cannot be cached.
504+-}
505+type Cache = Bool -- caching on/off
506+defaultCache :: Cache
507+defaultCache = False
508+
509+instance ToJSON Query where
510+ toJSON (TermQuery (Term termQueryField termQueryValue) boost) =
511+ object [ "term" .=
512+ object [termQueryField .= object merged]]
513+ where
514+ base = [ "value" .= termQueryValue ]
515+ boosted = maybe [] (return . ("boost" .=)) boost
516+ merged = mappend base boosted
517+
518+ toJSON (TermsQuery fieldName terms) =
519+ object [ "terms" .= object conjoined ]
520+ where conjoined = [fieldName .= terms]
521+
522+ toJSON (IdsQuery idsQueryMappingName docIds) =
523+ object [ "ids" .= object conjoined ]
524+ where conjoined = [ "type" .= idsQueryMappingName
525+ , "values" .= fmap toJSON docIds ]
526+
527+ toJSON (QueryQueryStringQuery qQueryStringQuery) =
528+ object [ "query_string" .= qQueryStringQuery ]
529+
530+ toJSON (QueryMatchQuery matchQuery) =
531+ object [ "match" .= matchQuery ]
532+
533+ toJSON (QueryMultiMatchQuery multiMatchQuery) =
534+ toJSON multiMatchQuery
535+
536+ toJSON (QueryBoolQuery boolQuery) =
537+ object [ "bool" .= boolQuery ]
538+
539+ toJSON (QueryBoostingQuery boostingQuery) =
540+ object [ "boosting" .= boostingQuery ]
541+
542+ toJSON (QueryCommonTermsQuery commonTermsQuery) =
543+ object [ "common" .= commonTermsQuery ]
544+
545+ toJSON (ConstantScoreQuery query boost) =
546+ object ["constant_score" .= object ["query" .= query
547+ , "boost" .= boost]]
548+
549+ toJSON (QueryDisMaxQuery disMaxQuery) =
550+ object [ "dis_max" .= disMaxQuery ]
551+
552+ toJSON (QueryFuzzyLikeThisQuery fuzzyQuery) =
553+ object [ "fuzzy_like_this" .= fuzzyQuery ]
554+
555+ toJSON (QueryFuzzyLikeFieldQuery fuzzyFieldQuery) =
556+ object [ "fuzzy_like_this_field" .= fuzzyFieldQuery ]
557+
558+ toJSON (QueryFuzzyQuery fuzzyQuery) =
559+ object [ "fuzzy" .= fuzzyQuery ]
560+
561+ toJSON (QueryHasChildQuery childQuery) =
562+ object [ "has_child" .= childQuery ]
563+
564+ toJSON (QueryHasParentQuery parentQuery) =
565+ object [ "has_parent" .= parentQuery ]
566+
567+ toJSON (QueryIndicesQuery qIndicesQuery) =
568+ object [ "indices" .= qIndicesQuery ]
569+
570+ toJSON (MatchAllQuery boost) =
571+ object [ "match_all" .= omitNulls [ "boost" .= boost ] ]
572+
573+ toJSON (QueryMoreLikeThisQuery query) =
574+ object [ "more_like_this" .= query ]
575+
576+ toJSON (QueryMoreLikeThisFieldQuery query) =
577+ object [ "more_like_this_field" .= query ]
578+
579+ toJSON (QueryNestedQuery query) =
580+ object [ "nested" .= query ]
581+
582+ toJSON (QueryPrefixQuery query) =
583+ object [ "prefix" .= query ]
584+
585+ toJSON (QueryRangeQuery query) =
586+ object [ "range" .= query ]
587+
588+ toJSON (QueryRegexpQuery query) =
589+ object [ "regexp" .= query ]
590+
591+ toJSON (QuerySimpleQueryStringQuery query) =
592+ object [ "simple_query_string" .= query ]
593+
594+ toJSON (QueryExistsQuery (FieldName fieldName)) =
595+ object ["exists" .= object
596+ ["field" .= fieldName]
597+ ]
598+ toJSON QueryMatchNoneQuery =
599+ object ["match_none" .= object []]
600+
601+ toJSON (QueryTemplateQueryInline templateQuery) =
602+ object [ "template" .= templateQuery ]
603+
604+instance FromJSON Query where
605+ parseJSON v = withObject "Query" parse v
606+ where parse o = termQuery `taggedWith` "term"
607+ <|> termsQuery `taggedWith` "terms"
608+ <|> idsQuery `taggedWith` "ids"
609+ <|> queryQueryStringQuery `taggedWith` "query_string"
610+ <|> queryMatchQuery `taggedWith` "match"
611+ <|> queryMultiMatchQuery
612+ <|> queryBoolQuery `taggedWith` "bool"
613+ <|> queryBoostingQuery `taggedWith` "boosting"
614+ <|> queryCommonTermsQuery `taggedWith` "common"
615+ <|> constantScoreQuery `taggedWith` "constant_score"
616+ <|> queryDisMaxQuery `taggedWith` "dis_max"
617+ <|> queryFuzzyLikeThisQuery `taggedWith` "fuzzy_like_this"
618+ <|> queryFuzzyLikeFieldQuery `taggedWith` "fuzzy_like_this_field"
619+ <|> queryFuzzyQuery `taggedWith` "fuzzy"
620+ <|> queryHasChildQuery `taggedWith` "has_child"
621+ <|> queryHasParentQuery `taggedWith` "has_parent"
622+ <|> queryIndicesQuery `taggedWith` "indices"
623+ <|> matchAllQuery `taggedWith` "match_all"
624+ <|> queryMoreLikeThisQuery `taggedWith` "more_like_this"
625+ <|> queryMoreLikeThisFieldQuery `taggedWith` "more_like_this_field"
626+ <|> queryNestedQuery `taggedWith` "nested"
627+ <|> queryPrefixQuery `taggedWith` "prefix"
628+ <|> queryRangeQuery `taggedWith` "range"
629+ <|> queryRegexpQuery `taggedWith` "regexp"
630+ <|> querySimpleQueryStringQuery `taggedWith` "simple_query_string"
631+ <|> queryTemplateQueryInline `taggedWith` "template"
632+ where taggedWith parser k = parser =<< o .: k
633+ termQuery = fieldTagged $ \(FieldName fn) o ->
634+ TermQuery <$> (Term fn <$> o .: "value") <*> o .:? "boost"
635+ termsQuery o = case HM.toList o of
636+ [(fn, vs)] -> do vals <- parseJSON vs
637+ case vals of
638+ x:xs -> return (TermsQuery fn (x :| xs))
639+ _ -> fail "Expected non empty list of values"
640+ _ -> fail "Expected object with 1 field-named key"
641+ idsQuery o = IdsQuery <$> o .: "type"
642+ <*> o .: "values"
643+ queryQueryStringQuery = pure . QueryQueryStringQuery
644+ queryMatchQuery = pure . QueryMatchQuery
645+ queryMultiMatchQuery = QueryMultiMatchQuery <$> parseJSON v
646+ queryBoolQuery = pure . QueryBoolQuery
647+ queryBoostingQuery = pure . QueryBoostingQuery
648+ queryCommonTermsQuery = pure . QueryCommonTermsQuery
649+ constantScoreQuery o = case HM.lookup "query" o of
650+ Just x -> ConstantScoreQuery <$> parseJSON x
651+ <*> o .: "boost"
652+ _ -> fail "Does not appear to be a ConstantScoreQuery"
653+ queryDisMaxQuery = pure . QueryDisMaxQuery
654+ queryFuzzyLikeThisQuery = pure . QueryFuzzyLikeThisQuery
655+ queryFuzzyLikeFieldQuery = pure . QueryFuzzyLikeFieldQuery
656+ queryFuzzyQuery = pure . QueryFuzzyQuery
657+ queryHasChildQuery = pure . QueryHasChildQuery
658+ queryHasParentQuery = pure . QueryHasParentQuery
659+ queryIndicesQuery = pure . QueryIndicesQuery
660+ matchAllQuery o = MatchAllQuery <$> o .:? "boost"
661+ queryMoreLikeThisQuery = pure . QueryMoreLikeThisQuery
662+ queryMoreLikeThisFieldQuery = pure . QueryMoreLikeThisFieldQuery
663+ queryNestedQuery = pure . QueryNestedQuery
664+ queryPrefixQuery = pure . QueryPrefixQuery
665+ queryRangeQuery = pure . QueryRangeQuery
666+ queryRegexpQuery = pure . QueryRegexpQuery
667+ querySimpleQueryStringQuery = pure . QuerySimpleQueryStringQuery
668+ -- queryExistsQuery o = QueryExistsQuery <$> o .: "field"
669+ queryTemplateQueryInline = pure . QueryTemplateQueryInline
670+
671+omitNulls :: [(Text, Value)] -> Value
672+omitNulls = object . filter notNull where
673+ notNull (_, Null) = False
674+ notNull (_, Array a) = (not . V.null) a
675+ notNull _ = True
676+
677+fieldTagged :: Monad m => (FieldName -> Object -> m a) -> Object -> m a
678+fieldTagged f o = case HM.toList o of
679+ [(k, Object o')] -> f (FieldName k) o'
680+ _ -> fail "Expected object with 1 field-named key"
681+
682+parseNEJSON :: (FromJSON a) => [Value] -> Parser (NonEmpty a)
683+parseNEJSON [] = fail "Expected non-empty list"
684+parseNEJSON (x:xs) = DT.mapM parseJSON (x :| xs)
685+
686+instance ToJSON SimpleQueryStringQuery where
687+ toJSON SimpleQueryStringQuery {..} =
688+ omitNulls (base ++ maybeAdd)
689+ where base = [ "query" .= simpleQueryStringQuery ]
690+ maybeAdd = [ "fields" .= simpleQueryStringField
691+ , "default_operator" .= simpleQueryStringOperator
692+ , "analyzer" .= simpleQueryStringAnalyzer
693+ , "flags" .= simpleQueryStringFlags
694+ , "lowercase_expanded_terms" .= simpleQueryStringLowercaseExpanded
695+ , "locale" .= simpleQueryStringLocale ]
696+
697+instance FromJSON SimpleQueryStringQuery where
698+ parseJSON = withObject "SimpleQueryStringQuery" parse
699+ where parse o = SimpleQueryStringQuery <$> o .: "query"
700+ <*> o .:? "fields"
701+ <*> o .:? "default_operator"
702+ <*> o .:? "analyzer"
703+ <*> (parseFlags <$> o .:? "flags")
704+ <*> o .:? "lowercase_expanded_terms"
705+ <*> o .:? "locale"
706+ parseFlags (Just (x:xs)) = Just (x :| xs)
707+ parseFlags _ = Nothing
708+
709+instance ToJSON FieldOrFields where
710+ toJSON (FofField fieldName) =
711+ toJSON fieldName
712+ toJSON (FofFields fieldNames) =
713+ toJSON fieldNames
714+
715+instance FromJSON FieldOrFields where
716+ parseJSON v = FofField <$> parseJSON v
717+ <|> FofFields <$> (parseNEJSON =<< parseJSON v)
718+
719+instance ToJSON SimpleQueryFlag where
720+ toJSON SimpleQueryAll = "ALL"
721+ toJSON SimpleQueryNone = "NONE"
722+ toJSON SimpleQueryAnd = "AND"
723+ toJSON SimpleQueryOr = "OR"
724+ toJSON SimpleQueryPrefix = "PREFIX"
725+ toJSON SimpleQueryPhrase = "PHRASE"
726+ toJSON SimpleQueryPrecedence = "PRECEDENCE"
727+ toJSON SimpleQueryEscape = "ESCAPE"
728+ toJSON SimpleQueryWhitespace = "WHITESPACE"
729+ toJSON SimpleQueryFuzzy = "FUZZY"
730+ toJSON SimpleQueryNear = "NEAR"
731+ toJSON SimpleQuerySlop = "SLOP"
732+
733+instance FromJSON SimpleQueryFlag where
734+ parseJSON = withText "SimpleQueryFlag" parse
735+ where parse "ALL" = pure SimpleQueryAll
736+ parse "NONE" = pure SimpleQueryNone
737+ parse "AND" = pure SimpleQueryAnd
738+ parse "OR" = pure SimpleQueryOr
739+ parse "PREFIX" = pure SimpleQueryPrefix
740+ parse "PHRASE" = pure SimpleQueryPhrase
741+ parse "PRECEDENCE" = pure SimpleQueryPrecedence
742+ parse "ESCAPE" = pure SimpleQueryEscape
743+ parse "WHITESPACE" = pure SimpleQueryWhitespace
744+ parse "FUZZY" = pure SimpleQueryFuzzy
745+ parse "NEAR" = pure SimpleQueryNear
746+ parse "SLOP" = pure SimpleQuerySlop
747+ parse f = fail ("Unexpected SimpleQueryFlag: " <> show f)
748+
749+instance ToJSON RegexpQuery where
750+ toJSON (RegexpQuery (FieldName rqQueryField)
751+ (Regexp regexpQueryQuery) rqQueryFlags
752+ rqQueryBoost) =
753+ object [ rqQueryField .= omitNulls base ]
754+ where base = [ "value" .= regexpQueryQuery
755+ , "flags" .= rqQueryFlags
756+ , "boost" .= rqQueryBoost ]
757+
758+instance FromJSON RegexpQuery where
759+ parseJSON = withObject "RegexpQuery" parse
760+ where parse = fieldTagged $ \fn o ->
761+ RegexpQuery fn
762+ <$> o .: "value"
763+ <*> o .: "flags"
764+ <*> o .:? "boost"
765+
766+instance ToJSON QueryStringQuery where
767+ toJSON (QueryStringQuery qsQueryString
768+ qsDefaultField qsOperator
769+ qsAnalyzer qsAllowWildcard
770+ qsLowercaseExpanded qsEnablePositionIncrements
771+ qsFuzzyMaxExpansions qsFuzziness
772+ qsFuzzyPrefixLength qsPhraseSlop
773+ qsBoost qsAnalyzeWildcard
774+ qsGeneratePhraseQueries qsMinimumShouldMatch
775+ qsLenient qsLocale) =
776+ omitNulls base
777+ where
778+ base = [ "query" .= qsQueryString
779+ , "default_field" .= qsDefaultField
780+ , "default_operator" .= qsOperator
781+ , "analyzer" .= qsAnalyzer
782+ , "allow_leading_wildcard" .= qsAllowWildcard
783+ , "lowercase_expanded_terms" .= qsLowercaseExpanded
784+ , "enable_position_increments" .= qsEnablePositionIncrements
785+ , "fuzzy_max_expansions" .= qsFuzzyMaxExpansions
786+ , "fuzziness" .= qsFuzziness
787+ , "fuzzy_prefix_length" .= qsFuzzyPrefixLength
788+ , "phrase_slop" .= qsPhraseSlop
789+ , "boost" .= qsBoost
790+ , "analyze_wildcard" .= qsAnalyzeWildcard
791+ , "auto_generate_phrase_queries" .= qsGeneratePhraseQueries
792+ , "minimum_should_match" .= qsMinimumShouldMatch
793+ , "lenient" .= qsLenient
794+ , "locale" .= qsLocale ]
795+
796+instance FromJSON QueryStringQuery where
797+ parseJSON = withObject "QueryStringQuery" parse
798+ where parse o = QueryStringQuery
799+ <$> o .: "query"
800+ <*> o .:? "default_field"
801+ <*> o .:? "default_operator"
802+ <*> o .:? "analyzer"
803+ <*> o .:? "allow_leading_wildcard"
804+ <*> o .:? "lowercase_expanded_terms"
805+ <*> o .:? "enable_position_increments"
806+ <*> o .:? "fuzzy_max_expansions"
807+ <*> o .:? "fuzziness"
808+ <*> o .:? "fuzzy_prefix_length"
809+ <*> o .:? "phrase_slop"
810+ <*> o .:? "boost"
811+ <*> o .:? "analyze_wildcard"
812+ <*> o .:? "auto_generate_phrase_queries"
813+ <*> o .:? "minimum_should_match"
814+ <*> o .:? "lenient"
815+ <*> o .:? "locale"
816+
817+instance ToJSON RangeQuery where
818+ toJSON (RangeQuery (FieldName fieldName) range boost) =
819+ object [ fieldName .= object conjoined ]
820+ where conjoined = [ "boost" .= boost ] ++ (rangeValueToPair range)
821+
822+instance FromJSON RangeQuery where
823+ parseJSON = withObject "RangeQuery" parse
824+ where parse = fieldTagged $ \fn o ->
825+ RangeQuery fn
826+ <$> parseJSON (Object o)
827+ <*> o .: "boost"
828+
829+instance FromJSON RangeValue where
830+ parseJSON = withObject "RangeValue" parse
831+ where parse o = parseDate o
832+ <|> parseDouble o
833+ parseDate o = do lt <- o .:? "lt"
834+ lte <- o .:? "lte"
835+ gt <- o .:? "gt"
836+ gte <- o .:? "gte"
837+ case (lt, lte, gt, gte) of
838+ (Just a, _, Just b, _) -> return (RangeDateGtLt (GreaterThanD b) (LessThanD a))
839+ (Just a, _, _, Just b)-> return (RangeDateGteLt (GreaterThanEqD b) (LessThanD a))
840+ (_, Just a, Just b, _)-> return (RangeDateGtLte (GreaterThanD b) (LessThanEqD a))
841+ (_, Just a, _, Just b)-> return (RangeDateGteLte (GreaterThanEqD b) (LessThanEqD a))
842+ (_, _, Just a, _)-> return (RangeDateGt (GreaterThanD a))
843+ (Just a, _, _, _)-> return (RangeDateLt (LessThanD a))
844+ (_, _, _, Just a)-> return (RangeDateGte (GreaterThanEqD a))
845+ (_, Just a, _, _)-> return (RangeDateLte (LessThanEqD a))
846+ (Nothing, Nothing, Nothing, Nothing) -> mzero
847+ parseDouble o = do lt <- o .:? "lt"
848+ lte <- o .:? "lte"
849+ gt <- o .:? "gt"
850+ gte <- o .:? "gte"
851+ case (lt, lte, gt, gte) of
852+ (Just a, _, Just b, _) -> return (RangeDoubleGtLt (GreaterThan b) (LessThan a))
853+ (Just a, _, _, Just b)-> return (RangeDoubleGteLt (GreaterThanEq b) (LessThan a))
854+ (_, Just a, Just b, _)-> return (RangeDoubleGtLte (GreaterThan b) (LessThanEq a))
855+ (_, Just a, _, Just b)-> return (RangeDoubleGteLte (GreaterThanEq b) (LessThanEq a))
856+ (_, _, Just a, _)-> return (RangeDoubleGt (GreaterThan a))
857+ (Just a, _, _, _)-> return (RangeDoubleLt (LessThan a))
858+ (_, _, _, Just a)-> return (RangeDoubleGte (GreaterThanEq a))
859+ (_, Just a, _, _)-> return (RangeDoubleLte (LessThanEq a))
860+ (Nothing, Nothing, Nothing, Nothing) -> mzero
861+
862+instance ToJSON PrefixQuery where
863+ toJSON (PrefixQuery (FieldName fieldName) queryValue boost) =
864+ object [ fieldName .= omitNulls base ]
865+ where base = [ "value" .= queryValue
866+ , "boost" .= boost ]
867+
868+instance FromJSON PrefixQuery where
869+ parseJSON = withObject "PrefixQuery" parse
870+ where parse = fieldTagged $ \fn o ->
871+ PrefixQuery fn
872+ <$> o .: "value"
873+ <*> o .:? "boost"
874+
875+instance ToJSON NestedQuery where
876+ toJSON (NestedQuery nqPath nqScoreType nqQuery) =
877+ object [ "path" .= nqPath
878+ , "score_mode" .= nqScoreType
879+ , "query" .= nqQuery ]
880+
881+instance FromJSON NestedQuery where
882+ parseJSON = withObject "NestedQuery" parse
883+ where parse o = NestedQuery
884+ <$> o .: "path"
885+ <*> o .: "score_mode"
886+ <*> o .: "query"
887+
888+instance ToJSON MoreLikeThisFieldQuery where
889+ toJSON (MoreLikeThisFieldQuery text (FieldName fieldName)
890+ percent mtf mqt stopwords mindf maxdf
891+ minwl maxwl boostTerms boost analyzer) =
892+ object [ fieldName .= omitNulls base ]
893+ where base = [ "like_text" .= text
894+ , "percent_terms_to_match" .= percent
895+ , "min_term_freq" .= mtf
896+ , "max_query_terms" .= mqt
897+ , "stop_words" .= stopwords
898+ , "min_doc_freq" .= mindf
899+ , "max_doc_freq" .= maxdf
900+ , "min_word_length" .= minwl
901+ , "max_word_length" .= maxwl
902+ , "boost_terms" .= boostTerms
903+ , "boost" .= boost
904+ , "analyzer" .= analyzer ]
905+
906+instance FromJSON MoreLikeThisFieldQuery where
907+ parseJSON = withObject "MoreLikeThisFieldQuery" parse
908+ where parse = fieldTagged $ \fn o ->
909+ MoreLikeThisFieldQuery
910+ <$> o .: "like_text"
911+ <*> pure fn
912+ <*> o .:? "percent_terms_to_match"
913+ <*> o .:? "min_term_freq"
914+ <*> o .:? "max_query_terms"
915+ -- <*> (optionalNE =<< o .:? "stop_words")
916+ <*> o .:? "stop_words"
917+ <*> o .:? "min_doc_freq"
918+ <*> o .:? "max_doc_freq"
919+ <*> o .:? "min_word_length"
920+ <*> o .:? "max_word_length"
921+ <*> o .:? "boost_terms"
922+ <*> o .:? "boost"
923+ <*> o .:? "analyzer"
924+ -- optionalNE = maybe (pure Nothing) (fmap Just . parseNEJSON)
925+
926+instance ToJSON MoreLikeThisQuery where
927+ toJSON (MoreLikeThisQuery text fields percent
928+ mtf mqt stopwords mindf maxdf
929+ minwl maxwl boostTerms boost analyzer) =
930+ omitNulls base
931+ where base = [ "like_text" .= text
932+ , "fields" .= fields
933+ , "percent_terms_to_match" .= percent
934+ , "min_term_freq" .= mtf
935+ , "max_query_terms" .= mqt
936+ , "stop_words" .= stopwords
937+ , "min_doc_freq" .= mindf
938+ , "max_doc_freq" .= maxdf
939+ , "min_word_length" .= minwl
940+ , "max_word_length" .= maxwl
941+ , "boost_terms" .= boostTerms
942+ , "boost" .= boost
943+ , "analyzer" .= analyzer ]
944+
945+instance FromJSON MoreLikeThisQuery where
946+ parseJSON = withObject "MoreLikeThisQuery" parse
947+ where parse o = MoreLikeThisQuery
948+ <$> o .: "like_text"
949+ -- <*> (optionalNE =<< o .:? "fields")
950+ <*> o .:? "fields"
951+ <*> o .:? "percent_terms_to_match"
952+ <*> o .:? "min_term_freq"
953+ <*> o .:? "max_query_terms"
954+ -- <*> (optionalNE =<< o .:? "stop_words")
955+ <*> o .:? "stop_words"
956+ <*> o .:? "min_doc_freq"
957+ <*> o .:? "max_doc_freq"
958+ <*> o .:? "min_word_length"
959+ <*> o .:? "max_word_length"
960+ <*> o .:? "boost_terms"
961+ <*> o .:? "boost"
962+ <*> o .:? "analyzer"
963+ -- optionalNE = maybe (pure Nothing) (fmap Just . parseNEJSON)
964+
965+instance ToJSON IndicesQuery where
966+ toJSON (IndicesQuery indices query noMatch) =
967+ omitNulls [ "indices" .= indices
968+ , "no_match_query" .= noMatch
969+ , "query" .= query ]
970+
971+instance FromJSON IndicesQuery where
972+ parseJSON = withObject "IndicesQuery" parse
973+ where parse o = IndicesQuery
974+ <$> o .:? "indices" .!= []
975+ <*> o .: "query"
976+ <*> o .:? "no_match_query"
977+
978+instance ToJSON HasParentQuery where
979+ toJSON (HasParentQuery queryType query scoreType) =
980+ omitNulls [ "parent_type" .= queryType
981+ , "score_type" .= scoreType
982+ , "query" .= query ]
983+
984+instance FromJSON HasParentQuery where
985+ parseJSON = withObject "HasParentQuery" parse
986+ where parse o = HasParentQuery
987+ <$> o .: "parent_type"
988+ <*> o .: "query"
989+ <*> o .:? "score_type"
990+
991+instance ToJSON HasChildQuery where
992+ toJSON (HasChildQuery queryType query scoreType) =
993+ omitNulls [ "query" .= query
994+ , "score_type" .= scoreType
995+ , "type" .= queryType ]
996+
997+instance FromJSON HasChildQuery where
998+ parseJSON = withObject "HasChildQuery" parse
999+ where parse o = HasChildQuery
1000+ <$> o .: "type"
1001+ <*> o .: "query"
1002+ <*> o .:? "score_type"
1003+
1004+instance ToJSON FuzzyQuery where
1005+ toJSON (FuzzyQuery (FieldName fieldName) queryText
1006+ prefixLength maxEx fuzziness boost) =
1007+ object [ fieldName .= omitNulls base ]
1008+ where base = [ "value" .= queryText
1009+ , "fuzziness" .= fuzziness
1010+ , "prefix_length" .= prefixLength
1011+ , "boost" .= boost
1012+ , "max_expansions" .= maxEx ]
1013+
1014+instance FromJSON FuzzyQuery where
1015+ parseJSON = withObject "FuzzyQuery" parse
1016+ where parse = fieldTagged $ \fn o ->
1017+ FuzzyQuery fn
1018+ <$> o .: "value"
1019+ <*> o .: "prefix_length"
1020+ <*> o .: "max_expansions"
1021+ <*> o .: "fuzziness"
1022+ <*> o .:? "boost"
1023+
1024+instance ToJSON FuzzyLikeFieldQuery where
1025+ toJSON (FuzzyLikeFieldQuery (FieldName fieldName)
1026+ fieldText maxTerms ignoreFreq fuzziness prefixLength
1027+ boost analyzer) =
1028+ object [ fieldName .=
1029+ omitNulls [ "like_text" .= fieldText
1030+ , "max_query_terms" .= maxTerms
1031+ , "ignore_tf" .= ignoreFreq
1032+ , "fuzziness" .= fuzziness
1033+ , "prefix_length" .= prefixLength
1034+ , "analyzer" .= analyzer
1035+ , "boost" .= boost ]]
1036+
1037+instance FromJSON FuzzyLikeFieldQuery where
1038+ parseJSON = withObject "FuzzyLikeFieldQuery" parse
1039+ where parse = fieldTagged $ \fn o ->
1040+ FuzzyLikeFieldQuery fn
1041+ <$> o .: "like_text"
1042+ <*> o .: "max_query_terms"
1043+ <*> o .: "ignore_tf"
1044+ <*> o .: "fuzziness"
1045+ <*> o .: "prefix_length"
1046+ <*> o .: "boost"
1047+ <*> o .:? "analyzer"
1048+
1049+instance ToJSON FuzzyLikeThisQuery where
1050+ toJSON (FuzzyLikeThisQuery fields text maxTerms
1051+ ignoreFreq fuzziness prefixLength boost analyzer) =
1052+ omitNulls base
1053+ where base = [ "fields" .= fields
1054+ , "like_text" .= text
1055+ , "max_query_terms" .= maxTerms
1056+ , "ignore_tf" .= ignoreFreq
1057+ , "fuzziness" .= fuzziness
1058+ , "prefix_length" .= prefixLength
1059+ , "analyzer" .= analyzer
1060+ , "boost" .= boost ]
1061+
1062+instance FromJSON FuzzyLikeThisQuery where
1063+ parseJSON = withObject "FuzzyLikeThisQuery" parse
1064+ where parse o = FuzzyLikeThisQuery
1065+ <$> o .:? "fields" .!= []
1066+ <*> o .: "like_text"
1067+ <*> o .: "max_query_terms"
1068+ <*> o .: "ignore_tf"
1069+ <*> o .: "fuzziness"
1070+ <*> o .: "prefix_length"
1071+ <*> o .: "boost"
1072+ <*> o .:? "analyzer"
1073+
1074+instance ToJSON DisMaxQuery where
1075+ toJSON (DisMaxQuery queries tiebreaker boost) =
1076+ omitNulls base
1077+ where base = [ "queries" .= queries
1078+ , "boost" .= boost
1079+ , "tie_breaker" .= tiebreaker ]
1080+
1081+instance FromJSON DisMaxQuery where
1082+ parseJSON = withObject "DisMaxQuery" parse
1083+ where parse o = DisMaxQuery
1084+ <$> o .:? "queries" .!= []
1085+ <*> o .: "tie_breaker"
1086+ <*> o .:? "boost"
1087+
1088+instance ToJSON CommonTermsQuery where
1089+ toJSON (CommonTermsQuery (FieldName fieldName)
1090+ (QueryString query) cf lfo hfo msm
1091+ boost analyzer disableCoord) =
1092+ object [fieldName .= omitNulls base ]
1093+ where base = [ "query" .= query
1094+ , "cutoff_frequency" .= cf
1095+ , "low_freq_operator" .= lfo
1096+ , "minimum_should_match" .= msm
1097+ , "boost" .= boost
1098+ , "analyzer" .= analyzer
1099+ , "disable_coord" .= disableCoord
1100+ , "high_freq_operator" .= hfo ]
1101+
1102+instance FromJSON CommonTermsQuery where
1103+ parseJSON = withObject "CommonTermsQuery" parse
1104+ where parse = fieldTagged $ \fn o ->
1105+ CommonTermsQuery fn
1106+ <$> o .: "query"
1107+ <*> o .: "cutoff_frequency"
1108+ <*> o .: "low_freq_operator"
1109+ <*> o .: "high_freq_operator"
1110+ <*> o .:? "minimum_should_match"
1111+ <*> o .:? "boost"
1112+ <*> o .:? "analyzer"
1113+ <*> o .:? "disable_coord"
1114+
1115+instance ToJSON CommonMinimumMatch where
1116+ toJSON (CommonMinimumMatch mm) = toJSON mm
1117+ toJSON (CommonMinimumMatchHighLow (MinimumMatchHighLow lowF highF)) =
1118+ object [ "low_freq" .= lowF
1119+ , "high_freq" .= highF ]
1120+
1121+instance FromJSON CommonMinimumMatch where
1122+ parseJSON v = parseMinimum v
1123+ <|> parseMinimumHighLow v
1124+ where parseMinimum = fmap CommonMinimumMatch . parseJSON
1125+ parseMinimumHighLow = fmap CommonMinimumMatchHighLow . withObject "CommonMinimumMatchHighLow" (\o ->
1126+ MinimumMatchHighLow
1127+ <$> o .: "low_freq"
1128+ <*> o .: "high_freq")
1129+
1130+
1131+instance ToJSON BoostingQuery where
1132+ toJSON (BoostingQuery bqPositiveQuery bqNegativeQuery bqNegativeBoost) =
1133+ object [ "positive" .= bqPositiveQuery
1134+ , "negative" .= bqNegativeQuery
1135+ , "negative_boost" .= bqNegativeBoost ]
1136+
1137+instance FromJSON BoostingQuery where
1138+ parseJSON = withObject "BoostingQuery" parse
1139+ where parse o = BoostingQuery
1140+ <$> o .: "positive"
1141+ <*> o .: "negative"
1142+ <*> o .: "negative_boost"
1143+
1144+instance ToJSON BoolQuery where
1145+ toJSON (BoolQuery mustM filterM' notM shouldM bqMin boost disableCoord) =
1146+ omitNulls base
1147+ where base = [ "must" .= mustM
1148+ , "filter" .= filterM'
1149+ , "must_not" .= notM
1150+ , "should" .= shouldM
1151+ , "minimum_should_match" .= bqMin
1152+ , "boost" .= boost
1153+ , "disable_coord" .= disableCoord ]
1154+
1155+instance FromJSON BoolQuery where
1156+ parseJSON = withObject "BoolQuery" parse
1157+ where parse o = BoolQuery
1158+ <$> o .:? "must" .!= []
1159+ <*> o .:? "filter" .!= []
1160+ <*> o .:? "must_not" .!= []
1161+ <*> o .:? "should" .!= []
1162+ <*> o .:? "minimum_should_match"
1163+ <*> o .:? "boost"
1164+ <*> o .:? "disable_coord"
1165+
1166+instance ToJSON MatchQuery where
1167+ toJSON (MatchQuery (FieldName fieldName)
1168+ (QueryString mqQueryString) booleanOperator
1169+ zeroTermsQuery cutoffFrequency matchQueryType
1170+ analyzer maxExpansions lenient boost
1171+ minShouldMatch
1172+ ) =
1173+ object [ fieldName .= omitNulls base ]
1174+ where base = [ "query" .= mqQueryString
1175+ , "operator" .= booleanOperator
1176+ , "zero_terms_query" .= zeroTermsQuery
1177+ , "cutoff_frequency" .= cutoffFrequency
1178+ , "type" .= matchQueryType
1179+ , "analyzer" .= analyzer
1180+ , "max_expansions" .= maxExpansions
1181+ , "lenient" .= lenient
1182+ , "boost" .= boost
1183+ , "minimum_should_match" .= minShouldMatch
1184+ ]
1185+
1186+instance FromJSON MatchQuery where
1187+ parseJSON = withObject "MatchQuery" parse
1188+ where parse = fieldTagged $ \fn o ->
1189+ MatchQuery fn
1190+ <$> o .: "query"
1191+ <*> o .: "operator"
1192+ <*> o .: "zero_terms_query"
1193+ <*> o .:? "cutoff_frequency"
1194+ <*> o .:? "type"
1195+ <*> o .:? "analyzer"
1196+ <*> o .:? "max_expansions"
1197+ <*> o .:? "lenient"
1198+ <*> o .:? "boost"
1199+ <*> o .:? "minimum_should_match"
1200+
1201+instance ToJSON MultiMatchQuery where
1202+ toJSON (MultiMatchQuery fields (QueryString query) boolOp
1203+ ztQ tb mmqt cf analyzer maxEx lenient) =
1204+ object ["multi_match" .= omitNulls base]
1205+ where base = [ "fields" .= fmap toJSON fields
1206+ , "query" .= query
1207+ , "operator" .= boolOp
1208+ , "zero_terms_query" .= ztQ
1209+ , "tie_breaker" .= tb
1210+ , "type" .= mmqt
1211+ , "cutoff_frequency" .= cf
1212+ , "analyzer" .= analyzer
1213+ , "max_expansions" .= maxEx
1214+ , "lenient" .= lenient ]
1215+
1216+instance FromJSON MultiMatchQuery where
1217+ parseJSON = withObject "MultiMatchQuery" parse
1218+ where parse raw = do o <- raw .: "multi_match"
1219+ MultiMatchQuery
1220+ <$> o .:? "fields" .!= []
1221+ <*> o .: "query"
1222+ <*> o .: "operator"
1223+ <*> o .: "zero_terms_query"
1224+ <*> o .:? "tie_breaker"
1225+ <*> o .:? "type"
1226+ <*> o .:? "cutoff_frequency"
1227+ <*> o .:? "analyzer"
1228+ <*> o .:? "max_expansions"
1229+ <*> o .:? "lenient"
1230+
1231+instance ToJSON MultiMatchQueryType where
1232+ toJSON MultiMatchBestFields = "best_fields"
1233+ toJSON MultiMatchMostFields = "most_fields"
1234+ toJSON MultiMatchCrossFields = "cross_fields"
1235+ toJSON MultiMatchPhrase = "phrase"
1236+ toJSON MultiMatchPhrasePrefix = "phrase_prefix"
1237+
1238+instance FromJSON MultiMatchQueryType where
1239+ parseJSON = withText "MultiMatchPhrasePrefix" parse
1240+ where parse "best_fields" = pure MultiMatchBestFields
1241+ parse "most_fields" = pure MultiMatchMostFields
1242+ parse "cross_fields" = pure MultiMatchCrossFields
1243+ parse "phrase" = pure MultiMatchPhrase
1244+ parse "phrase_prefix" = pure MultiMatchPhrasePrefix
1245+ parse t = fail ("Unexpected MultiMatchPhrasePrefix: " <> show t)
1246+
1247+instance ToJSON BooleanOperator where
1248+ toJSON And = String "and"
1249+ toJSON Or = String "or"
1250+
1251+instance FromJSON BooleanOperator where
1252+ parseJSON = withText "BooleanOperator" parse
1253+ where parse "and" = pure And
1254+ parse "or" = pure Or
1255+ parse o = fail ("Unexpected BooleanOperator: " <> show o)
1256+
1257+instance ToJSON ZeroTermsQuery where
1258+ toJSON ZeroTermsNone = String "none"
1259+ toJSON ZeroTermsAll = String "all"
1260+
1261+instance FromJSON ZeroTermsQuery where
1262+ parseJSON = withText "ZeroTermsQuery" parse
1263+ where parse "none" = pure ZeroTermsNone
1264+ parse "all" = pure ZeroTermsAll
1265+ parse q = fail ("Unexpected ZeroTermsQuery: " <> show q)
1266+
1267+instance ToJSON MatchQueryType where
1268+ toJSON MatchPhrase = "phrase"
1269+ toJSON MatchPhrasePrefix = "phrase_prefix"
1270+
1271+instance FromJSON MatchQueryType where
1272+ parseJSON = withText "MatchQueryType" parse
1273+ where parse "phrase" = pure MatchPhrase
1274+ parse "phrase_prefix" = pure MatchPhrasePrefix
1275+ parse t = fail ("Unexpected MatchQueryType: " <> show t)
1276+
1277+instance ToJSON ScoreType where
1278+ toJSON ScoreTypeMax = "max"
1279+ toJSON ScoreTypeAvg = "avg"
1280+ toJSON ScoreTypeSum = "sum"
1281+ toJSON ScoreTypeNone = "none"
1282+
1283+instance FromJSON ScoreType where
1284+ parseJSON = withText "ScoreType" parse
1285+ where parse "max" = pure ScoreTypeMax
1286+ parse "avg" = pure ScoreTypeAvg
1287+ parse "sum" = pure ScoreTypeSum
1288+ parse "none" = pure ScoreTypeNone
1289+ parse t = fail ("Unexpected ScoreType: " <> show t)
1290+
1291+instance ToJSON Distance where
1292+ toJSON (Distance dCoefficient dUnit) =
1293+ String boltedTogether where
1294+ coefText = showText dCoefficient
1295+ (String unitText) = toJSON dUnit
1296+ boltedTogether = mappend coefText unitText
1297+
1298+instance FromJSON Distance where
1299+ parseJSON = withText "Distance" parse
1300+ where parse t = Distance <$> parseCoeff nT
1301+ <*> parseJSON (String unitT)
1302+ where (nT, unitT) = T.span validForNumber t
1303+ -- may be a better way to do this
1304+ validForNumber '-' = True
1305+ validForNumber '.' = True
1306+ validForNumber 'e' = True
1307+ validForNumber c = isNumber c
1308+ parseCoeff "" = fail "Empty string cannot be parsed as number"
1309+ parseCoeff s = return (read (T.unpack s))
1310+
1311+instance ToJSON DistanceUnit where
1312+ toJSON Miles = String "mi"
1313+ toJSON Yards = String "yd"
1314+ toJSON Feet = String "ft"
1315+ toJSON Inches = String "in"
1316+ toJSON Kilometers = String "km"
1317+ toJSON Meters = String "m"
1318+ toJSON Centimeters = String "cm"
1319+ toJSON Millimeters = String "mm"
1320+ toJSON NauticalMiles = String "nmi"
1321+
1322+
1323+instance FromJSON DistanceUnit where
1324+ parseJSON = withText "DistanceUnit" parse
1325+ where parse "mi" = pure Miles
1326+ parse "yd" = pure Yards
1327+ parse "ft" = pure Feet
1328+ parse "in" = pure Inches
1329+ parse "km" = pure Kilometers
1330+ parse "m" = pure Meters
1331+ parse "cm" = pure Centimeters
1332+ parse "mm" = pure Millimeters
1333+ parse "nmi" = pure NauticalMiles
1334+ parse u = fail ("Unrecognized DistanceUnit: " <> show u)
1335+
1336+instance ToJSON DistanceType where
1337+ toJSON Arc = String "arc"
1338+ toJSON SloppyArc = String "sloppy_arc"
1339+ toJSON Plane = String "plane"
1340+
1341+instance FromJSON DistanceType where
1342+ parseJSON = withText "DistanceType" parse
1343+ where parse "arc" = pure Arc
1344+ parse "sloppy_arc" = pure SloppyArc
1345+ parse "plane" = pure Plane
1346+ parse t = fail ("Unrecognized DistanceType: " <> show t)
1347+
1348+
1349+instance ToJSON OptimizeBbox where
1350+ toJSON NoOptimizeBbox = String "none"
1351+ toJSON (OptimizeGeoFilterType gft) = toJSON gft
1352+
1353+instance FromJSON OptimizeBbox where
1354+ parseJSON v = withText "NoOptimizeBbox" parseNoOptimize v
1355+ <|> parseOptimize v
1356+ where parseNoOptimize "none" = pure NoOptimizeBbox
1357+ parseNoOptimize _ = mzero
1358+ parseOptimize = fmap OptimizeGeoFilterType . parseJSON
1359+
1360+instance ToJSON GeoBoundingBoxConstraint where
1361+ toJSON (GeoBoundingBoxConstraint
1362+ (FieldName gbbcGeoBBField) gbbcConstraintBox cache type') =
1363+ object [gbbcGeoBBField .= gbbcConstraintBox
1364+ , "_cache" .= cache
1365+ , "type" .= type']
1366+
1367+deleteSeveral :: (Eq k, Hashable k) => [k] -> HM.HashMap k v -> HM.HashMap k v
1368+deleteSeveral ks hm = foldr HM.delete hm ks
1369+
1370+instance FromJSON GeoBoundingBoxConstraint where
1371+ parseJSON = withObject "GeoBoundingBoxConstraint" parse
1372+ where parse o = case HM.toList (deleteSeveral ["type", "_cache"] o) of
1373+ [(fn, v)] -> GeoBoundingBoxConstraint (FieldName fn)
1374+ <$> parseJSON v
1375+ <*> o .:? "_cache" .!= defaultCache
1376+ <*> o .: "type"
1377+ _ -> fail "Could not find field name for GeoBoundingBoxConstraint"
1378+
1379+instance ToJSON GeoFilterType where
1380+ toJSON GeoFilterMemory = String "memory"
1381+ toJSON GeoFilterIndexed = String "indexed"
1382+
1383+instance FromJSON GeoFilterType where
1384+ parseJSON = withText "GeoFilterType" parse
1385+ where parse "memory" = pure GeoFilterMemory
1386+ parse "indexed" = pure GeoFilterIndexed
1387+ parse t = fail ("Unrecognized GeoFilterType: " <> show t)
1388+
1389+instance ToJSON GeoBoundingBox where
1390+ toJSON (GeoBoundingBox gbbTopLeft gbbBottomRight) =
1391+ object ["top_left" .= gbbTopLeft
1392+ , "bottom_right" .= gbbBottomRight]
1393+
1394+instance FromJSON GeoBoundingBox where
1395+ parseJSON = withObject "GeoBoundingBox" parse
1396+ where parse o = GeoBoundingBox
1397+ <$> o .: "top_left"
1398+ <*> o .: "bottom_right"
1399+
1400+instance ToJSON LatLon where
1401+ toJSON (LatLon lLat lLon) =
1402+ object ["lat" .= lLat
1403+ , "lon" .= lLon]
1404+
1405+instance FromJSON LatLon where
1406+ parseJSON = withObject "LatLon" parse
1407+ where parse o = LatLon <$> o .: "lat"
1408+ <*> o .: "lon"
1409+
1410+-- index for smaller ranges, fielddata for longer ranges
1411+instance ToJSON RangeExecution where
1412+ toJSON RangeExecutionIndex = "index"
1413+ toJSON RangeExecutionFielddata = "fielddata"
1414+
1415+
1416+instance FromJSON RangeExecution where
1417+ parseJSON = withText "RangeExecution" parse
1418+ where parse "index" = pure RangeExecutionIndex
1419+ parse "fielddata" = pure RangeExecutionFielddata
1420+ parse t = error ("Unrecognized RangeExecution " <> show t)
1421+
1422+instance ToJSON RegexpFlags where
1423+ toJSON AllRegexpFlags = String "ALL"
1424+ toJSON NoRegexpFlags = String "NONE"
1425+ toJSON (SomeRegexpFlags (h :| fs)) = String $ T.intercalate "|" flagStrs
1426+ where flagStrs = map flagStr . nub $ h:fs
1427+ flagStr AnyString = "ANYSTRING"
1428+ flagStr Automaton = "AUTOMATON"
1429+ flagStr Complement = "COMPLEMENT"
1430+ flagStr Empty = "EMPTY"
1431+ flagStr Intersection = "INTERSECTION"
1432+ flagStr Interval = "INTERVAL"
1433+
1434+instance FromJSON RegexpFlags where
1435+ parseJSON = withText "RegexpFlags" parse
1436+ where parse "ALL" = pure AllRegexpFlags
1437+ parse "NONE" = pure NoRegexpFlags
1438+ parse t = SomeRegexpFlags <$> parseNEJSON (String <$> T.splitOn "|" t)
1439+
1440+instance FromJSON RegexpFlag where
1441+ parseJSON = withText "RegexpFlag" parse
1442+ where parse "ANYSTRING" = pure AnyString
1443+ parse "AUTOMATON" = pure Automaton
1444+ parse "COMPLEMENT" = pure Complement
1445+ parse "EMPTY" = pure Empty
1446+ parse "INTERSECTION" = pure Intersection
1447+ parse "INTERVAL" = pure Interval
1448+ parse f = fail ("Unknown RegexpFlag: " <> show f)
1449+
1450+instance ToJSON Term where
1451+ toJSON (Term field value) = object ["term" .= object
1452+ [field .= value]]
1453+
1454+instance FromJSON Term where
1455+ parseJSON = withObject "Term" parse
1456+ where parse o = do termObj <- o .: "term"
1457+ case HM.toList termObj of
1458+ [(fn, v)] -> Term fn <$> parseJSON v
1459+ _ -> fail "Expected object with 1 field-named key"
1460+
1461+instance ToJSON BoolMatch where
1462+ toJSON (MustMatch term cache) = object ["must" .= term,
1463+ "_cache" .= cache]
1464+ toJSON (MustNotMatch term cache) = object ["must_not" .= term,
1465+ "_cache" .= cache]
1466+ toJSON (ShouldMatch terms cache) = object ["should" .= fmap toJSON terms,
1467+ "_cache" .= cache]
1468+
1469+instance FromJSON BoolMatch where
1470+ parseJSON = withObject "BoolMatch" parse
1471+ where parse o = mustMatch `taggedWith` "must"
1472+ <|> mustNotMatch `taggedWith` "must_not"
1473+ <|> shouldMatch `taggedWith` "should"
1474+ where taggedWith parser k = parser =<< o .: k
1475+ mustMatch t = MustMatch t <$> o .:? "_cache" .!= defaultCache
1476+ mustNotMatch t = MustNotMatch t <$> o .:? "_cache" .!= defaultCache
1477+ shouldMatch t = ShouldMatch t <$> o .:? "_cache" .!= defaultCache
src/Database/V5/Bloodhound/Types/Internal/StringlyTyped.hsnew file+50
@@ -0,0 +1,50 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+
3+module Database.V5.Bloodhound.Types.Internal.StringlyTyped where
4+
5+import Control.Monad (MonadPlus(..))
6+import Data.Aeson
7+import Data.Aeson.Types ( Pair, Parser,
8+ emptyObject,
9+ parseEither, parseMaybe,
10+ typeMismatch
11+ )
12+import Data.Text (Text)
13+import qualified Data.Text as T
14+
15+import Bloodhound.Import
16+
17+-- This whole module is a sin bucket to deal with Elasticsearch badness.
18+newtype StringlyTypedDouble = StringlyTypedDouble
19+ { unStringlyTypedDouble :: Double }
20+
21+instance FromJSON StringlyTypedDouble where
22+ parseJSON =
23+ fmap StringlyTypedDouble
24+ . parseJSON
25+ . unStringlyTypeJSON
26+
27+newtype StringlyTypedInt = StringlyTypedInt
28+ { unStringlyTypedInt :: Int }
29+
30+instance FromJSON StringlyTypedInt where
31+ parseJSON =
32+ fmap StringlyTypedInt
33+ . parseJSON
34+ . unStringlyTypeJSON
35+
36+-- | For some reason in several settings APIs, all leaf values get returned
37+-- as strings. This function attepmts to recover from this for all
38+-- non-recursive JSON types. If nothing can be done, the value is left alone.
39+unStringlyTypeJSON :: Value -> Value
40+unStringlyTypeJSON (String "true") =
41+ Bool True
42+unStringlyTypeJSON (String "false") =
43+ Bool False
44+unStringlyTypeJSON (String "null") =
45+ Null
46+unStringlyTypeJSON v@(String t) =
47+ case readMay (T.unpack t) of
48+ Just n -> Number n
49+ Nothing -> v
50+unStringlyTypeJSON v = v
tests/V5/tests.hs+4−4
@@ -44,7 +44,7 @@ import Data.Typeable
44import qualified Data.Vector as V
44import qualified Data.Vector as V
45import qualified Data.Version as Vers
45import qualified Data.Version as Vers
46import Database.V5.Bloodhound
46import Database.V5.Bloodhound
47−import GHC.Generics as G
47+-- import GHC.Generics as G
48import Network.HTTP.Client hiding (Proxy)
48import Network.HTTP.Client hiding (Proxy)
49import qualified Network.HTTP.Types.Method as NHTM
49import qualified Network.HTTP.Types.Method as NHTM
50import qualified Network.HTTP.Types.Status as NHTS
50import qualified Network.HTTP.Types.Status as NHTS
@@ -164,7 +164,7 @@ propJSON _ = prop testName $ \(a :: a) ->
164 ty = typeOf (undefined :: a)
164 ty = typeOf (undefined :: a)
165
165
166data Location = Location { lat :: Double
166data Location = Location { lat :: Double
167− , lon :: Double } deriving (Eq, Generic, Show)
167+ , lon :: Double } deriving (Eq, Show)
168
168
169data Tweet = Tweet { user :: Text
169data Tweet = Tweet { user :: Text
170 , postDate :: UTCTime
170 , postDate :: UTCTime
@@ -172,7 +172,7 @@ data Tweet = Tweet { user :: Text
172 , age :: Int
172 , age :: Int
173 , location :: Location
173 , location :: Location
174 , extra :: Maybe Text }
174 , extra :: Maybe Text }
175− deriving (Eq, Generic, Show)
175+ deriving (Eq, Show)
176
176
177instance ToJSON Tweet where
177instance ToJSON Tweet where
178 toJSON = genericToJSON defaultOptions
178 toJSON = genericToJSON defaultOptions
@@ -433,7 +433,7 @@ withSnapshot srn sn = bracket_ alloc free
433
433
434
434
435
435
436−data BulkTest = BulkTest { name :: Text } deriving (Eq, Generic, Show)
436+data BulkTest = BulkTest { name :: Text } deriving (Eq, Show)
437instance FromJSON BulkTest where
437instance FromJSON BulkTest where
438 parseJSON = genericParseJSON defaultOptions
438 parseJSON = genericParseJSON defaultOptions
439instance ToJSON BulkTest where
439instance ToJSON BulkTest where