git.iko.soy/typeable/bloodhound
on es-2-canary help sign in
5222 lines 225 kB history raw
1{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE DeriveGeneric #-}
3{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE GeneralizedNewtypeDeriving #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
7-- {-# LANGUAGE NoMonomorphismRestriction #-}
8{-# LANGUAGE NamedFieldPuns #-}
9{-# LANGUAGE OverloadedStrings #-}
10{-# LANGUAGE RecordWildCards #-}
11{-# LANGUAGE UndecidableInstances #-}
13-------------------------------------------------------------------------------
14-- |
15-- Module : Database.Bloodhound.Types
16-- Copyright : (C) 2014, 2015, 2016 Chris Allen
17-- License : BSD-style (see the file LICENSE)
18-- Maintainer : Chris Allen <cma@bitemyapp.com
19-- Stability : provisional
20-- Portability : DeriveGeneric, RecordWildCards
21--
22-- Data types for describing actions and data structures performed to interact
23-- with Elasticsearch. The two main buckets your queries against Elasticsearch
24-- will fall into are 'Query's and 'Filter's. 'Filter's are more like
25-- traditional database constraints and often have preferable performance
26-- properties. 'Query's support human-written textual queries, such as fuzzy
27-- queries.
28-------------------------------------------------------------------------------
32module Database.Bloodhound.Types
33 ( defaultCache
34 , defaultIndexSettings
35 , defaultIndexDocumentSettings
36 , mkSort
37 , showText
38 , unpackId
39 , mkMatchQuery
40 , mkMultiMatchQuery
41 , mkBoolQuery
42 , mkRangeQuery
43 , mkQueryStringQuery
44 , mkAggregations
45 , mkTermsAggregation
46 , mkTermsScriptAggregation
47 , mkDateHistogram
48 , mkCardinalityAggregation
49 , mkDocVersion
50 , docVersionNumber
51 , toMissing
52 , toTerms
53 , toDateHistogram
54 , omitNulls
55 , BH(..)
56 , runBH
57 , BHEnv
58 , bhServer
59 , bhManager
60 , bhRequestHook
61 , mkBHEnv
62 , MonadBH(..)
63 , Version(..)
64 , VersionNumber(..)
65 , MaybeNA(..)
66 , BuildHash(..)
67 , Status(..)
68 , Existence(..)
69 , NullValue(..)
70 , IndexSettings(..)
71 , UpdatableIndexSetting(..)
72 , IndexSettingsSummary(..)
73 , AllocationPolicy(..)
74 , ReplicaBounds(..)
75 , Bytes(..)
76 , gigabytes
77 , megabytes
78 , kilobytes
79 , FSType(..)
80 , InitialShardCount(..)
81 , NodeAttrFilter(..)
82 , NodeAttrName(..)
83 , CompoundFormat(..)
84 , IndexTemplate(..)
85 , Server(..)
86 , Reply
87 , EsResult(..)
88 , EsResultFound(..)
89 , EsError(..)
90 , EsProtocolException(..)
91 , IndexAlias(..)
92 , IndexAliasName(..)
93 , IndexAliasAction(..)
94 , IndexAliasCreate(..)
95 , IndexAliasSummary(..)
96 , IndexAliasesSummary(..)
97 , AliasRouting(..)
98 , SearchAliasRouting(..)
99 , IndexAliasRouting(..)
100 , RoutingValue(..)
101 , DocVersion
102 , ExternalDocVersion(..)
103 , VersionControl(..)
104 , DocumentParent(..)
105 , IndexDocumentSettings(..)
106 , Query(..)
107 , Search(..)
108 , SearchType(..)
109 , SearchResult(..)
110 , ScrollId(..)
111 , SearchHits(..)
112 , TrackSortScores
113 , From(..)
114 , Size(..)
115 , Source(..)
116 , PatternOrPatterns(..)
117 , Include(..)
118 , Exclude(..)
119 , Pattern(..)
120 , ShardResult(..)
121 , Hit(..)
122 , Filter(..)
123 , Seminearring(..)
124 , BoolMatch(..)
125 , Term(..)
126 , GeoPoint(..)
127 , GeoBoundingBoxConstraint(..)
128 , GeoBoundingBox(..)
129 , GeoFilterType(..)
130 , Distance(..)
131 , DistanceUnit(..)
132 , DistanceType(..)
133 , DistanceRange(..)
134 , OptimizeBbox(..)
135 , LatLon(..)
136 , RangeValue(..)
137 , RangeExecution(..)
138 , LessThan(..)
139 , LessThanEq(..)
140 , GreaterThan(..)
141 , GreaterThanEq(..)
142 , LessThanD(..)
143 , LessThanEqD(..)
144 , GreaterThanD(..)
145 , GreaterThanEqD(..)
146 , Regexp(..)
147 , RegexpFlags(..)
148 , RegexpFlag(..)
149 , FieldName(..)
150 , Script(..)
151 , IndexName(..)
152 , IndexSelection(..)
153 , NodeSelection(..)
154 , NodeSelector(..)
155 , IndexOptimizationSettings(..)
156 , defaultIndexOptimizationSettings
157 , TemplateName(..)
158 , TemplatePattern(..)
159 , MappingName(..)
160 , DocId(..)
161 , CacheName(..)
162 , CacheKey(..)
163 , BulkOperation(..)
164 , ReplicaCount(..)
165 , ShardCount(..)
166 , Sort
167 , SortMode(..)
168 , SortOrder(..)
169 , SortSpec(..)
170 , DefaultSort(..)
171 , Missing(..)
172 , OpenCloseIndex(..)
173 , Method
174 , Boost(..)
175 , MatchQuery(..)
176 , MultiMatchQuery(..)
177 , BoolQuery(..)
178 , BoostingQuery(..)
179 , CommonTermsQuery(..)
180 , DisMaxQuery(..)
181 , FilteredQuery(..)
182 , FuzzyLikeThisQuery(..)
183 , FuzzyLikeFieldQuery(..)
184 , FuzzyQuery(..)
185 , HasChildQuery(..)
186 , HasParentQuery(..)
187 , IndicesQuery(..)
188 , MoreLikeThisQuery(..)
189 , MoreLikeThisFieldQuery(..)
190 , NestedQuery(..)
191 , PrefixQuery(..)
192 , QueryStringQuery(..)
193 , SimpleQueryStringQuery(..)
194 , RangeQuery(..)
195 , RegexpQuery(..)
196 , QueryString(..)
197 , BooleanOperator(..)
198 , ZeroTermsQuery(..)
199 , CutoffFrequency(..)
200 , Analyzer(..)
201 , MaxExpansions(..)
202 , Lenient(..)
203 , MatchQueryType(..)
204 , MultiMatchQueryType(..)
205 , Tiebreaker(..)
206 , MinimumMatch(..)
207 , DisableCoord(..)
208 , CommonMinimumMatch(..)
209 , MinimumMatchHighLow(..)
210 , PrefixLength(..)
211 , Fuzziness(..)
212 , IgnoreTermFrequency(..)
213 , MaxQueryTerms(..)
214 , ScoreType(..)
215 , Score
216 , Cache
217 , TypeName(..)
218 , BoostTerms(..)
219 , MaxWordLength(..)
220 , MinWordLength(..)
221 , MaxDocFrequency(..)
222 , MinDocFrequency(..)
223 , PhraseSlop(..)
224 , StopWord(..)
225 , QueryPath(..)
226 , MinimumTermFrequency(..)
227 , PercentMatch(..)
228 , FieldDefinition(..)
229 , MappingField(..)
230 , Mapping(..)
231 , AllowLeadingWildcard(..)
232 , LowercaseExpanded(..)
233 , GeneratePhraseQueries(..)
234 , Locale(..)
235 , AnalyzeWildcard(..)
236 , EnablePositionIncrements(..)
237 , SimpleQueryFlag(..)
238 , FieldOrFields(..)
239 , Monoid(..)
240 , ToJSON(..)
241 , Interval(..)
242 , TimeInterval(..)
243 , ExecutionHint(..)
244 , CollectionMode(..)
245 , TermOrder(..)
246 , TermInclusion(..)
247 , SnapshotRepoSelection(..)
248 , GenericSnapshotRepo(..)
249 , SnapshotRepo(..)
250 , SnapshotRepoConversionError(..)
251 , SnapshotRepoType(..)
252 , GenericSnapshotRepoSettings(..)
253 , SnapshotRepoUpdateSettings(..)
254 , defaultSnapshotRepoUpdateSettings
255 , SnapshotRepoName(..)
256 , SnapshotRepoPattern(..)
257 , SnapshotVerification(..)
258 , SnapshotNodeVerification(..)
259 , FullNodeId(..)
260 , NodeName(..)
261 , ClusterName(..)
262 , NodesInfo(..)
263 , NodesStats(..)
264 , NodeStats(..)
265 , NodeBreakersStats(..)
266 , NodeBreakerStats(..)
267 , NodeHTTPStats(..)
268 , NodeTransportStats(..)
269 , NodeFSStats(..)
270 , NodeDataPathStats(..)
271 , NodeFSTotalStats(..)
272 , NodeNetworkStats(..)
273 , NodeThreadPoolsStats(..)
274 , NodeThreadPoolStats(..)
275 , NodeJVMStats(..)
276 , JVMBufferPoolStats(..)
277 , JVMGCStats(..)
278 , JVMPoolStats(..)
279 , NodeProcessStats(..)
280 , NodeOSStats(..)
281 , LoadAvgs(..)
282 , NodeIndicesStats(..)
283 , EsAddress(..)
284 , PluginName(..)
285 , NodeInfo(..)
286 , NodePluginInfo(..)
287 , NodeHTTPInfo(..)
288 , NodeTransportInfo(..)
289 , BoundTransportAddress(..)
290 , NodeNetworkInfo(..)
291 , MacAddress(..)
292 , NetworkInterfaceName(..)
293 , NodeNetworkInterface(..)
294 , NodeThreadPoolsInfo(..)
295 , NodeThreadPoolInfo(..)
296 , ThreadPoolSize(..)
297 , ThreadPoolType(..)
298 , NodeJVMInfo(..)
299 , JVMMemoryPool(..)
300 , JVMGCCollector(..)
301 , JVMMemoryInfo(..)
302 , PID(..)
303 , NodeOSInfo(..)
304 , CPUInfo(..)
305 , NodeProcessInfo(..)
306 , FsSnapshotRepo(..)
307 , SnapshotCreateSettings(..)
308 , defaultSnapshotCreateSettings
309 , SnapshotSelection(..)
310 , SnapshotPattern(..)
311 , SnapshotInfo(..)
312 , SnapshotShardFailure(..)
313 , ShardId(..)
314 , SnapshotName(..)
315 , SnapshotState(..)
316 , SnapshotRestoreSettings(..)
317 , defaultSnapshotRestoreSettings
318 , RestoreRenamePattern(..)
319 , RestoreRenameToken(..)
320 , RRGroupRefNum
321 , rrGroupRefNum
322 , mkRRGroupRefNum
323 , RestoreIndexSettings(..)
325 , Aggregation(..)
326 , Aggregations
327 , AggregationResults
328 , BucketValue(..)
329 , Bucket(..)
330 , BucketAggregation(..)
331 , TermsAggregation(..)
332 , MissingAggregation(..)
333 , ValueCountAggregation(..)
334 , FilterAggregation(..)
335 , CardinalityAggregation(..)
336 , DateHistogramAggregation(..)
337 , DateRangeAggregation(..)
338 , DateRangeAggRange(..)
339 , DateMathExpr(..)
340 , DateMathAnchor(..)
341 , DateMathModifier(..)
342 , DateMathUnit(..)
344 , Highlights(..)
345 , FieldHighlight(..)
346 , HighlightSettings(..)
347 , PlainHighlight(..)
348 , PostingsHighlight(..)
349 , FastVectorHighlight(..)
350 , CommonHighlight(..)
351 , NonPostings(..)
352 , HighlightEncoder(..)
353 , HighlightTag(..)
354 , HitHighlight
356 , MissingResult(..)
357 , TermsResult(..)
358 , DateHistogramResult(..)
359 , DateRangeResult(..)
361 , EsUsername(..)
362 , EsPassword(..)
363 ) where
365import Control.Applicative as A
366import Control.Arrow (first)
367import Control.Monad.Catch
368import Control.Monad.Except
369import Control.Monad.Reader
370import Control.Monad.State
371import Control.Monad.Writer
372import Data.Aeson
373import Data.Aeson.Types (Pair, Parser, emptyObject,
374 parseEither, parseMaybe)
375import qualified Data.ByteString.Lazy.Char8 as L
376import Data.Char
377import Data.Hashable (Hashable)
378import qualified Data.HashMap.Strict as HM
379import Data.List (foldl', intercalate, nub)
380import Data.List.NonEmpty (NonEmpty (..), toList)
381import qualified Data.Map.Strict as M
382import Data.Maybe
383import Data.Scientific (Scientific)
384import Data.Text (Text)
385import qualified Data.Text as T
386import Data.Time.Calendar
387import Data.Time.Clock (NominalDiffTime, UTCTime)
388import Data.Time.Clock.POSIX
389import qualified Data.Traversable as DT
390import Data.Typeable (Typeable)
391import qualified Data.Vector as V
392import qualified Data.Version as Vers
393import GHC.Enum
394import GHC.Generics (Generic)
395import Network.HTTP.Client
396import qualified Network.HTTP.Types.Method as NHTM
397import qualified Text.ParserCombinators.ReadP as RP
398import qualified Text.Read as TR
400import Database.Bloodhound.Types.Class
401import Database.Bloodhound.Types.Internal
403-- $setup
404-- >>> :set -XOverloadedStrings
405-- >>> import Data.Aeson
406-- >>> import Database.Bloodhound
407-- >>> let testServer = (Server "http://localhost:9200")
408-- >>> let testIndex = IndexName "twitter"
409-- >>> let testMapping = MappingName "tweet"
410-- >>> let defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
412-- defaultIndexSettings is exported by Database.Bloodhound as well
413-- no trailing slashes in servers, library handles building the path.
415-- | Create a 'BHEnv' with all optional fields defaulted. HTTP hook
416-- will be a noop. You can use the exported fields to customize it further, e.g.:
417--
418-- >> (mkBHEnv myServer myManager) { bhRequestHook = customHook }
419mkBHEnv :: Server -> Manager -> BHEnv
420mkBHEnv s m = BHEnv s m return
422newtype BH m a = BH {
423 unBH :: ReaderT BHEnv m a
424 } deriving ( Functor
425 , A.Applicative
426 , Monad
427 , MonadIO
428 , MonadState s
429 , MonadWriter w
430 , MonadError e
431 , Alternative
432 , MonadPlus
433 , MonadFix
434 , MonadThrow
435 , MonadCatch
436 , MonadMask)
438instance MonadTrans BH where
439 lift = BH . lift
441instance (MonadReader r m) => MonadReader r (BH m) where
442 ask = lift ask
443 local f (BH (ReaderT m)) = BH $ ReaderT $ \r ->
444 local f (m r)
446instance (Functor m, Applicative m, MonadIO m) => MonadBH (BH m) where
447 getBHEnv = BH getBHEnv
449runBH :: BHEnv -> BH m a -> m a
450runBH e f = runReaderT (unBH f) e
452{-| 'Version' is embedded in 'Status' -}
453data Version = Version { number :: VersionNumber
454 , build_hash :: BuildHash
455 , build_timestamp :: UTCTime
456 , build_snapshot :: Bool
457 , lucene_version :: VersionNumber } deriving (Eq, Read, Show, Generic, Typeable)
459-- | Traditional software versioning number
460newtype VersionNumber = VersionNumber { versionNumber :: Vers.Version
461 } deriving (Eq, Read, Show, Generic, Typeable, Ord)
463{-| 'Status' is a data type for describing the JSON body returned by
464 Elasticsearch when you query its status. This was deprecated in 1.2.0.
466 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-status.html#indices-status>
467-}
469data Status = Status { ok :: Maybe Bool
470 , status :: Int
471 , name :: Text
472 , version :: Version
473 , tagline :: Text } deriving (Eq, Read, Show, Generic)
475{-| 'IndexSettings' is used to configure the shards and replicas when you create
476 an Elasticsearch Index.
478 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html>
479-}
481data IndexSettings =
482 IndexSettings { indexShards :: ShardCount
483 , indexReplicas :: ReplicaCount } deriving (Eq, Read, Show, Generic, Typeable)
485{-| 'defaultIndexSettings' is an 'IndexSettings' with 3 shards and 2 replicas. -}
486defaultIndexSettings :: IndexSettings
487defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
490{-| 'IndexOptimizationSettings' is used to configure index optimization. See
491 <https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-optimize.html>
492 for more info.
493-}
494data IndexOptimizationSettings =
495 IndexOptimizationSettings { maxNumSegments :: Maybe Int
496 -- ^ 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.
497 , onlyExpungeDeletes :: Bool
498 -- ^ 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.
499 , flushAfterOptimize :: Bool
500 -- ^ Should a flush be performed after the optimize.
501 } deriving (Eq, Show, Generic, Typeable)
504{-| 'defaultIndexOptimizationSettings' implements the default settings that
505 ElasticSearch uses for index optimization. 'maxNumSegments' is Nothing,
506 'onlyExpungeDeletes' is False, and flushAfterOptimize is True.
507-}
508defaultIndexOptimizationSettings :: IndexOptimizationSettings
509defaultIndexOptimizationSettings = IndexOptimizationSettings Nothing False True
511{-| 'UpdatableIndexSetting' are settings which may be updated after an index is created.
513 <https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html>
514-}
515data UpdatableIndexSetting = NumberOfReplicas ReplicaCount
516 -- ^ The number of replicas each shard has.
517 | AutoExpandReplicas ReplicaBounds
518 | BlocksReadOnly Bool
519 -- ^ Set to True to have the index read only. False to allow writes and metadata changes.
520 | BlocksRead Bool
521 -- ^ Set to True to disable read operations against the index.
522 | BlocksWrite Bool
523 -- ^ Set to True to disable write operations against the index.
524 | BlocksMetaData Bool
525 -- ^ Set to True to disable metadata operations against the index.
526 | RefreshInterval NominalDiffTime
527 -- ^ The async refresh interval of a shard
528 | IndexConcurrency Int
529 | FailOnMergeFailure Bool
530 | TranslogFlushThresholdOps Int
531 -- ^ When to flush on operations.
532 | TranslogFlushThresholdSize Bytes
533 -- ^ When to flush based on translog (bytes) size.
534 | TranslogFlushThresholdPeriod NominalDiffTime
535 -- ^ When to flush based on a period of not flushing.
536 | TranslogDisableFlush Bool
537 -- ^ Disables flushing. Note, should be set for a short interval and then enabled.
538 | CacheFilterMaxSize (Maybe Bytes)
539 -- ^ The maximum size of filter cache (per segment in shard).
540 | CacheFilterExpire (Maybe NominalDiffTime)
541 -- ^ The expire after access time for filter cache.
542 | GatewaySnapshotInterval NominalDiffTime
543 -- ^ The gateway snapshot interval (only applies to shared gateways).
544 | RoutingAllocationInclude (NonEmpty NodeAttrFilter)
545 -- ^ A node matching any rule will be allowed to host shards from the index.
546 | RoutingAllocationExclude (NonEmpty NodeAttrFilter)
547 -- ^ A node matching any rule will NOT be allowed to host shards from the index.
548 | RoutingAllocationRequire (NonEmpty NodeAttrFilter)
549 -- ^ Only nodes matching all rules will be allowed to host shards from the index.
550 | RoutingAllocationEnable AllocationPolicy
551 -- ^ Enables shard allocation for a specific index.
552 | RoutingAllocationShardsPerNode ShardCount
553 -- ^ Controls the total number of shards (replicas and primaries) allowed to be allocated on a single node.
554 | RecoveryInitialShards InitialShardCount
555 -- ^ When using local gateway a particular shard is recovered only if there can be allocated quorum shards in the cluster.
556 | GCDeletes NominalDiffTime
557 | TTLDisablePurge Bool
558 -- ^ Disables temporarily the purge of expired docs.
559 | TranslogFSType FSType
560 | IndexCompoundFormat CompoundFormat
561 | IndexCompoundOnFlush Bool
562 | WarmerEnabled Bool
563 deriving (Eq, Show, Generic, Typeable)
565data AllocationPolicy = AllocAll
566 -- ^ Allows shard allocation for all shards.
567 | AllocPrimaries
568 -- ^ Allows shard allocation only for primary shards.
569 | AllocNewPrimaries
570 -- ^ Allows shard allocation only for primary shards for new indices.
571 | AllocNone
572 -- ^ No shard allocation is allowed
573 deriving (Eq, Read, Show, Generic, Typeable)
575data ReplicaBounds = ReplicasBounded Int Int
576 | ReplicasLowerBounded Int
577 | ReplicasUnbounded
578 deriving (Eq, Read, Show, Generic, Typeable)
580-- | A measure of bytes used for various configurations. You may want
581-- to use smart constructors like 'gigabytes' for larger values.
582--
583-- >>> gigabytes 9
584-- Bytes 9000000000
585--
586-- >>> megabytes 9
587-- Bytes 9000000
588--
589-- >>> kilobytes 9
590-- Bytes 9000
591newtype Bytes = Bytes Int deriving (Eq, Read, Show, Generic, Typeable, Ord, ToJSON, FromJSON)
593gigabytes :: Int -> Bytes
594gigabytes n = megabytes (1000 * n)
597megabytes :: Int -> Bytes
598megabytes n = kilobytes (1000 * n)
601kilobytes :: Int -> Bytes
602kilobytes n = Bytes (1000 * n)
605data FSType = FSSimple
606 | FSBuffered deriving (Eq, Read, Show, Generic, Typeable, Ord)
608data InitialShardCount = QuorumShards
609 | QuorumMinus1Shards
610 | FullShards
611 | FullMinus1Shards
612 | ExplicitShards Int
613 deriving (Eq, Read, Show, Generic, Typeable)
615data NodeAttrFilter = NodeAttrFilter { nodeAttrFilterName :: NodeAttrName
616 , nodeAttrFilterValues :: NonEmpty Text}
617 deriving (Eq, Read, Show, Generic, Ord, Typeable)
619newtype NodeAttrName = NodeAttrName Text deriving (Eq, Read, Show, Ord, Generic, Typeable)
621data CompoundFormat = CompoundFileFormat Bool
622 | MergeSegmentVsTotalIndex Double
623 -- ^ percentage between 0 and 1 where 0 is false, 1 is true
624 deriving (Eq, Read, Show, Generic, Typeable)
626newtype NominalDiffTimeJSON = NominalDiffTimeJSON { ndtJSON :: NominalDiffTime }
628data IndexSettingsSummary = IndexSettingsSummary { sSummaryIndexName :: IndexName
629 , sSummaryFixedSettings :: IndexSettings
630 , sSummaryUpdateable :: [UpdatableIndexSetting]}
631 deriving (Eq, Show, Generic, Typeable)
633{-| 'Reply' and 'Method' are type synonyms from 'Network.HTTP.Types.Method.Method' -}
634type Reply = Network.HTTP.Client.Response L.ByteString
635type Method = NHTM.Method
637{-| 'OpenCloseIndex' is a sum type for opening and closing indices.
639 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-open-close.html>
640-}
641data OpenCloseIndex = OpenIndex | CloseIndex deriving (Eq, Read, Show, Generic, Typeable)
643data FieldType = GeoPointType
644 | GeoShapeType
645 | FloatType
646 | IntegerType
647 | LongType
648 | ShortType
649 | ByteType deriving (Eq, Read, Show, Generic, Typeable)
651data FieldDefinition =
652 FieldDefinition { fieldType :: FieldType } deriving (Eq, Read, Show, Generic, Typeable)
654{-| An 'IndexTemplate' defines a template that will automatically be
655 applied to new indices created. The templates include both
656 'IndexSettings' and mappings, and a simple 'TemplatePattern' that
657 controls if the template will be applied to the index created.
658 Specify mappings as follows: @[toJSON TweetMapping, ...]@
660 https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-templates.html
661-}
662data IndexTemplate =
663 IndexTemplate { templatePattern :: TemplatePattern
664 , templateSettings :: Maybe IndexSettings
665 , templateMappings :: [Value]
666 }
668data MappingField =
669 MappingField { mappingFieldName :: FieldName
670 , fieldDefinition :: FieldDefinition } deriving (Eq, Read, Show, Generic, Typeable)
672{-| Support for type reification of 'Mapping's is currently incomplete, for
673 now the mapping API verbiage expects a 'ToJSON'able blob.
675 Indexes have mappings, mappings are schemas for the documents contained in the
676 index. I'd recommend having only one mapping per index, always having a mapping,
677 and keeping different kinds of documents separated if possible.
678-}
679data Mapping = Mapping { typeName :: TypeName
680 , mappingFields :: [MappingField] } deriving (Eq, Read, Show, Generic, Typeable)
682{-| 'BulkOperation' is a sum type for expressing the four kinds of bulk
683 operation index, create, delete, and update. 'BulkIndex' behaves like an
684 "upsert", 'BulkCreate' will fail if a document already exists at the DocId.
686 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-bulk.html#docs-bulk>
687-}
688data BulkOperation =
689 BulkIndex IndexName MappingName DocId Value
690 | BulkCreate IndexName MappingName DocId Value
691 | BulkDelete IndexName MappingName DocId
692 | BulkUpdate IndexName MappingName DocId Value deriving (Eq, Read, Show, Generic, Typeable)
694{-| 'EsResult' describes the standard wrapper JSON document that you see in
695 successful Elasticsearch lookups or lookups that couldn't find the document.
696-}
697data EsResult a = EsResult { _index :: Text
698 , _type :: Text
699 , _id :: Text
700 , foundResult :: Maybe (EsResultFound a)} deriving (Eq, Read, Show, Generic, Typeable)
702{-| 'EsResultFound' contains the document and its metadata inside of an
703 'EsResult' when the document was successfully found.
704-}
705data EsResultFound a = EsResultFound { _version :: DocVersion
706 , _source :: a } deriving (Eq, Read, Show, Generic, Typeable)
708{-| 'EsError' is the generic type that will be returned when there was a
709 problem. If you can't parse the expected response, its a good idea to
710 try parsing this.
711-}
712data EsError = EsError { errorStatus :: Int
713 , errorMessage :: Text } deriving (Eq, Read, Show, Generic, Typeable)
715{-| 'EsProtocolException' will be thrown if Bloodhound cannot parse a response
716returned by the ElasticSearch server. If you encounter this error, please
717verify that your domain data types and FromJSON instances are working properly
718(for example, the 'a' of '[Hit a]' in 'SearchResult.searchHits.hits'). If you're
719sure that your mappings are correct, then this error may be an indication of an
720incompatibility between Bloodhound and ElasticSearch. Please open a bug report
721and be sure to include the exception body.
722-}
723data EsProtocolException = EsProtocolException { esProtoExBody :: L.ByteString }
724 deriving (Eq, Read, Show, Generic, Typeable)
726instance Exception EsProtocolException
728data IndexAlias = IndexAlias { srcIndex :: IndexName
729 , indexAlias :: IndexAliasName } deriving (Eq, Read, Show, Generic, Typeable)
731newtype IndexAliasName = IndexAliasName { indexAliasName :: IndexName } deriving (Eq, Read, Show, Generic, ToJSON)
733data IndexAliasAction = AddAlias IndexAlias IndexAliasCreate
734 | RemoveAlias IndexAlias deriving (Read, Show, Eq, Generic, Typeable)
736data IndexAliasCreate = IndexAliasCreate { aliasCreateRouting :: Maybe AliasRouting
737 , aliasCreateFilter :: Maybe Filter}
738 deriving (Read, Show, Eq, Generic, Typeable)
740data AliasRouting = AllAliasRouting RoutingValue
741 | GranularAliasRouting (Maybe SearchAliasRouting) (Maybe IndexAliasRouting)
742 deriving (Read, Show, Eq, Generic, Typeable)
744newtype SearchAliasRouting = SearchAliasRouting (NonEmpty RoutingValue) deriving (Read, Show, Eq, Generic, Typeable)
746newtype IndexAliasRouting = IndexAliasRouting RoutingValue deriving (Read, Show, Eq, Generic, ToJSON, FromJSON, Typeable)
748newtype RoutingValue = RoutingValue { routingValue :: Text } deriving (Read, Show, Eq, Generic, ToJSON, FromJSON, Typeable)
750newtype IndexAliasesSummary = IndexAliasesSummary { indexAliasesSummary :: [IndexAliasSummary] } deriving (Read, Show, Eq, Generic, Typeable)
752{-| 'IndexAliasSummary' is a summary of an index alias configured for a server. -}
753data IndexAliasSummary = IndexAliasSummary { indexAliasSummaryAlias :: IndexAlias
754 , indexAliasSummaryCreate :: IndexAliasCreate} deriving (Read, Show, Eq, Generic, Typeable)
756{-| 'DocVersion' is an integer version number for a document between 1
757and 9.2e+18 used for <<https://www.elastic.co/guide/en/elasticsearch/guide/current/optimistic-concurrency-control.html optimistic concurrency control>>.
758-}
759newtype DocVersion = DocVersion {
760 docVersionNumber :: Int
761 } deriving (Eq, Read, Show, Generic, Ord, ToJSON)
763-- | Smart constructor for in-range doc version
764mkDocVersion :: Int -> Maybe DocVersion
765mkDocVersion i
766 | i >= (docVersionNumber minBound) && i <= (docVersionNumber maxBound) =
767 Just $ DocVersion i
768 | otherwise = Nothing
771{-| 'ExternalDocVersion' is a convenience wrapper if your code uses its
772own version numbers instead of ones from ES.
773-}
774newtype ExternalDocVersion = ExternalDocVersion DocVersion
775 deriving (Eq, Read, Show, Generic, Ord, Bounded, Enum, ToJSON)
777{-| 'VersionControl' is specified when indexing documents as a
778optimistic concurrency control.
779-}
780data VersionControl = NoVersionControl
781 -- ^ Don't send a version. This is a pure overwrite.
782 | InternalVersion DocVersion
783 -- ^ Use the default ES versioning scheme. Only
784 -- index the document if the version is the same
785 -- as the one specified. Only applicable to
786 -- updates, as you should be getting Version from
787 -- a search result.
788 | ExternalGT ExternalDocVersion
789 -- ^ Use your own version numbering. Only index
790 -- the document if the version is strictly higher
791 -- OR the document doesn't exist. The given
792 -- version will be used as the new version number
793 -- for the stored document. N.B. All updates must
794 -- increment this number, meaning there is some
795 -- global, external ordering of updates.
796 | ExternalGTE ExternalDocVersion
797 -- ^ Use your own version numbering. Only index
798 -- the document if the version is equal or higher
799 -- than the stored version. Will succeed if there
800 -- is no existing document. The given version will
801 -- be used as the new version number for the
802 -- stored document. Use with care, as this could
803 -- result in data loss.
804 | ForceVersion ExternalDocVersion
805 -- ^ The document will always be indexed and the
806 -- given version will be the new version. This is
807 -- typically used for correcting errors. Use with
808 -- care, as this could result in data loss.
809 deriving (Read, Show, Eq, Generic, Ord)
811{-| 'DocumentParent' is used to specify a parent document.
812-}
813newtype DocumentParent = DocumentParent DocId
814 deriving (Eq, Read, Show, Generic, Typeable)
816{-| 'IndexDocumentSettings' are special settings supplied when indexing
817a document. For the best backwards compatiblity when new fields are
818added, you should probably prefer to start with 'defaultIndexDocumentSettings'
819-}
820data IndexDocumentSettings =
821 IndexDocumentSettings { idsVersionControl :: VersionControl
822 , idsParent :: Maybe DocumentParent
823 } deriving (Eq, Read, Show, Generic, Typeable)
825{-| Reasonable default settings. Chooses no version control and no parent.
826-}
827defaultIndexDocumentSettings :: IndexDocumentSettings
828defaultIndexDocumentSettings = IndexDocumentSettings NoVersionControl Nothing
830{-| 'Sort' is a synonym for a list of 'SortSpec's. Sort behavior is order
831 dependent with later sorts acting as tie-breakers for earlier sorts.
832-}
833type Sort = [SortSpec]
835{-| The two main kinds of 'SortSpec' are 'DefaultSortSpec' and
836 'GeoDistanceSortSpec'. The latter takes a 'SortOrder', 'GeoPoint', and
837 'DistanceUnit' to express "nearness" to a single geographical point as a
838 sort specification.
840<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
841-}
842data SortSpec = DefaultSortSpec DefaultSort
843 | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit deriving (Eq, Read, Show, Generic, Typeable)
845{-| 'DefaultSort' is usually the kind of 'SortSpec' you'll want. There's a
846 'mkSort' convenience function for when you want to specify only the most
847 common parameters.
849<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
850-}
851data DefaultSort =
852 DefaultSort { sortFieldName :: FieldName
853 , sortOrder :: SortOrder
854 -- default False
855 , ignoreUnmapped :: Bool
856 , sortMode :: Maybe SortMode
857 , missingSort :: Maybe Missing
858 , nestedFilter :: Maybe Filter } deriving (Eq, Read, Show, Generic, Typeable)
860{-| 'SortOrder' is 'Ascending' or 'Descending', as you might expect. These get
861 encoded into "asc" or "desc" when turned into JSON.
863<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
864-}
865data SortOrder = Ascending
866 | Descending deriving (Eq, Read, Show, Generic, Typeable)
868{-| 'Missing' prescribes how to handle missing fields. A missing field can be
869 sorted last, first, or using a custom value as a substitute.
871<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_missing_values>
872-}
873data Missing = LastMissing
874 | FirstMissing
875 | CustomMissing Text deriving (Eq, Read, Show, Generic, Typeable)
877{-| 'SortMode' prescribes how to handle sorting array/multi-valued fields.
879http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_sort_mode_option
880-}
881data SortMode = SortMin
882 | SortMax
883 | SortSum
884 | SortAvg deriving (Eq, Read, Show, Generic, Typeable)
886{-| 'mkSort' defaults everything but the 'FieldName' and the 'SortOrder' so
887 that you can concisely describe the usual kind of 'SortSpec's you want.
888-}
889mkSort :: FieldName -> SortOrder -> DefaultSort
890mkSort fieldName sOrder = DefaultSort fieldName sOrder False Nothing Nothing Nothing
892{-| 'Cache' is for telling ES whether it should cache a 'Filter' not.
893 'Query's cannot be cached.
894-}
895type Cache = Bool -- caching on/off
896defaultCache :: Cache
897defaultCache = False
899{-| 'PrefixValue' is used in 'PrefixQuery' as the main query component.
900-}
901type PrefixValue = Text
903{-| 'BooleanOperator' is the usual And/Or operators with an ES compatible
904 JSON encoding baked in. Used all over the place.
905-}
906data BooleanOperator = And | Or deriving (Eq, Read, Show, Generic, Typeable)
908{-| 'ShardCount' is part of 'IndexSettings'
909-}
910newtype ShardCount = ShardCount Int deriving (Eq, Read, Show, Generic, ToJSON, Typeable)
912{-| 'ReplicaCount' is part of 'IndexSettings'
913-}
914newtype ReplicaCount = ReplicaCount Int deriving (Eq, Read, Show, Generic, ToJSON, Typeable)
916{-| 'IndexName' is used to describe which index to query/create/delete
917-}
918newtype IndexName = IndexName Text deriving (Eq, Generic, Read, Show, ToJSON, FromJSON, Typeable)
920{-| 'IndexSelection' is used for APIs which take a single index, a list of
921 indexes, or the special @_all@ index.
922-}
923--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.
924data IndexSelection = IndexList (NonEmpty IndexName)
925 | AllIndexes deriving (Eq, Generic, Show, Typeable)
927{-| '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.
928-}
929data NodeSelection = LocalNode
930 -- ^ Whatever node receives this request
931 | NodeList (NonEmpty NodeSelector)
932 | AllNodes deriving (Eq, Generic, Show, Typeable)
935-- | An exact match or pattern to identify a node. Note that All of
936-- these options support wildcarding, so your node name, server, attr
937-- name can all contain * characters to be a fuzzy match.
938data NodeSelector = NodeByName NodeName
939 | NodeByFullNodeId FullNodeId
940 | NodeByHost Server
941 -- ^ e.g. 10.0.0.1 or even 10.0.0.*
942 | NodeByAttribute NodeAttrName Text
943 -- ^ NodeAttrName can be a pattern, e.g. rack*. The value can too.
944 deriving (Eq, Generic, Show, Typeable)
946{-| 'TemplateName' is used to describe which template to query/create/delete
947-}
948newtype TemplateName = TemplateName Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
950{-| 'TemplatePattern' represents a pattern which is matched against index names
951-}
952newtype TemplatePattern = TemplatePattern Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
954{-| 'MappingName' is part of mappings which are how ES describes and schematizes
955 the data in the indices.
956-}
957newtype MappingName = MappingName Text deriving (Eq, Generic, Read, Show, ToJSON, FromJSON, Typeable)
959{-| 'DocId' is a generic wrapper value for expressing unique Document IDs.
960 Can be set by the user or created by ES itself. Often used in client
961 functions for poking at specific documents.
962-}
963newtype DocId = DocId Text deriving (Eq, Generic, Read, Show, ToJSON, FromJSON, Typeable)
965{-| 'QueryString' is used to wrap query text bodies, be they human written or not.
966-}
967newtype QueryString = QueryString Text deriving (Eq, Generic, Read, Show, ToJSON, FromJSON, Typeable)
969{-| 'FieldName' is used all over the place wherever a specific field within
970 a document needs to be specified, usually in 'Query's or 'Filter's.
971-}
972newtype FieldName = FieldName Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
975{-| 'Script' is often used in place of 'FieldName' to specify more
976complex ways of extracting a value from a document.
977-}
978newtype Script = Script { scriptText :: Text } deriving (Eq, Read, Show, Generic, Typeable)
980{-| 'CacheName' is used in 'RegexpFilter' for describing the
981 'CacheKey' keyed caching behavior.
982-}
983newtype CacheName = CacheName Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
985{-| 'CacheKey' is used in 'RegexpFilter' to key regex caching.
986-}
987newtype CacheKey =
988 CacheKey Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
989newtype Existence =
990 Existence Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
991newtype NullValue =
992 NullValue Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
993newtype CutoffFrequency =
994 CutoffFrequency Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
995newtype Analyzer =
996 Analyzer Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
997newtype MaxExpansions =
998 MaxExpansions Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1000{-| 'Lenient', if set to true, will cause format based failures to be
1001 ignored. I don't know what the bloody default is, Elasticsearch
1002 documentation didn't say what it was. Let me know if you figure it out.
1004newtype Lenient =
1005 Lenient Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1006newtype Tiebreaker =
1007 Tiebreaker Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1008newtype Boost =
1009 Boost Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1010newtype BoostTerms =
1011 BoostTerms Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1013{-| 'MinimumMatch' controls how many should clauses in the bool query should
1014 match. Can be an absolute value (2) or a percentage (30%) or a
1015 combination of both.
1017newtype MinimumMatch =
1018 MinimumMatch Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1019newtype DisableCoord =
1020 DisableCoord Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1021newtype IgnoreTermFrequency =
1022 IgnoreTermFrequency Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1023newtype MinimumTermFrequency =
1024 MinimumTermFrequency Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1025newtype MaxQueryTerms =
1026 MaxQueryTerms Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1027newtype Fuzziness =
1028 Fuzziness Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1030{-| 'PrefixLength' is the prefix length used in queries, defaults to 0. -}
1031newtype PrefixLength =
1032 PrefixLength Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1033newtype TypeName =
1034 TypeName Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1035newtype PercentMatch =
1036 PercentMatch Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1037newtype StopWord =
1038 StopWord Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1039newtype QueryPath =
1040 QueryPath Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1042{-| Allowing a wildcard at the beginning of a word (eg "*ing") is particularly
1043 heavy, because all terms in the index need to be examined, just in case
1044 they match. Leading wildcards can be disabled by setting
1045 'AllowLeadingWildcard' to false. -}
1046newtype AllowLeadingWildcard =
1047 AllowLeadingWildcard Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1048newtype LowercaseExpanded =
1049 LowercaseExpanded Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1050newtype EnablePositionIncrements =
1051 EnablePositionIncrements Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1053{-| By default, wildcard terms in a query are not analyzed.
1054 Setting 'AnalyzeWildcard' to true enables best-effort analysis.
1056newtype AnalyzeWildcard = AnalyzeWildcard Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1058{-| 'GeneratePhraseQueries' defaults to false.
1060newtype GeneratePhraseQueries =
1061 GeneratePhraseQueries Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1063{-| 'Locale' is used for string conversions - defaults to ROOT.
1065newtype Locale = Locale Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1066newtype MaxWordLength = MaxWordLength Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1067newtype MinWordLength = MinWordLength Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1069{-| 'PhraseSlop' sets the default slop for phrases, 0 means exact
1070 phrase matches. Default is 0.
1072newtype PhraseSlop = PhraseSlop Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1073newtype MinDocFrequency = MinDocFrequency Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1074newtype MaxDocFrequency = MaxDocFrequency Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1076-- | Newtype wrapper to parse ES's concerning tendency to in some APIs return a floating point number of milliseconds since epoch ಠ_ಠ
1077newtype POSIXMS = POSIXMS { posixMS :: UTCTime }
1079{-| 'unpackId' is a silly convenience function that gets used once.
1081unpackId :: DocId -> Text
1082unpackId (DocId docId) = docId
1084type TrackSortScores = Bool
1085newtype From = From Int deriving (Eq, Read, Show, Generic, ToJSON)
1086newtype Size = Size Int deriving (Eq, Read, Show, Generic, ToJSON)
1088data Search = Search { queryBody :: Maybe Query
1089 , filterBody :: Maybe Filter
1090 , sortBody :: Maybe Sort
1091 , aggBody :: Maybe Aggregations
1092 , highlight :: Maybe Highlights
1093 -- default False
1094 , trackSortScores :: TrackSortScores
1095 , from :: From
1096 , size :: Size
1097 , searchType :: SearchType
1098 , fields :: Maybe [FieldName]
1099 , source :: Maybe Source } deriving (Eq, Read, Show, Generic, Typeable)
1101data SearchType = SearchTypeQueryThenFetch
1102 | SearchTypeDfsQueryThenFetch
1103 | SearchTypeCount
1104 | SearchTypeScan
1105 | SearchTypeQueryAndFetch
1106 | SearchTypeDfsQueryAndFetch
1107 deriving (Eq, Read, Show, Generic, Typeable)
1109data Source =
1110 NoSource
1111 | SourcePatterns PatternOrPatterns
1112 | SourceIncludeExclude Include Exclude
1113 deriving (Read, Show, Eq, Generic, Typeable)
1115data PatternOrPatterns = PopPattern Pattern
1116 | PopPatterns [Pattern] deriving (Eq, Read, Show, Generic, Typeable)
1118data Include = Include [Pattern] deriving (Eq, Read, Show, Generic, Typeable)
1119data Exclude = Exclude [Pattern] deriving (Eq, Read, Show, Generic, Typeable)
1121newtype Pattern = Pattern Text deriving (Eq, Read, Show, Generic, Typeable)
1123data Highlights = Highlights { globalsettings :: Maybe HighlightSettings
1124 , highlightFields :: [FieldHighlight]
1125 } deriving (Read, Show, Eq, Generic, Typeable)
1127data FieldHighlight = FieldHighlight FieldName (Maybe HighlightSettings)
1128 deriving (Read, Show, Eq, Generic, Typeable)
1131data HighlightSettings = Plain PlainHighlight
1132 | Postings PostingsHighlight
1133 | FastVector FastVectorHighlight
1134 deriving (Read, Show, Eq, Generic, Typeable)
1135data PlainHighlight =
1136 PlainHighlight { plainCommon :: Maybe CommonHighlight
1137 , plainNonPost :: Maybe NonPostings } deriving (Read, Show, Eq, Generic, Typeable)
1139 -- This requires that index_options are set to 'offset' in the mapping.
1140data PostingsHighlight = PostingsHighlight (Maybe CommonHighlight) deriving (Read, Show, Eq, Generic, Typeable)
1142-- This requires that term_vector is set to 'with_positions_offsets' in the mapping.
1143data FastVectorHighlight =
1144 FastVectorHighlight { fvCommon :: Maybe CommonHighlight
1145 , fvNonPostSettings :: Maybe NonPostings
1146 , boundaryChars :: Maybe Text
1147 , boundaryMaxScan :: Maybe Int
1148 , fragmentOffset :: Maybe Int
1149 , matchedFields :: [Text]
1150 , phraseLimit :: Maybe Int
1151 } deriving (Read, Show, Eq, Generic, Typeable)
1153data CommonHighlight =
1154 CommonHighlight { order :: Maybe Text
1155 , forceSource :: Maybe Bool
1156 , tag :: Maybe HighlightTag
1157 , encoder :: Maybe HighlightEncoder
1158 , noMatchSize :: Maybe Int
1159 , highlightQuery :: Maybe Query
1160 , requireFieldMatch :: Maybe Bool
1161 } deriving (Read, Show, Eq, Generic, Typeable)
1163-- Settings that are only applicable to FastVector and Plain highlighters.
1164data NonPostings =
1165 NonPostings { fragmentSize :: Maybe Int
1166 , numberOfFragments :: Maybe Int} deriving (Read, Show, Eq, Generic, Typeable)
1168data HighlightEncoder = DefaultEncoder
1169 | HTMLEncoder
1170 deriving (Read, Show, Eq, Generic, Typeable)
1172-- NOTE: Should the tags use some kind of HTML type, rather than Text?
1173data HighlightTag = TagSchema Text
1174 | CustomTags ([Text], [Text]) -- Only uses more than the first value in the lists if fvh
1175 deriving (Read, Show, Eq, Generic, Typeable)
1178data Query =
1179 TermQuery Term (Maybe Boost)
1180 | TermsQuery Text (NonEmpty Text)
1181 | QueryMatchQuery MatchQuery
1182 | QueryMultiMatchQuery MultiMatchQuery
1183 | QueryBoolQuery BoolQuery
1184 | QueryBoostingQuery BoostingQuery
1185 | QueryCommonTermsQuery CommonTermsQuery
1186 | ConstantScoreFilter Filter Boost
1187 | ConstantScoreQuery Query Boost
1188 | QueryDisMaxQuery DisMaxQuery
1189 | QueryFilteredQuery FilteredQuery
1190 | QueryFuzzyLikeThisQuery FuzzyLikeThisQuery
1191 | QueryFuzzyLikeFieldQuery FuzzyLikeFieldQuery
1192 | QueryFuzzyQuery FuzzyQuery
1193 | QueryHasChildQuery HasChildQuery
1194 | QueryHasParentQuery HasParentQuery
1195 | IdsQuery MappingName [DocId]
1196 | QueryIndicesQuery IndicesQuery
1197 | MatchAllQuery (Maybe Boost)
1198 | QueryMoreLikeThisQuery MoreLikeThisQuery
1199 | QueryMoreLikeThisFieldQuery MoreLikeThisFieldQuery
1200 | QueryNestedQuery NestedQuery
1201 | QueryPrefixQuery PrefixQuery
1202 | QueryQueryStringQuery QueryStringQuery
1203 | QuerySimpleQueryStringQuery SimpleQueryStringQuery
1204 | QueryRangeQuery RangeQuery
1205 | QueryRegexpQuery RegexpQuery
1206 deriving (Eq, Read, Show, Generic, Typeable)
1208data RegexpQuery =
1209 RegexpQuery { regexpQueryField :: FieldName
1210 , regexpQuery :: Regexp
1211 , regexpQueryFlags :: RegexpFlags
1212 , regexpQueryBoost :: Maybe Boost
1213 } deriving (Eq, Read, Show, Generic, Typeable)
1215data RangeQuery =
1216 RangeQuery { rangeQueryField :: FieldName
1217 , rangeQueryRange :: RangeValue
1218 , rangeQueryBoost :: Boost } deriving (Eq, Read, Show, Generic, Typeable)
1220mkRangeQuery :: FieldName -> RangeValue -> RangeQuery
1221mkRangeQuery f r = RangeQuery f r (Boost 1.0)
1223data SimpleQueryStringQuery =
1224 SimpleQueryStringQuery
1225 { simpleQueryStringQuery :: QueryString
1226 , simpleQueryStringField :: Maybe FieldOrFields
1227 , simpleQueryStringOperator :: Maybe BooleanOperator
1228 , simpleQueryStringAnalyzer :: Maybe Analyzer
1229 , simpleQueryStringFlags :: Maybe (NonEmpty SimpleQueryFlag)
1230 , simpleQueryStringLowercaseExpanded :: Maybe LowercaseExpanded
1231 , simpleQueryStringLocale :: Maybe Locale
1232 } deriving (Eq, Read, Show, Generic, Typeable)
1234data SimpleQueryFlag =
1235 SimpleQueryAll
1236 | SimpleQueryNone
1237 | SimpleQueryAnd
1238 | SimpleQueryOr
1239 | SimpleQueryPrefix
1240 | SimpleQueryPhrase
1241 | SimpleQueryPrecedence
1242 | SimpleQueryEscape
1243 | SimpleQueryWhitespace
1244 | SimpleQueryFuzzy
1245 | SimpleQueryNear
1246 | SimpleQuerySlop deriving (Eq, Read, Show, Generic, Typeable)
1248-- use_dis_max and tie_breaker when fields are plural?
1249data QueryStringQuery =
1250 QueryStringQuery
1251 { queryStringQuery :: QueryString
1252 , queryStringDefaultField :: Maybe FieldName
1253 , queryStringOperator :: Maybe BooleanOperator
1254 , queryStringAnalyzer :: Maybe Analyzer
1255 , queryStringAllowLeadingWildcard :: Maybe AllowLeadingWildcard
1256 , queryStringLowercaseExpanded :: Maybe LowercaseExpanded
1257 , queryStringEnablePositionIncrements :: Maybe EnablePositionIncrements
1258 , queryStringFuzzyMaxExpansions :: Maybe MaxExpansions
1259 , queryStringFuzziness :: Maybe Fuzziness
1260 , queryStringFuzzyPrefixLength :: Maybe PrefixLength
1261 , queryStringPhraseSlop :: Maybe PhraseSlop
1262 , queryStringBoost :: Maybe Boost
1263 , queryStringAnalyzeWildcard :: Maybe AnalyzeWildcard
1264 , queryStringGeneratePhraseQueries :: Maybe GeneratePhraseQueries
1265 , queryStringMinimumShouldMatch :: Maybe MinimumMatch
1266 , queryStringLenient :: Maybe Lenient
1267 , queryStringLocale :: Maybe Locale
1268 } deriving (Eq, Read, Show, Generic, Typeable)
1270mkQueryStringQuery :: QueryString -> QueryStringQuery
1271mkQueryStringQuery qs =
1272 QueryStringQuery qs Nothing Nothing
1273 Nothing Nothing Nothing Nothing
1274 Nothing Nothing Nothing Nothing
1275 Nothing Nothing Nothing Nothing
1276 Nothing Nothing
1278data FieldOrFields = FofField FieldName
1279 | FofFields (NonEmpty FieldName) deriving (Eq, Read, Show, Generic, Typeable)
1281data PrefixQuery =
1282 PrefixQuery
1283 { prefixQueryField :: FieldName
1284 , prefixQueryPrefixValue :: Text
1285 , prefixQueryBoost :: Maybe Boost } deriving (Eq, Read, Show, Generic, Typeable)
1287data NestedQuery =
1288 NestedQuery
1289 { nestedQueryPath :: QueryPath
1290 , nestedQueryScoreType :: ScoreType
1291 , nestedQuery :: Query } deriving (Eq, Read, Show, Generic, Typeable)
1293data MoreLikeThisFieldQuery =
1294 MoreLikeThisFieldQuery
1295 { moreLikeThisFieldText :: Text
1296 , moreLikeThisFieldFields :: FieldName
1297 -- default 0.3 (30%)
1298 , moreLikeThisFieldPercentMatch :: Maybe PercentMatch
1299 , moreLikeThisFieldMinimumTermFreq :: Maybe MinimumTermFrequency
1300 , moreLikeThisFieldMaxQueryTerms :: Maybe MaxQueryTerms
1301 , moreLikeThisFieldStopWords :: Maybe (NonEmpty StopWord)
1302 , moreLikeThisFieldMinDocFrequency :: Maybe MinDocFrequency
1303 , moreLikeThisFieldMaxDocFrequency :: Maybe MaxDocFrequency
1304 , moreLikeThisFieldMinWordLength :: Maybe MinWordLength
1305 , moreLikeThisFieldMaxWordLength :: Maybe MaxWordLength
1306 , moreLikeThisFieldBoostTerms :: Maybe BoostTerms
1307 , moreLikeThisFieldBoost :: Maybe Boost
1308 , moreLikeThisFieldAnalyzer :: Maybe Analyzer
1309 } deriving (Eq, Read, Show, Generic, Typeable)
1311data MoreLikeThisQuery =
1312 MoreLikeThisQuery
1313 { moreLikeThisText :: Text
1314 , moreLikeThisFields :: Maybe (NonEmpty FieldName)
1315 -- default 0.3 (30%)
1316 , moreLikeThisPercentMatch :: Maybe PercentMatch
1317 , moreLikeThisMinimumTermFreq :: Maybe MinimumTermFrequency
1318 , moreLikeThisMaxQueryTerms :: Maybe MaxQueryTerms
1319 , moreLikeThisStopWords :: Maybe (NonEmpty StopWord)
1320 , moreLikeThisMinDocFrequency :: Maybe MinDocFrequency
1321 , moreLikeThisMaxDocFrequency :: Maybe MaxDocFrequency
1322 , moreLikeThisMinWordLength :: Maybe MinWordLength
1323 , moreLikeThisMaxWordLength :: Maybe MaxWordLength
1324 , moreLikeThisBoostTerms :: Maybe BoostTerms
1325 , moreLikeThisBoost :: Maybe Boost
1326 , moreLikeThisAnalyzer :: Maybe Analyzer
1327 } deriving (Eq, Read, Show, Generic, Typeable)
1329data IndicesQuery =
1330 IndicesQuery
1331 { indicesQueryIndices :: [IndexName]
1332 , indicesQuery :: Query
1333 -- default "all"
1334 , indicesQueryNoMatch :: Maybe Query } deriving (Eq, Read, Show, Generic, Typeable)
1336data HasParentQuery =
1337 HasParentQuery
1338 { hasParentQueryType :: TypeName
1339 , hasParentQuery :: Query
1340 , hasParentQueryScoreType :: Maybe ScoreType } deriving (Eq, Read, Show, Generic, Typeable)
1342data HasChildQuery =
1343 HasChildQuery
1344 { hasChildQueryType :: TypeName
1345 , hasChildQuery :: Query
1346 , hasChildQueryScoreType :: Maybe ScoreType } deriving (Eq, Read, Show, Generic, Typeable)
1348data ScoreType =
1349 ScoreTypeMax
1350 | ScoreTypeSum
1351 | ScoreTypeAvg
1352 | ScoreTypeNone deriving (Eq, Read, Show, Generic, Typeable)
1354data FuzzyQuery =
1355 FuzzyQuery { fuzzyQueryField :: FieldName
1356 , fuzzyQueryValue :: Text
1357 , fuzzyQueryPrefixLength :: PrefixLength
1358 , fuzzyQueryMaxExpansions :: MaxExpansions
1359 , fuzzyQueryFuzziness :: Fuzziness
1360 , fuzzyQueryBoost :: Maybe Boost
1361 } deriving (Eq, Read, Show, Generic, Typeable)
1363data FuzzyLikeFieldQuery =
1364 FuzzyLikeFieldQuery
1365 { fuzzyLikeField :: FieldName
1366 -- anaphora is good for the soul.
1367 , fuzzyLikeFieldText :: Text
1368 , fuzzyLikeFieldMaxQueryTerms :: MaxQueryTerms
1369 , fuzzyLikeFieldIgnoreTermFrequency :: IgnoreTermFrequency
1370 , fuzzyLikeFieldFuzziness :: Fuzziness
1371 , fuzzyLikeFieldPrefixLength :: PrefixLength
1372 , fuzzyLikeFieldBoost :: Boost
1373 , fuzzyLikeFieldAnalyzer :: Maybe Analyzer
1374 } deriving (Eq, Read, Show, Generic, Typeable)
1376data FuzzyLikeThisQuery =
1377 FuzzyLikeThisQuery
1378 { fuzzyLikeFields :: [FieldName]
1379 , fuzzyLikeText :: Text
1380 , fuzzyLikeMaxQueryTerms :: MaxQueryTerms
1381 , fuzzyLikeIgnoreTermFrequency :: IgnoreTermFrequency
1382 , fuzzyLikeFuzziness :: Fuzziness
1383 , fuzzyLikePrefixLength :: PrefixLength
1384 , fuzzyLikeBoost :: Boost
1385 , fuzzyLikeAnalyzer :: Maybe Analyzer
1386 } deriving (Eq, Read, Show, Generic, Typeable)
1388data FilteredQuery =
1389 FilteredQuery
1390 { filteredQuery :: Query
1391 , filteredFilter :: Filter } deriving (Eq, Read, Show, Generic, Typeable)
1393data DisMaxQuery =
1394 DisMaxQuery { disMaxQueries :: [Query]
1395 -- default 0.0
1396 , disMaxTiebreaker :: Tiebreaker
1397 , disMaxBoost :: Maybe Boost
1398 } deriving (Eq, Read, Show, Generic, Typeable)
1400data MatchQuery =
1401 MatchQuery { matchQueryField :: FieldName
1402 , matchQueryQueryString :: QueryString
1403 , matchQueryOperator :: BooleanOperator
1404 , matchQueryZeroTerms :: ZeroTermsQuery
1405 , matchQueryCutoffFrequency :: Maybe CutoffFrequency
1406 , matchQueryMatchType :: Maybe MatchQueryType
1407 , matchQueryAnalyzer :: Maybe Analyzer
1408 , matchQueryMaxExpansions :: Maybe MaxExpansions
1409 , matchQueryLenient :: Maybe Lenient
1410 , matchQueryBoost :: Maybe Boost } deriving (Eq, Read, Show, Generic, Typeable)
1412{-| 'mkMatchQuery' is a convenience function that defaults the less common parameters,
1413 enabling you to provide only the 'FieldName' and 'QueryString' to make a 'MatchQuery'
1415mkMatchQuery :: FieldName -> QueryString -> MatchQuery
1416mkMatchQuery field query = MatchQuery field query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1418data MatchQueryType =
1419 MatchPhrase
1420 | MatchPhrasePrefix deriving (Eq, Read, Show, Generic, Typeable)
1422data MultiMatchQuery =
1423 MultiMatchQuery { multiMatchQueryFields :: [FieldName]
1424 , multiMatchQueryString :: QueryString
1425 , multiMatchQueryOperator :: BooleanOperator
1426 , multiMatchQueryZeroTerms :: ZeroTermsQuery
1427 , multiMatchQueryTiebreaker :: Maybe Tiebreaker
1428 , multiMatchQueryType :: Maybe MultiMatchQueryType
1429 , multiMatchQueryCutoffFrequency :: Maybe CutoffFrequency
1430 , multiMatchQueryAnalyzer :: Maybe Analyzer
1431 , multiMatchQueryMaxExpansions :: Maybe MaxExpansions
1432 , multiMatchQueryLenient :: Maybe Lenient } deriving (Eq, Read, Show, Generic, Typeable)
1434{-| 'mkMultiMatchQuery' is a convenience function that defaults the less common parameters,
1435 enabling you to provide only the list of 'FieldName's and 'QueryString' to
1436 make a 'MultiMatchQuery'.
1439mkMultiMatchQuery :: [FieldName] -> QueryString -> MultiMatchQuery
1440mkMultiMatchQuery matchFields query =
1441 MultiMatchQuery matchFields query
1442 Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1444data MultiMatchQueryType =
1445 MultiMatchBestFields
1446 | MultiMatchMostFields
1447 | MultiMatchCrossFields
1448 | MultiMatchPhrase
1449 | MultiMatchPhrasePrefix deriving (Eq, Read, Show, Generic, Typeable)
1451data BoolQuery =
1452 BoolQuery { boolQueryMustMatch :: [Query]
1453 , boolQueryMustNotMatch :: [Query]
1454 , boolQueryShouldMatch :: [Query]
1455 , boolQueryMinimumShouldMatch :: Maybe MinimumMatch
1456 , boolQueryBoost :: Maybe Boost
1457 , boolQueryDisableCoord :: Maybe DisableCoord
1458 } deriving (Eq, Read, Show, Generic, Typeable)
1460mkBoolQuery :: [Query] -> [Query] -> [Query] -> BoolQuery
1461mkBoolQuery must mustNot should =
1462 BoolQuery must mustNot should Nothing Nothing Nothing
1464data BoostingQuery =
1465 BoostingQuery { positiveQuery :: Query
1466 , negativeQuery :: Query
1467 , negativeBoost :: Boost } deriving (Eq, Read, Show, Generic, Typeable)
1469data CommonTermsQuery =
1470 CommonTermsQuery { commonField :: FieldName
1471 , commonQuery :: QueryString
1472 , commonCutoffFrequency :: CutoffFrequency
1473 , commonLowFreqOperator :: BooleanOperator
1474 , commonHighFreqOperator :: BooleanOperator
1475 , commonMinimumShouldMatch :: Maybe CommonMinimumMatch
1476 , commonBoost :: Maybe Boost
1477 , commonAnalyzer :: Maybe Analyzer
1478 , commonDisableCoord :: Maybe DisableCoord
1479 } deriving (Eq, Read, Show, Generic, Typeable)
1481data CommonMinimumMatch =
1482 CommonMinimumMatchHighLow MinimumMatchHighLow
1483 | CommonMinimumMatch MinimumMatch
1484 deriving (Eq, Read, Show, Generic, Typeable)
1486data MinimumMatchHighLow =
1487 MinimumMatchHighLow { lowFreq :: MinimumMatch
1488 , highFreq :: MinimumMatch } deriving (Eq, Read, Show, Generic, Typeable)
1490data Filter = AndFilter [Filter] Cache
1491 | OrFilter [Filter] Cache
1492 | NotFilter Filter Cache
1493 | IdentityFilter
1494 | BoolFilter BoolMatch
1495 | ExistsFilter FieldName -- always cached
1496 | GeoBoundingBoxFilter GeoBoundingBoxConstraint
1497 | GeoDistanceFilter GeoPoint Distance DistanceType OptimizeBbox Cache
1498 | GeoDistanceRangeFilter GeoPoint DistanceRange
1499 | GeoPolygonFilter FieldName [LatLon]
1500 | IdsFilter MappingName [DocId]
1501 | LimitFilter Int
1502 | MissingFilter FieldName Existence NullValue
1503 | PrefixFilter FieldName PrefixValue Cache
1504 | QueryFilter Query Cache
1505 | RangeFilter FieldName RangeValue RangeExecution Cache
1506 | RegexpFilter FieldName Regexp RegexpFlags CacheName Cache CacheKey
1507 | TermFilter Term Cache
1508 deriving (Eq, Read, Show, Generic, Typeable)
1510data ZeroTermsQuery = ZeroTermsNone
1511 | ZeroTermsAll deriving (Eq, Read, Show, Generic, Typeable)
1513data RangeExecution = RangeExecutionIndex
1514 | RangeExecutionFielddata deriving (Eq, Read, Show, Generic, Typeable)
1516newtype Regexp = Regexp Text deriving (Eq, Read, Show, Generic, Typeable, FromJSON)
1518data RegexpFlags = AllRegexpFlags
1519 | NoRegexpFlags
1520 | SomeRegexpFlags (NonEmpty RegexpFlag) deriving (Eq, Read, Show, Generic, Typeable)
1522data RegexpFlag = AnyString
1523 | Automaton
1524 | Complement
1525 | Empty
1526 | Intersection
1527 | Interval deriving (Eq, Read, Show, Generic, Typeable)
1529newtype LessThan = LessThan Double deriving (Eq, Read, Show, Generic, Typeable)
1530newtype LessThanEq = LessThanEq Double deriving (Eq, Read, Show, Generic, Typeable)
1531newtype GreaterThan = GreaterThan Double deriving (Eq, Read, Show, Generic, Typeable)
1532newtype GreaterThanEq = GreaterThanEq Double deriving (Eq, Read, Show, Generic, Typeable)
1534newtype LessThanD = LessThanD UTCTime deriving (Eq, Read, Show, Generic, Typeable)
1535newtype LessThanEqD = LessThanEqD UTCTime deriving (Eq, Read, Show, Generic, Typeable)
1536newtype GreaterThanD = GreaterThanD UTCTime deriving (Eq, Read, Show, Generic, Typeable)
1537newtype GreaterThanEqD = GreaterThanEqD UTCTime deriving (Eq, Read, Show, Generic, Typeable)
1539data RangeValue = RangeDateLte LessThanEqD
1540 | RangeDateLt LessThanD
1541 | RangeDateGte GreaterThanEqD
1542 | RangeDateGt GreaterThanD
1543 | RangeDateGtLt GreaterThanD LessThanD
1544 | RangeDateGteLte GreaterThanEqD LessThanEqD
1545 | RangeDateGteLt GreaterThanEqD LessThanD
1546 | RangeDateGtLte GreaterThanD LessThanEqD
1547 | RangeDoubleLte LessThanEq
1548 | RangeDoubleLt LessThan
1549 | RangeDoubleGte GreaterThanEq
1550 | RangeDoubleGt GreaterThan
1551 | RangeDoubleGtLt GreaterThan LessThan
1552 | RangeDoubleGteLte GreaterThanEq LessThanEq
1553 | RangeDoubleGteLt GreaterThanEq LessThan
1554 | RangeDoubleGtLte GreaterThan LessThanEq
1555 deriving (Eq, Read, Show, Generic, Typeable)
1557rangeValueToPair :: RangeValue -> [Pair]
1558rangeValueToPair rv = case rv of
1559 RangeDateLte (LessThanEqD t) -> ["lte" .= t]
1560 RangeDateGte (GreaterThanEqD t) -> ["gte" .= t]
1561 RangeDateLt (LessThanD t) -> ["lt" .= t]
1562 RangeDateGt (GreaterThanD t) -> ["gt" .= t]
1563 RangeDateGteLte (GreaterThanEqD l) (LessThanEqD g) -> ["gte" .= l, "lte" .= g]
1564 RangeDateGtLte (GreaterThanD l) (LessThanEqD g) -> ["gt" .= l, "lte" .= g]
1565 RangeDateGteLt (GreaterThanEqD l) (LessThanD g) -> ["gte" .= l, "lt" .= g]
1566 RangeDateGtLt (GreaterThanD l) (LessThanD g) -> ["gt" .= l, "lt" .= g]
1567 RangeDoubleLte (LessThanEq t) -> ["lte" .= t]
1568 RangeDoubleGte (GreaterThanEq t) -> ["gte" .= t]
1569 RangeDoubleLt (LessThan t) -> ["lt" .= t]
1570 RangeDoubleGt (GreaterThan t) -> ["gt" .= t]
1571 RangeDoubleGteLte (GreaterThanEq l) (LessThanEq g) -> ["gte" .= l, "lte" .= g]
1572 RangeDoubleGtLte (GreaterThan l) (LessThanEq g) -> ["gt" .= l, "lte" .= g]
1573 RangeDoubleGteLt (GreaterThanEq l) (LessThan g) -> ["gte" .= l, "lt" .= g]
1574 RangeDoubleGtLt (GreaterThan l) (LessThan g) -> ["gt" .= l, "lt" .= g]
1576data Term = Term { termField :: Text
1577 , termValue :: Text } deriving (Eq, Read, Show, Generic, Typeable)
1579data BoolMatch = MustMatch Term Cache
1580 | MustNotMatch Term Cache
1581 | ShouldMatch [Term] Cache deriving (Eq, Read, Show, Generic, Typeable)
1583-- "memory" or "indexed"
1584data GeoFilterType = GeoFilterMemory
1585 | GeoFilterIndexed deriving (Eq, Read, Show, Generic, Typeable)
1587data LatLon = LatLon { lat :: Double
1588 , lon :: Double } deriving (Eq, Read, Show, Generic, Typeable)
1590data GeoBoundingBox =
1591 GeoBoundingBox { topLeft :: LatLon
1592 , bottomRight :: LatLon } deriving (Eq, Read, Show, Generic, Typeable)
1594data GeoBoundingBoxConstraint =
1595 GeoBoundingBoxConstraint { geoBBField :: FieldName
1596 , constraintBox :: GeoBoundingBox
1597 , bbConstraintcache :: Cache
1598 , geoType :: GeoFilterType
1599 } deriving (Eq, Read, Show, Generic, Typeable)
1601data GeoPoint =
1602 GeoPoint { geoField :: FieldName
1603 , latLon :: LatLon} deriving (Eq, Read, Show, Generic, Typeable)
1605data DistanceUnit = Miles
1606 | Yards
1607 | Feet
1608 | Inches
1609 | Kilometers
1610 | Meters
1611 | Centimeters
1612 | Millimeters
1613 | NauticalMiles deriving (Eq, Read, Show, Generic, Typeable)
1615data DistanceType = Arc
1616 | SloppyArc -- doesn't exist <1.0
1617 | Plane deriving (Eq, Read, Show, Generic, Typeable)
1619data OptimizeBbox = OptimizeGeoFilterType GeoFilterType
1620 | NoOptimizeBbox deriving (Eq, Read, Show, Generic, Typeable)
1622data Distance =
1623 Distance { coefficient :: Double
1624 , unit :: DistanceUnit } deriving (Eq, Read, Show, Generic, Typeable)
1626data DistanceRange =
1627 DistanceRange { distanceFrom :: Distance
1628 , distanceTo :: Distance } deriving (Eq, Read, Show, Generic, Typeable)
1630data SearchResult a =
1631 SearchResult { took :: Int
1632 , timedOut :: Bool
1633 , shards :: ShardResult
1634 , searchHits :: SearchHits a
1635 , aggregations :: Maybe AggregationResults
1636 , scrollId :: Maybe ScrollId } deriving (Eq, Read, Show, Generic, Typeable)
1638newtype ScrollId = ScrollId Text deriving (Eq, Read, Show, Generic, Ord, ToJSON, FromJSON)
1640type Score = Maybe Double
1642data SearchHits a =
1643 SearchHits { hitsTotal :: Int
1644 , maxScore :: Score
1645 , hits :: [Hit a] } deriving (Eq, Read, Show, Generic, Typeable)
1648instance Monoid (SearchHits a) where
1649 mempty = SearchHits 0 Nothing mempty
1650 mappend (SearchHits ta ma ha) (SearchHits tb mb hb) =
1651 SearchHits (ta + tb) (max ma mb) (ha <> hb)
1654data Hit a =
1655 Hit { hitIndex :: IndexName
1656 , hitType :: MappingName
1657 , hitDocId :: DocId
1658 , hitScore :: Score
1659 , hitSource :: Maybe a
1660 , hitHighlight :: Maybe HitHighlight } deriving (Eq, Read, Show, Generic, Typeable)
1662data ShardResult =
1663 ShardResult { shardTotal :: Int
1664 , shardsSuccessful :: Int
1665 , shardsFailed :: Int } deriving (Eq, Read, Show, Generic, Typeable)
1667type HitHighlight = M.Map Text [Text]
1669showText :: Show a => a -> Text
1670showText = T.pack . show
1672readMay :: Read a => String -> Maybe a
1673readMay s = case reads s of
1674 (a, ""):_ -> Just a
1675 _ -> Nothing
1677parseReadText :: Read a => Text -> Parser a
1678parseReadText = maybe mzero return . readMay . T.unpack
1680type Aggregations = M.Map Text Aggregation
1682emptyAggregations :: Aggregations
1683emptyAggregations = M.empty
1685mkAggregations :: Text -> Aggregation -> Aggregations
1686mkAggregations name aggregation = M.insert name aggregation emptyAggregations
1688data TermOrder = TermOrder{ termSortField :: Text
1689 , termSortOrder :: SortOrder } deriving (Eq, Read, Show, Generic, Typeable)
1691data TermInclusion = TermInclusion Text
1692 | TermPattern Text Text deriving (Eq, Read, Show, Generic, Typeable)
1694data CollectionMode = BreadthFirst
1695 | DepthFirst deriving (Eq, Read, Show, Generic, Typeable)
1697data ExecutionHint = Ordinals
1698 | GlobalOrdinals
1699 | GlobalOrdinalsHash
1700 | GlobalOrdinalsLowCardinality
1701 | Map deriving (Eq, Read, Show, Generic, Typeable)
1703data TimeInterval = Weeks
1704 | Days
1705 | Hours
1706 | Minutes
1707 | Seconds deriving Eq
1709data Interval = Year
1710 | Quarter
1711 | Month
1712 | Week
1713 | Day
1714 | Hour
1715 | Minute
1716 | Second
1717 | FractionalInterval Float TimeInterval deriving (Eq, Read, Show, Generic, Typeable)
1719data Aggregation = TermsAgg TermsAggregation
1720 | CardinalityAgg CardinalityAggregation
1721 | DateHistogramAgg DateHistogramAggregation
1722 | ValueCountAgg ValueCountAggregation
1723 | FilterAgg FilterAggregation
1724 | DateRangeAgg DateRangeAggregation
1725 | MissingAgg MissingAggregation deriving (Eq, Read, Show, Generic, Typeable)
1727data MissingAggregation = MissingAggregation
1728 { maField :: Text
1729 } deriving (Eq, Read, Show, Generic, Typeable)
1731data TermsAggregation = TermsAggregation { term :: Either Text Text
1732 , termInclude :: Maybe TermInclusion
1733 , termExclude :: Maybe TermInclusion
1734 , termOrder :: Maybe TermOrder
1735 , termMinDocCount :: Maybe Int
1736 , termSize :: Maybe Int
1737 , termShardSize :: Maybe Int
1738 , termCollectMode :: Maybe CollectionMode
1739 , termExecutionHint :: Maybe ExecutionHint
1740 , termAggs :: Maybe Aggregations
1741 } deriving (Eq, Read, Show, Generic, Typeable)
1743data CardinalityAggregation = CardinalityAggregation { cardinalityField :: FieldName,
1744 precisionThreshold :: Maybe Int
1745 } deriving (Eq, Read, Show, Generic, Typeable)
1747data DateHistogramAggregation = DateHistogramAggregation { dateField :: FieldName
1748 , dateInterval :: Interval
1749 , dateFormat :: Maybe Text
1750 -- pre and post deprecated in 1.5
1751 , datePreZone :: Maybe Text
1752 , datePostZone :: Maybe Text
1753 , datePreOffset :: Maybe Text
1754 , datePostOffset :: Maybe Text
1755 , dateAggs :: Maybe Aggregations
1756 } deriving (Eq, Read, Show, Generic, Typeable)
1759data DateRangeAggregation = DateRangeAggregation { draField :: FieldName
1760 , draFormat :: Maybe Text
1761 , draRanges :: NonEmpty DateRangeAggRange
1762 } deriving (Eq, Read, Show, Generic, Typeable)
1764data DateRangeAggRange = DateRangeFrom DateMathExpr
1765 | DateRangeTo DateMathExpr
1766 | DateRangeFromAndTo DateMathExpr DateMathExpr deriving (Eq, Read, Show, Generic, Typeable)
1768-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math> for more information.
1769data DateMathExpr = DateMathExpr DateMathAnchor [DateMathModifier] deriving (Eq, Read, Show, Generic, Typeable)
1772-- | Starting point for a date range. This along with the 'DateMathModifiers' gets you the date ES will start from.
1773data DateMathAnchor = DMNow
1774 | DMDate Day deriving (Eq, Read, Show, Generic, Typeable)
1776data DateMathModifier = AddTime Int DateMathUnit
1777 | SubtractTime Int DateMathUnit
1778 | RoundDownTo DateMathUnit deriving (Eq, Read, Show, Generic, Typeable)
1780data DateMathUnit = DMYear
1781 | DMMonth
1782 | DMWeek
1783 | DMDay
1784 | DMHour
1785 | DMMinute
1786 | DMSecond deriving (Eq, Read, Show, Generic, Typeable)
1788-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html> for more information.
1789data ValueCountAggregation = FieldValueCount FieldName
1790 | ScriptValueCount Script deriving (Eq, Read, Show, Generic, Typeable)
1792-- | 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.
1793data FilterAggregation = FilterAggregation { faFilter :: Filter
1794 , faAggs :: Maybe Aggregations} deriving (Eq, Read, Show, Generic, Typeable)
1796mkTermsAggregation :: Text -> TermsAggregation
1797mkTermsAggregation t = TermsAggregation (Left t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1799mkTermsScriptAggregation :: Text -> TermsAggregation
1800mkTermsScriptAggregation t = TermsAggregation (Right t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1802mkDateHistogram :: FieldName -> Interval -> DateHistogramAggregation
1803mkDateHistogram t i = DateHistogramAggregation t i Nothing Nothing Nothing Nothing Nothing Nothing
1805mkCardinalityAggregation :: FieldName -> CardinalityAggregation
1806mkCardinalityAggregation t = CardinalityAggregation t Nothing
1808instance ToJSON Version where
1809 toJSON Version {..} = object ["number" .= number
1810 ,"build_hash" .= build_hash
1811 ,"build_timestamp" .= build_timestamp
1812 ,"build_snapshot" .= build_snapshot
1813 ,"lucene_version" .= lucene_version]
1815instance FromJSON Version where
1816 parseJSON = withObject "Version" parse
1817 where parse o = Version
1818 <$> o .: "number"
1819 <*> o .: "build_hash"
1820 <*> o .: "build_timestamp"
1821 <*> o .: "build_snapshot"
1822 <*> o .: "lucene_version"
1824instance ToJSON VersionNumber where
1825 toJSON = toJSON . Vers.showVersion . versionNumber
1827instance FromJSON VersionNumber where
1828 parseJSON = withText "VersionNumber" (parse . T.unpack)
1829 where
1830 parse s = case filter (null . snd)(RP.readP_to_S Vers.parseVersion s) of
1831 [(v, _)] -> pure (VersionNumber v)
1832 [] -> fail ("Invalid version string " ++ s)
1833 xs -> fail ("Ambiguous version string " ++ s ++ " (" ++ intercalate ", " (Vers.showVersion . fst <$> xs) ++ ")")
1835instance ToJSON TermOrder where
1836 toJSON (TermOrder termSortField termSortOrder) = object [termSortField .= termSortOrder]
1838instance ToJSON TermInclusion where
1839 toJSON (TermInclusion x) = toJSON x
1840 toJSON (TermPattern pattern flags) = omitNulls [ "pattern" .= pattern,
1841 "flags" .= flags]
1843instance ToJSON CollectionMode where
1844 toJSON BreadthFirst = "breadth_first"
1845 toJSON DepthFirst = "depth_first"
1847instance ToJSON ExecutionHint where
1848 toJSON Ordinals = "ordinals"
1849 toJSON GlobalOrdinals = "global_ordinals"
1850 toJSON GlobalOrdinalsHash = "global_ordinals_hash"
1851 toJSON GlobalOrdinalsLowCardinality = "global_ordinals_low_cardinality"
1852 toJSON Map = "map"
1854instance ToJSON Interval where
1855 toJSON Year = "year"
1856 toJSON Quarter = "quarter"
1857 toJSON Month = "month"
1858 toJSON Week = "week"
1859 toJSON Day = "day"
1860 toJSON Hour = "hour"
1861 toJSON Minute = "minute"
1862 toJSON Second = "second"
1863 toJSON (FractionalInterval fraction interval) = toJSON $ show fraction ++ show interval
1865instance Show TimeInterval where
1866 show Weeks = "w"
1867 show Days = "d"
1868 show Hours = "h"
1869 show Minutes = "m"
1870 show Seconds = "s"
1872instance Read TimeInterval where
1873 readPrec = f =<< TR.get
1874 where
1875 f 'w' = return Weeks
1876 f 'd' = return Days
1877 f 'h' = return Hours
1878 f 'm' = return Minutes
1879 f 's' = return Seconds
1880 f _ = fail "TimeInterval expected one of w, d, h, m, s"
1882instance ToJSON Aggregation where
1883 toJSON (TermsAgg (TermsAggregation term include exclude order minDocCount size shardSize collectMode executionHint termAggs)) =
1884 omitNulls ["terms" .= omitNulls [ toJSON' term,
1885 "include" .= include,
1886 "exclude" .= exclude,
1887 "order" .= order,
1888 "min_doc_count" .= minDocCount,
1889 "size" .= size,
1890 "shard_size" .= shardSize,
1891 "collect_mode" .= collectMode,
1892 "execution_hint" .= executionHint
1893 ],
1894 "aggs" .= termAggs ]
1895 where
1896 toJSON' x = case x of { Left y -> "field" .= y; Right y -> "script" .= y }
1898 toJSON (CardinalityAgg (CardinalityAggregation field precisionThreshold)) =
1899 object ["cardinality" .= omitNulls [ "field" .= field,
1900 "precisionThreshold" .= precisionThreshold
1904 toJSON (DateHistogramAgg (DateHistogramAggregation field interval format preZone postZone preOffset postOffset dateHistoAggs)) =
1905 omitNulls ["date_histogram" .= omitNulls [ "field" .= field,
1906 "interval" .= interval,
1907 "format" .= format,
1908 "pre_zone" .= preZone,
1909 "post_zone" .= postZone,
1910 "pre_offset" .= preOffset,
1911 "post_offset" .= postOffset
1912 ],
1913 "aggs" .= dateHistoAggs ]
1914 toJSON (ValueCountAgg a) = object ["value_count" .= v]
1915 where v = case a of
1916 (FieldValueCount (FieldName n)) -> object ["field" .= n]
1917 (ScriptValueCount (Script s)) -> object ["script" .= s]
1918 toJSON (FilterAgg (FilterAggregation filt ags)) =
1919 omitNulls [ "filter" .= filt
1920 , "aggs" .= ags]
1921 toJSON (DateRangeAgg a) = object [ "date_range" .= a
1923 toJSON (MissingAgg (MissingAggregation{..})) =
1924 object ["missing" .= object ["field" .= maField]]
1926instance ToJSON DateRangeAggregation where
1927 toJSON DateRangeAggregation {..} =
1928 omitNulls [ "field" .= draField
1929 , "format" .= draFormat
1930 , "ranges" .= toList draRanges
1933instance ToJSON DateRangeAggRange where
1934 toJSON (DateRangeFrom e) = object [ "from" .= e ]
1935 toJSON (DateRangeTo e) = object [ "to" .= e ]
1936 toJSON (DateRangeFromAndTo f t) = object [ "from" .= f, "to" .= t ]
1938instance ToJSON DateMathExpr where
1939 toJSON (DateMathExpr a mods) = String (fmtA a <> mconcat (fmtMod <$> mods))
1940 where fmtA DMNow = "now"
1941 fmtA (DMDate date) = (T.pack $ showGregorian date) <> "||"
1942 fmtMod (AddTime n u) = "+" <> showText n <> fmtU u
1943 fmtMod (SubtractTime n u) = "-" <> showText n <> fmtU u
1944 fmtMod (RoundDownTo u) = "/" <> fmtU u
1945 fmtU DMYear = "y"
1946 fmtU DMMonth = "M"
1947 fmtU DMWeek = "w"
1948 fmtU DMDay = "d"
1949 fmtU DMHour = "h"
1950 fmtU DMMinute = "m"
1951 fmtU DMSecond = "s"
1954type AggregationResults = M.Map Text Value
1956class BucketAggregation a where
1957 key :: a -> BucketValue
1958 docCount :: a -> Int
1959 aggs :: a -> Maybe AggregationResults
1962data Bucket a = Bucket { buckets :: [a]} deriving (Read, Show)
1964data BucketValue = TextValue Text
1965 | ScientificValue Scientific
1966 | BoolValue Bool deriving (Read, Show)
1968data MissingResult = MissingResult { missingDocCount :: Int } deriving (Show)
1970data TermsResult = TermsResult { termKey :: BucketValue
1971 , termsDocCount :: Int
1972 , termsAggs :: Maybe AggregationResults } deriving (Read, Show)
1974data DateHistogramResult = DateHistogramResult { dateKey :: Int
1975 , dateKeyStr :: Maybe Text
1976 , dateDocCount :: Int
1977 , dateHistogramAggs :: Maybe AggregationResults } deriving (Read, Show)
1979data DateRangeResult = DateRangeResult { dateRangeKey :: Text
1980 , dateRangeFrom :: Maybe UTCTime
1981 , dateRangeFromAsString :: Maybe Text
1982 , dateRangeTo :: Maybe UTCTime
1983 , dateRangeToAsString :: Maybe Text
1984 , dateRangeDocCount :: Int
1985 , dateRangeAggs :: Maybe AggregationResults } deriving (Read, Show, Eq, Generic, Typeable)
1987toTerms :: Text -> AggregationResults -> Maybe (Bucket TermsResult)
1988toTerms = toAggResult
1990toDateHistogram :: Text -> AggregationResults -> Maybe (Bucket DateHistogramResult)
1991toDateHistogram = toAggResult
1993toMissing :: Text -> AggregationResults -> Maybe MissingResult
1994toMissing = toAggResult
1996toAggResult :: (FromJSON a) => Text -> AggregationResults -> Maybe a
1997toAggResult t a = M.lookup t a >>= deserialize
1998 where deserialize = parseMaybe parseJSON
2000instance BucketAggregation TermsResult where
2001 key = termKey
2002 docCount = termsDocCount
2003 aggs = termsAggs
2005instance BucketAggregation DateHistogramResult where
2006 key = TextValue . showText . dateKey
2007 docCount = dateDocCount
2008 aggs = dateHistogramAggs
2010instance BucketAggregation DateRangeResult where
2011 key = TextValue . dateRangeKey
2012 docCount = dateRangeDocCount
2013 aggs = dateRangeAggs
2015instance (FromJSON a, BucketAggregation a) => FromJSON (Bucket a) where
2016 parseJSON (Object v) = Bucket <$>
2017 v .: "buckets"
2018 parseJSON _ = mempty
2020instance FromJSON BucketValue where
2021 parseJSON (String t) = return $ TextValue t
2022 parseJSON (Number s) = return $ ScientificValue s
2023 parseJSON (Bool b) = return $ BoolValue b
2024 parseJSON _ = mempty
2026instance FromJSON MissingResult where
2027 parseJSON = withObject "MissingResult" parse
2028 where parse v = MissingResult <$> v .: "doc_count"
2030instance FromJSON TermsResult where
2031 parseJSON (Object v) = TermsResult <$>
2032 v .: "key" <*>
2033 v .: "doc_count" <*>
2034 v .:? "aggregations"
2035 parseJSON _ = mempty
2037instance FromJSON DateHistogramResult where
2038 parseJSON (Object v) = DateHistogramResult <$>
2039 v .: "key" <*>
2040 v .:? "key_as_string" <*>
2041 v .: "doc_count" <*>
2042 v .:? "aggregations"
2043 parseJSON _ = mempty
2045instance FromJSON DateRangeResult where
2046 parseJSON = withObject "DateRangeResult" parse
2047 where parse v = DateRangeResult <$>
2048 v .: "key" <*>
2049 (fmap posixMS <$> v .:? "from") <*>
2050 v .:? "from_as_string" <*>
2051 (fmap posixMS <$> v .:? "to") <*>
2052 v .:? "to_as_string" <*>
2053 v .: "doc_count" <*>
2054 v .:? "aggregations"
2056instance FromJSON POSIXMS where
2057 parseJSON = withScientific "POSIXMS" (return . parse)
2058 where parse n = let n' = truncate n :: Integer
2059 in POSIXMS (posixSecondsToUTCTime (fromInteger (n' `div` 1000)))
2061instance Monoid Filter where
2062 mempty = IdentityFilter
2063 mappend a b = AndFilter [a, b] defaultCache
2065instance Seminearring Filter where
2066 a <||> b = OrFilter [a, b] defaultCache
2068instance ToJSON Filter where
2069 toJSON (AndFilter filters cache) =
2070 object ["and" .=
2071 object [ "filters" .= fmap toJSON filters
2072 , "_cache" .= cache]]
2074 toJSON (OrFilter filters cache) =
2075 object ["or" .=
2076 object [ "filters" .= fmap toJSON filters
2077 , "_cache" .= cache]]
2079 toJSON (NotFilter notFilter cache) =
2080 object ["not" .=
2081 object ["filter" .= notFilter
2082 , "_cache" .= cache]]
2084 toJSON (IdentityFilter) =
2085 object ["match_all" .= object []]
2087 toJSON (TermFilter (Term termFilterField termFilterValue) cache) =
2088 object ["term" .= object base]
2089 where base = [termFilterField .= termFilterValue,
2090 "_cache" .= cache]
2092 toJSON (ExistsFilter (FieldName fieldName)) =
2093 object ["exists" .= object
2094 ["field" .= fieldName]]
2096 toJSON (BoolFilter boolMatch) =
2097 object ["bool" .= boolMatch]
2099 toJSON (GeoBoundingBoxFilter bbConstraint) =
2100 object ["geo_bounding_box" .= bbConstraint]
2102 toJSON (GeoDistanceFilter (GeoPoint (FieldName distanceGeoField) geoDistLatLon)
2103 distance distanceType optimizeBbox cache) =
2104 object ["geo_distance" .=
2105 object ["distance" .= distance
2106 , "distance_type" .= distanceType
2107 , "optimize_bbox" .= optimizeBbox
2108 , distanceGeoField .= geoDistLatLon
2109 , "_cache" .= cache]]
2111 toJSON (GeoDistanceRangeFilter (GeoPoint (FieldName gddrField) drLatLon)
2112 (DistanceRange geoDistRangeDistFrom drDistanceTo)) =
2113 object ["geo_distance_range" .=
2114 object ["from" .= geoDistRangeDistFrom
2115 , "to" .= drDistanceTo
2116 , gddrField .= drLatLon]]
2118 toJSON (GeoPolygonFilter (FieldName geoPolygonFilterField) latLons) =
2119 object ["geo_polygon" .=
2120 object [geoPolygonFilterField .=
2121 object ["points" .= fmap toJSON latLons]]]
2123 toJSON (IdsFilter (MappingName mappingName) values) =
2124 object ["ids" .=
2125 object ["type" .= mappingName
2126 , "values" .= fmap unpackId values]]
2128 toJSON (LimitFilter limit) =
2129 object ["limit" .= object ["value" .= limit]]
2131 toJSON (MissingFilter (FieldName fieldName) (Existence existence) (NullValue nullValue)) =
2132 object ["missing" .=
2133 object ["field" .= fieldName
2134 , "existence" .= existence
2135 , "null_value" .= nullValue]]
2137 toJSON (PrefixFilter (FieldName fieldName) fieldValue cache) =
2138 object ["prefix" .=
2139 object [fieldName .= fieldValue
2140 , "_cache" .= cache]]
2142 toJSON (QueryFilter query False) =
2143 object ["query" .= toJSON query ]
2144 toJSON (QueryFilter query True) =
2145 object ["fquery" .=
2146 object [ "query" .= toJSON query
2147 , "_cache" .= True ]]
2149 toJSON (RangeFilter (FieldName fieldName) rangeValue rangeExecution cache) =
2150 object ["range" .=
2151 object [ fieldName .= object (rangeValueToPair rangeValue)
2152 , "execution" .= rangeExecution
2153 , "_cache" .= cache]]
2155 toJSON (RegexpFilter (FieldName fieldName)
2156 (Regexp regexText) flags (CacheName cacheName) cache (CacheKey cacheKey)) =
2157 object ["regexp" .=
2158 object [fieldName .=
2159 object ["value" .= regexText
2160 , "flags" .= flags]
2161 , "_name" .= cacheName
2162 , "_cache" .= cache
2163 , "_cache_key" .= cacheKey]]
2165instance FromJSON Filter where
2166 parseJSON = withObject "Filter" parse
2167 where parse o = andFilter `taggedWith` "and"
2168 <|> orFilter `taggedWith` "or"
2169 <|> notFilter `taggedWith` "not"
2170 <|> identityFilter `taggedWith` "match_all"
2171 <|> boolFilter `taggedWith` "bool"
2172 <|> existsFilter `taggedWith` "exists"
2173 <|> geoBoundingBoxFilter `taggedWith` "geo_bounding_box"
2174 <|> geoDistanceFilter `taggedWith` "geo_distance"
2175 <|> geoDistanceRangeFilter `taggedWith` "geo_distance_range"
2176 <|> geoPolygonFilter `taggedWith` "geo_polygon"
2177 <|> idsFilter `taggedWith` "ids"
2178 <|> limitFilter `taggedWith` "limit"
2179 <|> missingFilter `taggedWith` "missing"
2180 <|> prefixFilter `taggedWith` "prefix"
2181 <|> queryFilter `taggedWith` "query"
2182 <|> fqueryFilter `taggedWith` "fquery"
2183 <|> rangeFilter `taggedWith` "range"
2184 <|> regexpFilter `taggedWith` "regexp"
2185 <|> termFilter `taggedWith` "term"
2186 where taggedWith parser k = parser =<< o .: k
2187 andFilter o = AndFilter <$> o .: "filters"
2188 <*> o .:? "_cache" .!= defaultCache
2189 orFilter o = OrFilter <$> o .: "filters"
2190 <*> o .:? "_cache" .!= defaultCache
2191 notFilter o = NotFilter <$> o .: "filter"
2192 <*> o .: "_cache" .!= defaultCache
2193 identityFilter :: Object -> Parser Filter
2194 identityFilter m
2195 | HM.null m = pure IdentityFilter
2196 | otherwise = fail ("Identityfilter expected empty object but got " <> show m)
2197 boolFilter = pure . BoolFilter
2198 existsFilter o = ExistsFilter <$> o .: "field"
2199 geoBoundingBoxFilter = pure . GeoBoundingBoxFilter
2200 geoDistanceFilter o = do
2201 case HM.toList (deleteSeveral ["distance", "distance_type", "optimize_bbox", "_cache"] o) of
2202 [(fn, v)] -> do
2203 gp <- GeoPoint (FieldName fn) <$> parseJSON v
2204 GeoDistanceFilter gp <$> o .: "distance"
2205 <*> o .: "distance_type"
2206 <*> o .: "optimize_bbox"
2207 <*> o .:? "_cache" .!= defaultCache
2208 _ -> fail "Could not find GeoDistanceFilter field name"
2209 geoDistanceRangeFilter o = do
2210 case HM.toList (deleteSeveral ["from", "to"] o) of
2211 [(fn, v)] -> do
2212 gp <- GeoPoint (FieldName fn) <$> parseJSON v
2213 rng <- DistanceRange <$> o .: "from" <*> o .: "to"
2214 return (GeoDistanceRangeFilter gp rng)
2215 _ -> fail "Could not find GeoDistanceRangeFilter field name"
2216 geoPolygonFilter = fieldTagged $ \fn o -> GeoPolygonFilter fn <$> o .: "points"
2217 idsFilter o = IdsFilter <$> o .: "type"
2218 <*> o .: "values"
2219 limitFilter o = LimitFilter <$> o .: "value"
2220 missingFilter o = MissingFilter <$> o .: "field"
2221 <*> o .: "existence"
2222 <*> o .: "null_value"
2223 prefixFilter o = case HM.toList (HM.delete "_cache" o) of
2224 [(fn, String v)] -> PrefixFilter (FieldName fn) v <$> o .:? "_cache" .!= defaultCache
2225 _ -> fail "Could not parse PrefixFilter"
2227 queryFilter q = pure (QueryFilter q False)
2228 fqueryFilter o = QueryFilter <$> o .: "query" <*> pure True
2229 rangeFilter o = case HM.toList (deleteSeveral ["execution", "_cache"] o) of
2230 [(fn, v)] -> RangeFilter (FieldName fn)
2231 <$> parseJSON v
2232 <*> o .: "execution"
2233 <*> o .:? "_cache" .!= defaultCache
2234 _ -> fail "Could not find field name for RangeFilter"
2235 regexpFilter o = case HM.toList (deleteSeveral ["_name", "_cache", "_cache_key"] o) of
2236 [(fn, Object o')] -> RegexpFilter (FieldName fn)
2237 <$> o' .: "value"
2238 <*> o' .: "flags"
2239 <*> o .: "_name"
2240 <*> o .:? "_cache" .!= defaultCache
2241 <*> o .: "_cache_key"
2242 _ -> fail "Could not find field name for RegexpFilter"
2243 termFilter o = case HM.toList (HM.delete "_cache" o) of
2244 [(termField, String termVal)] -> TermFilter (Term termField termVal)
2245 <$> o .:? "_cache" .!= defaultCache
2246 _ -> fail "Could not find term field for TermFilter"
2248fieldTagged :: Monad m => (FieldName -> Object -> m a) -> Object -> m a
2249fieldTagged f o = case HM.toList o of
2250 [(k, Object o')] -> f (FieldName k) o'
2251 _ -> fail "Expected object with 1 field-named key"
2253instance ToJSON GeoPoint where
2254 toJSON (GeoPoint (FieldName geoPointField) geoPointLatLon) =
2255 object [ geoPointField .= geoPointLatLon ]
2258instance ToJSON Query where
2259 toJSON (TermQuery (Term termQueryField termQueryValue) boost) =
2260 object [ "term" .=
2261 object [termQueryField .= object merged]]
2262 where
2263 base = [ "value" .= termQueryValue ]
2264 boosted = maybe [] (return . ("boost" .=)) boost
2265 merged = mappend base boosted
2267 toJSON (TermsQuery fieldName terms) =
2268 object [ "terms" .= object conjoined ]
2269 where conjoined = [fieldName .= terms]
2271 toJSON (IdsQuery idsQueryMappingName docIds) =
2272 object [ "ids" .= object conjoined ]
2273 where conjoined = [ "type" .= idsQueryMappingName
2274 , "values" .= fmap toJSON docIds ]
2276 toJSON (QueryQueryStringQuery qQueryStringQuery) =
2277 object [ "query_string" .= qQueryStringQuery ]
2279 toJSON (QueryMatchQuery matchQuery) =
2280 object [ "match" .= matchQuery ]
2282 toJSON (QueryMultiMatchQuery multiMatchQuery) =
2283 toJSON multiMatchQuery
2285 toJSON (QueryBoolQuery boolQuery) =
2286 object [ "bool" .= boolQuery ]
2288 toJSON (QueryBoostingQuery boostingQuery) =
2289 object [ "boosting" .= boostingQuery ]
2291 toJSON (QueryCommonTermsQuery commonTermsQuery) =
2292 object [ "common" .= commonTermsQuery ]
2294 toJSON (ConstantScoreFilter csFilter boost) =
2295 object ["constant_score" .= object ["filter" .= csFilter
2296 , "boost" .= boost]]
2298 toJSON (ConstantScoreQuery query boost) =
2299 object ["constant_score" .= object ["query" .= query
2300 , "boost" .= boost]]
2302 toJSON (QueryDisMaxQuery disMaxQuery) =
2303 object [ "dis_max" .= disMaxQuery ]
2305 toJSON (QueryFilteredQuery qFilteredQuery) =
2306 object [ "filtered" .= qFilteredQuery ]
2308 toJSON (QueryFuzzyLikeThisQuery fuzzyQuery) =
2309 object [ "fuzzy_like_this" .= fuzzyQuery ]
2311 toJSON (QueryFuzzyLikeFieldQuery fuzzyFieldQuery) =
2312 object [ "fuzzy_like_this_field" .= fuzzyFieldQuery ]
2314 toJSON (QueryFuzzyQuery fuzzyQuery) =
2315 object [ "fuzzy" .= fuzzyQuery ]
2317 toJSON (QueryHasChildQuery childQuery) =
2318 object [ "has_child" .= childQuery ]
2320 toJSON (QueryHasParentQuery parentQuery) =
2321 object [ "has_parent" .= parentQuery ]
2323 toJSON (QueryIndicesQuery qIndicesQuery) =
2324 object [ "indices" .= qIndicesQuery ]
2326 toJSON (MatchAllQuery boost) =
2327 object [ "match_all" .= omitNulls [ "boost" .= boost ] ]
2329 toJSON (QueryMoreLikeThisQuery query) =
2330 object [ "more_like_this" .= query ]
2332 toJSON (QueryMoreLikeThisFieldQuery query) =
2333 object [ "more_like_this_field" .= query ]
2335 toJSON (QueryNestedQuery query) =
2336 object [ "nested" .= query ]
2338 toJSON (QueryPrefixQuery query) =
2339 object [ "prefix" .= query ]
2341 toJSON (QueryRangeQuery query) =
2342 object [ "range" .= query ]
2344 toJSON (QueryRegexpQuery query) =
2345 object [ "regexp" .= query ]
2347 toJSON (QuerySimpleQueryStringQuery query) =
2348 object [ "simple_query_string" .= query ]
2350instance FromJSON Query where
2351 parseJSON v = withObject "Query" parse v
2352 where parse o = termQuery `taggedWith` "term"
2353 <|> termsQuery `taggedWith` "terms"
2354 <|> idsQuery `taggedWith` "ids"
2355 <|> queryQueryStringQuery `taggedWith` "query_string"
2356 <|> queryMatchQuery `taggedWith` "match"
2357 <|> queryMultiMatchQuery
2358 <|> queryBoolQuery `taggedWith` "bool"
2359 <|> queryBoostingQuery `taggedWith` "boosting"
2360 <|> queryCommonTermsQuery `taggedWith` "common"
2361 <|> constantScoreFilter `taggedWith` "constant_score"
2362 <|> constantScoreQuery `taggedWith` "constant_score"
2363 <|> queryDisMaxQuery `taggedWith` "dis_max"
2364 <|> queryFilteredQuery `taggedWith` "filtered"
2365 <|> queryFuzzyLikeThisQuery `taggedWith` "fuzzy_like_this"
2366 <|> queryFuzzyLikeFieldQuery `taggedWith` "fuzzy_like_this_field"
2367 <|> queryFuzzyQuery `taggedWith` "fuzzy"
2368 <|> queryHasChildQuery `taggedWith` "has_child"
2369 <|> queryHasParentQuery `taggedWith` "has_parent"
2370 <|> queryIndicesQuery `taggedWith` "indices"
2371 <|> matchAllQuery `taggedWith` "match_all"
2372 <|> queryMoreLikeThisQuery `taggedWith` "more_like_this"
2373 <|> queryMoreLikeThisFieldQuery `taggedWith` "more_like_this_field"
2374 <|> queryNestedQuery `taggedWith` "nested"
2375 <|> queryPrefixQuery `taggedWith` "prefix"
2376 <|> queryRangeQuery `taggedWith` "range"
2377 <|> queryRegexpQuery `taggedWith` "regexp"
2378 <|> querySimpleQueryStringQuery `taggedWith` "simple_query_string"
2379 where taggedWith parser k = parser =<< o .: k
2380 termQuery = fieldTagged $ \(FieldName fn) o ->
2381 TermQuery <$> (Term fn <$> o .: "value") <*> o .:? "boost"
2382 termsQuery o = case HM.toList o of
2383 [(fn, vs)] -> do vals <- parseJSON vs
2384 case vals of
2385 x:xs -> return (TermsQuery fn (x :| xs))
2386 _ -> fail "Expected non empty list of values"
2387 _ -> fail "Expected object with 1 field-named key"
2388 idsQuery o = IdsQuery <$> o .: "type"
2389 <*> o .: "values"
2390 queryQueryStringQuery = pure . QueryQueryStringQuery
2391 queryMatchQuery = pure . QueryMatchQuery
2392 queryMultiMatchQuery = QueryMultiMatchQuery <$> parseJSON v
2393 queryBoolQuery = pure . QueryBoolQuery
2394 queryBoostingQuery = pure . QueryBoostingQuery
2395 queryCommonTermsQuery = pure . QueryCommonTermsQuery
2396 constantScoreFilter o = case HM.lookup "filter" o of
2397 Just x -> ConstantScoreFilter <$> parseJSON x
2398 <*> o .: "boost"
2399 _ -> fail "Does not appear to be a ConstantScoreFilter"
2400 constantScoreQuery o = case HM.lookup "query" o of
2401 Just x -> ConstantScoreQuery <$> parseJSON x
2402 <*> o .: "boost"
2403 _ -> fail "Does not appear to be a ConstantScoreQuery"
2404 queryDisMaxQuery = pure . QueryDisMaxQuery
2405 queryFilteredQuery = pure . QueryFilteredQuery
2406 queryFuzzyLikeThisQuery = pure . QueryFuzzyLikeThisQuery
2407 queryFuzzyLikeFieldQuery = pure . QueryFuzzyLikeFieldQuery
2408 queryFuzzyQuery = pure . QueryFuzzyQuery
2409 queryHasChildQuery = pure . QueryHasChildQuery
2410 queryHasParentQuery = pure . QueryHasParentQuery
2411 queryIndicesQuery = pure . QueryIndicesQuery
2412 matchAllQuery o = MatchAllQuery <$> o .:? "boost"
2413 queryMoreLikeThisQuery = pure . QueryMoreLikeThisQuery
2414 queryMoreLikeThisFieldQuery = pure . QueryMoreLikeThisFieldQuery
2415 queryNestedQuery = pure . QueryNestedQuery
2416 queryPrefixQuery = pure . QueryPrefixQuery
2417 queryRangeQuery = pure . QueryRangeQuery
2418 queryRegexpQuery = pure . QueryRegexpQuery
2419 querySimpleQueryStringQuery = pure . QuerySimpleQueryStringQuery
2422omitNulls :: [(Text, Value)] -> Value
2423omitNulls = object . filter notNull where
2424 notNull (_, Null) = False
2425 notNull (_, Array a) = (not . V.null) a
2426 notNull _ = True
2429instance ToJSON SimpleQueryStringQuery where
2430 toJSON SimpleQueryStringQuery {..} =
2431 omitNulls (base ++ maybeAdd)
2432 where base = [ "query" .= simpleQueryStringQuery ]
2433 maybeAdd = [ "fields" .= simpleQueryStringField
2434 , "default_operator" .= simpleQueryStringOperator
2435 , "analyzer" .= simpleQueryStringAnalyzer
2436 , "flags" .= simpleQueryStringFlags
2437 , "lowercase_expanded_terms" .= simpleQueryStringLowercaseExpanded
2438 , "locale" .= simpleQueryStringLocale ]
2440instance FromJSON SimpleQueryStringQuery where
2441 parseJSON = withObject "SimpleQueryStringQuery" parse
2442 where parse o = SimpleQueryStringQuery <$> o .: "query"
2443 <*> o .:? "fields"
2444 <*> o .:? "default_operator"
2445 <*> o .:? "analyzer"
2446 <*> (parseFlags <$> o .:? "flags")
2447 <*> o .:? "lowercase_expanded_terms"
2448 <*> o .:? "locale"
2449 parseFlags (Just (x:xs)) = Just (x :| xs)
2450 parseFlags _ = Nothing
2452instance ToJSON FieldOrFields where
2453 toJSON (FofField fieldName) =
2454 toJSON fieldName
2455 toJSON (FofFields fieldNames) =
2456 toJSON fieldNames
2458instance FromJSON FieldOrFields where
2459 parseJSON v = FofField <$> parseJSON v
2460 <|> FofFields <$> (parseNEJSON =<< parseJSON v)
2462instance ToJSON SimpleQueryFlag where
2463 toJSON SimpleQueryAll = "ALL"
2464 toJSON SimpleQueryNone = "NONE"
2465 toJSON SimpleQueryAnd = "AND"
2466 toJSON SimpleQueryOr = "OR"
2467 toJSON SimpleQueryPrefix = "PREFIX"
2468 toJSON SimpleQueryPhrase = "PHRASE"
2469 toJSON SimpleQueryPrecedence = "PRECEDENCE"
2470 toJSON SimpleQueryEscape = "ESCAPE"
2471 toJSON SimpleQueryWhitespace = "WHITESPACE"
2472 toJSON SimpleQueryFuzzy = "FUZZY"
2473 toJSON SimpleQueryNear = "NEAR"
2474 toJSON SimpleQuerySlop = "SLOP"
2476instance FromJSON SimpleQueryFlag where
2477 parseJSON = withText "SimpleQueryFlag" parse
2478 where parse "ALL" = pure SimpleQueryAll
2479 parse "NONE" = pure SimpleQueryNone
2480 parse "AND" = pure SimpleQueryAnd
2481 parse "OR" = pure SimpleQueryOr
2482 parse "PREFIX" = pure SimpleQueryPrefix
2483 parse "PHRASE" = pure SimpleQueryPhrase
2484 parse "PRECEDENCE" = pure SimpleQueryPrecedence
2485 parse "ESCAPE" = pure SimpleQueryEscape
2486 parse "WHITESPACE" = pure SimpleQueryWhitespace
2487 parse "FUZZY" = pure SimpleQueryFuzzy
2488 parse "NEAR" = pure SimpleQueryNear
2489 parse "SLOP" = pure SimpleQuerySlop
2490 parse f = fail ("Unexpected SimpleQueryFlag: " <> show f)
2492instance ToJSON RegexpQuery where
2493 toJSON (RegexpQuery (FieldName rqQueryField)
2494 (Regexp regexpQueryQuery) rqQueryFlags
2495 rqQueryBoost) =
2496 object [ rqQueryField .= omitNulls base ]
2497 where base = [ "value" .= regexpQueryQuery
2498 , "flags" .= rqQueryFlags
2499 , "boost" .= rqQueryBoost ]
2501instance FromJSON RegexpQuery where
2502 parseJSON = withObject "RegexpQuery" parse
2503 where parse = fieldTagged $ \fn o ->
2504 RegexpQuery fn
2505 <$> o .: "value"
2506 <*> o .: "flags"
2507 <*> o .:? "boost"
2509instance ToJSON QueryStringQuery where
2510 toJSON (QueryStringQuery qsQueryString
2511 qsDefaultField qsOperator
2512 qsAnalyzer qsAllowWildcard
2513 qsLowercaseExpanded qsEnablePositionIncrements
2514 qsFuzzyMaxExpansions qsFuzziness
2515 qsFuzzyPrefixLength qsPhraseSlop
2516 qsBoost qsAnalyzeWildcard
2517 qsGeneratePhraseQueries qsMinimumShouldMatch
2518 qsLenient qsLocale) =
2519 omitNulls base
2520 where
2521 base = [ "query" .= qsQueryString
2522 , "default_field" .= qsDefaultField
2523 , "default_operator" .= qsOperator
2524 , "analyzer" .= qsAnalyzer
2525 , "allow_leading_wildcard" .= qsAllowWildcard
2526 , "lowercase_expanded_terms" .= qsLowercaseExpanded
2527 , "enable_position_increments" .= qsEnablePositionIncrements
2528 , "fuzzy_max_expansions" .= qsFuzzyMaxExpansions
2529 , "fuzziness" .= qsFuzziness
2530 , "fuzzy_prefix_length" .= qsFuzzyPrefixLength
2531 , "phrase_slop" .= qsPhraseSlop
2532 , "boost" .= qsBoost
2533 , "analyze_wildcard" .= qsAnalyzeWildcard
2534 , "auto_generate_phrase_queries" .= qsGeneratePhraseQueries
2535 , "minimum_should_match" .= qsMinimumShouldMatch
2536 , "lenient" .= qsLenient
2537 , "locale" .= qsLocale ]
2539instance FromJSON QueryStringQuery where
2540 parseJSON = withObject "QueryStringQuery" parse
2541 where parse o = QueryStringQuery
2542 <$> o .: "query"
2543 <*> o .:? "default_field"
2544 <*> o .:? "default_operator"
2545 <*> o .:? "analyzer"
2546 <*> o .:? "allow_leading_wildcard"
2547 <*> o .:? "lowercase_expanded_terms"
2548 <*> o .:? "enable_position_increments"
2549 <*> o .:? "fuzzy_max_expansions"
2550 <*> o .:? "fuzziness"
2551 <*> o .:? "fuzzy_prefix_length"
2552 <*> o .:? "phrase_slop"
2553 <*> o .:? "boost"
2554 <*> o .:? "analyze_wildcard"
2555 <*> o .:? "auto_generate_phrase_queries"
2556 <*> o .:? "minimum_should_match"
2557 <*> o .:? "lenient"
2558 <*> o .:? "locale"
2560instance ToJSON RangeQuery where
2561 toJSON (RangeQuery (FieldName fieldName) range boost) =
2562 object [ fieldName .= object conjoined ]
2563 where conjoined = [ "boost" .= boost ] ++ (rangeValueToPair range)
2565instance FromJSON RangeQuery where
2566 parseJSON = withObject "RangeQuery" parse
2567 where parse = fieldTagged $ \fn o ->
2568 RangeQuery fn
2569 <$> parseJSON (Object o)
2570 <*> o .: "boost"
2572instance FromJSON RangeValue where
2573 parseJSON = withObject "RangeValue" parse
2574 where parse o = parseDate o
2575 <|> parseDouble o
2576 parseDate o = do lt <- o .:? "lt"
2577 lte <- o .:? "lte"
2578 gt <- o .:? "gt"
2579 gte <- o .:? "gte"
2580 case (lt, lte, gt, gte) of
2581 (Just a, _, Just b, _) -> return (RangeDateGtLt (GreaterThanD b) (LessThanD a))
2582 (Just a, _, _, Just b)-> return (RangeDateGteLt (GreaterThanEqD b) (LessThanD a))
2583 (_, Just a, Just b, _)-> return (RangeDateGtLte (GreaterThanD b) (LessThanEqD a))
2584 (_, Just a, _, Just b)-> return (RangeDateGteLte (GreaterThanEqD b) (LessThanEqD a))
2585 (_, _, Just a, _)-> return (RangeDateGt (GreaterThanD a))
2586 (Just a, _, _, _)-> return (RangeDateLt (LessThanD a))
2587 (_, _, _, Just a)-> return (RangeDateGte (GreaterThanEqD a))
2588 (_, Just a, _, _)-> return (RangeDateLte (LessThanEqD a))
2589 (Nothing, Nothing, Nothing, Nothing) -> mzero
2590 parseDouble o = do lt <- o .:? "lt"
2591 lte <- o .:? "lte"
2592 gt <- o .:? "gt"
2593 gte <- o .:? "gte"
2594 case (lt, lte, gt, gte) of
2595 (Just a, _, Just b, _) -> return (RangeDoubleGtLt (GreaterThan b) (LessThan a))
2596 (Just a, _, _, Just b)-> return (RangeDoubleGteLt (GreaterThanEq b) (LessThan a))
2597 (_, Just a, Just b, _)-> return (RangeDoubleGtLte (GreaterThan b) (LessThanEq a))
2598 (_, Just a, _, Just b)-> return (RangeDoubleGteLte (GreaterThanEq b) (LessThanEq a))
2599 (_, _, Just a, _)-> return (RangeDoubleGt (GreaterThan a))
2600 (Just a, _, _, _)-> return (RangeDoubleLt (LessThan a))
2601 (_, _, _, Just a)-> return (RangeDoubleGte (GreaterThanEq a))
2602 (_, Just a, _, _)-> return (RangeDoubleLte (LessThanEq a))
2603 (Nothing, Nothing, Nothing, Nothing) -> mzero
2605instance ToJSON PrefixQuery where
2606 toJSON (PrefixQuery (FieldName fieldName) queryValue boost) =
2607 object [ fieldName .= omitNulls base ]
2608 where base = [ "value" .= queryValue
2609 , "boost" .= boost ]
2611instance FromJSON PrefixQuery where
2612 parseJSON = withObject "PrefixQuery" parse
2613 where parse = fieldTagged $ \fn o ->
2614 PrefixQuery fn
2615 <$> o .: "value"
2616 <*> o .:? "boost"
2618instance ToJSON NestedQuery where
2619 toJSON (NestedQuery nqPath nqScoreType nqQuery) =
2620 object [ "path" .= nqPath
2621 , "score_mode" .= nqScoreType
2622 , "query" .= nqQuery ]
2624instance FromJSON NestedQuery where
2625 parseJSON = withObject "NestedQuery" parse
2626 where parse o = NestedQuery
2627 <$> o .: "path"
2628 <*> o .: "score_mode"
2629 <*> o .: "query"
2631instance ToJSON MoreLikeThisFieldQuery where
2632 toJSON (MoreLikeThisFieldQuery text (FieldName fieldName)
2633 percent mtf mqt stopwords mindf maxdf
2634 minwl maxwl boostTerms boost analyzer) =
2635 object [ fieldName .= omitNulls base ]
2636 where base = [ "like_text" .= text
2637 , "percent_terms_to_match" .= percent
2638 , "min_term_freq" .= mtf
2639 , "max_query_terms" .= mqt
2640 , "stop_words" .= stopwords
2641 , "min_doc_freq" .= mindf
2642 , "max_doc_freq" .= maxdf
2643 , "min_word_length" .= minwl
2644 , "max_word_length" .= maxwl
2645 , "boost_terms" .= boostTerms
2646 , "boost" .= boost
2647 , "analyzer" .= analyzer ]
2649instance FromJSON MoreLikeThisFieldQuery where
2650 parseJSON = withObject "MoreLikeThisFieldQuery" parse
2651 where parse = fieldTagged $ \fn o ->
2652 MoreLikeThisFieldQuery
2653 <$> o .: "like_text"
2654 <*> pure fn
2655 <*> o .:? "percent_terms_to_match"
2656 <*> o .:? "min_term_freq"
2657 <*> o .:? "max_query_terms"
2658 -- <*> (optionalNE =<< o .:? "stop_words")
2659 <*> o .:? "stop_words"
2660 <*> o .:? "min_doc_freq"
2661 <*> o .:? "max_doc_freq"
2662 <*> o .:? "min_word_length"
2663 <*> o .:? "max_word_length"
2664 <*> o .:? "boost_terms"
2665 <*> o .:? "boost"
2666 <*> o .:? "analyzer"
2667 -- optionalNE = maybe (pure Nothing) (fmap Just . parseNEJSON)
2669instance ToJSON MoreLikeThisQuery where
2670 toJSON (MoreLikeThisQuery text fields percent
2671 mtf mqt stopwords mindf maxdf
2672 minwl maxwl boostTerms boost analyzer) =
2673 omitNulls base
2674 where base = [ "like_text" .= text
2675 , "fields" .= fields
2676 , "percent_terms_to_match" .= percent
2677 , "min_term_freq" .= mtf
2678 , "max_query_terms" .= mqt
2679 , "stop_words" .= stopwords
2680 , "min_doc_freq" .= mindf
2681 , "max_doc_freq" .= maxdf
2682 , "min_word_length" .= minwl
2683 , "max_word_length" .= maxwl
2684 , "boost_terms" .= boostTerms
2685 , "boost" .= boost
2686 , "analyzer" .= analyzer ]
2688instance FromJSON MoreLikeThisQuery where
2689 parseJSON = withObject "MoreLikeThisQuery" parse
2690 where parse o = MoreLikeThisQuery
2691 <$> o .: "like_text"
2692 -- <*> (optionalNE =<< o .:? "fields")
2693 <*> o .:? "fields"
2694 <*> o .:? "percent_terms_to_match"
2695 <*> o .:? "min_term_freq"
2696 <*> o .:? "max_query_terms"
2697 -- <*> (optionalNE =<< o .:? "stop_words")
2698 <*> o .:? "stop_words"
2699 <*> o .:? "min_doc_freq"
2700 <*> o .:? "max_doc_freq"
2701 <*> o .:? "min_word_length"
2702 <*> o .:? "max_word_length"
2703 <*> o .:? "boost_terms"
2704 <*> o .:? "boost"
2705 <*> o .:? "analyzer"
2706 -- optionalNE = maybe (pure Nothing) (fmap Just . parseNEJSON)
2708instance ToJSON IndicesQuery where
2709 toJSON (IndicesQuery indices query noMatch) =
2710 omitNulls [ "indices" .= indices
2711 , "no_match_query" .= noMatch
2712 , "query" .= query ]
2714instance FromJSON IndicesQuery where
2715 parseJSON = withObject "IndicesQuery" parse
2716 where parse o = IndicesQuery
2717 <$> o .:? "indices" .!= []
2718 <*> o .: "query"
2719 <*> o .:? "no_match_query"
2721instance ToJSON HasParentQuery where
2722 toJSON (HasParentQuery queryType query scoreType) =
2723 omitNulls [ "parent_type" .= queryType
2724 , "score_type" .= scoreType
2725 , "query" .= query ]
2727instance FromJSON HasParentQuery where
2728 parseJSON = withObject "HasParentQuery" parse
2729 where parse o = HasParentQuery
2730 <$> o .: "parent_type"
2731 <*> o .: "query"
2732 <*> o .:? "score_type"
2734instance ToJSON HasChildQuery where
2735 toJSON (HasChildQuery queryType query scoreType) =
2736 omitNulls [ "query" .= query
2737 , "score_type" .= scoreType
2738 , "type" .= queryType ]
2740instance FromJSON HasChildQuery where
2741 parseJSON = withObject "HasChildQuery" parse
2742 where parse o = HasChildQuery
2743 <$> o .: "type"
2744 <*> o .: "query"
2745 <*> o .:? "score_type"
2747instance ToJSON FuzzyQuery where
2748 toJSON (FuzzyQuery (FieldName fieldName) queryText
2749 prefixLength maxEx fuzziness boost) =
2750 object [ fieldName .= omitNulls base ]
2751 where base = [ "value" .= queryText
2752 , "fuzziness" .= fuzziness
2753 , "prefix_length" .= prefixLength
2754 , "boost" .= boost
2755 , "max_expansions" .= maxEx ]
2757instance FromJSON FuzzyQuery where
2758 parseJSON = withObject "FuzzyQuery" parse
2759 where parse = fieldTagged $ \fn o ->
2760 FuzzyQuery fn
2761 <$> o .: "value"
2762 <*> o .: "prefix_length"
2763 <*> o .: "max_expansions"
2764 <*> o .: "fuzziness"
2765 <*> o .:? "boost"
2767instance ToJSON FuzzyLikeFieldQuery where
2768 toJSON (FuzzyLikeFieldQuery (FieldName fieldName)
2769 fieldText maxTerms ignoreFreq fuzziness prefixLength
2770 boost analyzer) =
2771 object [ fieldName .=
2772 omitNulls [ "like_text" .= fieldText
2773 , "max_query_terms" .= maxTerms
2774 , "ignore_tf" .= ignoreFreq
2775 , "fuzziness" .= fuzziness
2776 , "prefix_length" .= prefixLength
2777 , "analyzer" .= analyzer
2778 , "boost" .= boost ]]
2780instance FromJSON FuzzyLikeFieldQuery where
2781 parseJSON = withObject "FuzzyLikeFieldQuery" parse
2782 where parse = fieldTagged $ \fn o ->
2783 FuzzyLikeFieldQuery fn
2784 <$> o .: "like_text"
2785 <*> o .: "max_query_terms"
2786 <*> o .: "ignore_tf"
2787 <*> o .: "fuzziness"
2788 <*> o .: "prefix_length"
2789 <*> o .: "boost"
2790 <*> o .:? "analyzer"
2792instance ToJSON FuzzyLikeThisQuery where
2793 toJSON (FuzzyLikeThisQuery fields text maxTerms
2794 ignoreFreq fuzziness prefixLength boost analyzer) =
2795 omitNulls base
2796 where base = [ "fields" .= fields
2797 , "like_text" .= text
2798 , "max_query_terms" .= maxTerms
2799 , "ignore_tf" .= ignoreFreq
2800 , "fuzziness" .= fuzziness
2801 , "prefix_length" .= prefixLength
2802 , "analyzer" .= analyzer
2803 , "boost" .= boost ]
2805instance FromJSON FuzzyLikeThisQuery where
2806 parseJSON = withObject "FuzzyLikeThisQuery" parse
2807 where parse o = FuzzyLikeThisQuery
2808 <$> o .:? "fields" .!= []
2809 <*> o .: "like_text"
2810 <*> o .: "max_query_terms"
2811 <*> o .: "ignore_tf"
2812 <*> o .: "fuzziness"
2813 <*> o .: "prefix_length"
2814 <*> o .: "boost"
2815 <*> o .:? "analyzer"
2817instance ToJSON FilteredQuery where
2818 toJSON (FilteredQuery query fFilter) =
2819 object [ "query" .= query
2820 , "filter" .= fFilter ]
2822instance FromJSON FilteredQuery where
2823 parseJSON = withObject "FilteredQuery" parse
2824 where parse o = FilteredQuery
2825 <$> o .: "query"
2826 <*> o .: "filter"
2828instance ToJSON DisMaxQuery where
2829 toJSON (DisMaxQuery queries tiebreaker boost) =
2830 omitNulls base
2831 where base = [ "queries" .= queries
2832 , "boost" .= boost
2833 , "tie_breaker" .= tiebreaker ]
2835instance FromJSON DisMaxQuery where
2836 parseJSON = withObject "DisMaxQuery" parse
2837 where parse o = DisMaxQuery
2838 <$> o .:? "queries" .!= []
2839 <*> o .: "tie_breaker"
2840 <*> o .:? "boost"
2842instance ToJSON CommonTermsQuery where
2843 toJSON (CommonTermsQuery (FieldName fieldName)
2844 (QueryString query) cf lfo hfo msm
2845 boost analyzer disableCoord) =
2846 object [fieldName .= omitNulls base ]
2847 where base = [ "query" .= query
2848 , "cutoff_frequency" .= cf
2849 , "low_freq_operator" .= lfo
2850 , "minimum_should_match" .= msm
2851 , "boost" .= boost
2852 , "analyzer" .= analyzer
2853 , "disable_coord" .= disableCoord
2854 , "high_freq_operator" .= hfo ]
2856instance FromJSON CommonTermsQuery where
2857 parseJSON = withObject "CommonTermsQuery" parse
2858 where parse = fieldTagged $ \fn o ->
2859 CommonTermsQuery fn
2860 <$> o .: "query"
2861 <*> o .: "cutoff_frequency"
2862 <*> o .: "low_freq_operator"
2863 <*> o .: "high_freq_operator"
2864 <*> o .:? "minimum_should_match"
2865 <*> o .:? "boost"
2866 <*> o .:? "analyzer"
2867 <*> o .:? "disable_coord"
2869instance ToJSON CommonMinimumMatch where
2870 toJSON (CommonMinimumMatch mm) = toJSON mm
2871 toJSON (CommonMinimumMatchHighLow (MinimumMatchHighLow lowF highF)) =
2872 object [ "low_freq" .= lowF
2873 , "high_freq" .= highF ]
2875instance FromJSON CommonMinimumMatch where
2876 parseJSON v = parseMinimum v
2877 <|> parseMinimumHighLow v
2878 where parseMinimum = fmap CommonMinimumMatch . parseJSON
2879 parseMinimumHighLow = fmap CommonMinimumMatchHighLow . withObject "CommonMinimumMatchHighLow" (\o ->
2880 MinimumMatchHighLow
2881 <$> o .: "low_freq"
2882 <*> o .: "high_freq")
2885instance ToJSON BoostingQuery where
2886 toJSON (BoostingQuery bqPositiveQuery bqNegativeQuery bqNegativeBoost) =
2887 object [ "positive" .= bqPositiveQuery
2888 , "negative" .= bqNegativeQuery
2889 , "negative_boost" .= bqNegativeBoost ]
2891instance FromJSON BoostingQuery where
2892 parseJSON = withObject "BoostingQuery" parse
2893 where parse o = BoostingQuery
2894 <$> o .: "positive"
2895 <*> o .: "negative"
2896 <*> o .: "negative_boost"
2898instance ToJSON BoolQuery where
2899 toJSON (BoolQuery mustM notM shouldM bqMin boost disableCoord) =
2900 omitNulls base
2901 where base = [ "must" .= mustM
2902 , "must_not" .= notM
2903 , "should" .= shouldM
2904 , "minimum_should_match" .= bqMin
2905 , "boost" .= boost
2906 , "disable_coord" .= disableCoord ]
2908instance FromJSON BoolQuery where
2909 parseJSON = withObject "BoolQuery" parse
2910 where parse o = BoolQuery
2911 <$> o .:? "must" .!= []
2912 <*> o .:? "must_not" .!= []
2913 <*> o .:? "should" .!= []
2914 <*> o .:? "minimum_should_match"
2915 <*> o .:? "boost"
2916 <*> o .:? "disable_coord"
2918instance ToJSON MatchQuery where
2919 toJSON (MatchQuery (FieldName fieldName)
2920 (QueryString mqQueryString) booleanOperator
2921 zeroTermsQuery cutoffFrequency matchQueryType
2922 analyzer maxExpansions lenient boost) =
2923 object [ fieldName .= omitNulls base ]
2924 where base = [ "query" .= mqQueryString
2925 , "operator" .= booleanOperator
2926 , "zero_terms_query" .= zeroTermsQuery
2927 , "cutoff_frequency" .= cutoffFrequency
2928 , "type" .= matchQueryType
2929 , "analyzer" .= analyzer
2930 , "max_expansions" .= maxExpansions
2931 , "lenient" .= lenient
2932 , "boost" .= boost ]
2934instance FromJSON MatchQuery where
2935 parseJSON = withObject "MatchQuery" parse
2936 where parse = fieldTagged $ \fn o ->
2937 MatchQuery fn
2938 <$> o .: "query"
2939 <*> o .: "operator"
2940 <*> o .: "zero_terms_query"
2941 <*> o .:? "cutoff_frequency"
2942 <*> o .:? "type"
2943 <*> o .:? "analyzer"
2944 <*> o .:? "max_expansions"
2945 <*> o .:? "lenient"
2946 <*> o .:? "boost"
2948instance ToJSON MultiMatchQuery where
2949 toJSON (MultiMatchQuery fields (QueryString query) boolOp
2950 ztQ tb mmqt cf analyzer maxEx lenient) =
2951 object ["multi_match" .= omitNulls base]
2952 where base = [ "fields" .= fmap toJSON fields
2953 , "query" .= query
2954 , "operator" .= boolOp
2955 , "zero_terms_query" .= ztQ
2956 , "tiebreaker" .= tb
2957 , "type" .= mmqt
2958 , "cutoff_frequency" .= cf
2959 , "analyzer" .= analyzer
2960 , "max_expansions" .= maxEx
2961 , "lenient" .= lenient ]
2963instance FromJSON MultiMatchQuery where
2964 parseJSON = withObject "MultiMatchQuery" parse
2965 where parse raw = do o <- raw .: "multi_match"
2966 MultiMatchQuery
2967 <$> o .:? "fields" .!= []
2968 <*> o .: "query"
2969 <*> o .: "operator"
2970 <*> o .: "zero_terms_query"
2971 <*> o .:? "tiebreaker"
2972 <*> o .:? "type"
2973 <*> o .:? "cutoff_frequency"
2974 <*> o .:? "analyzer"
2975 <*> o .:? "max_expansions"
2976 <*> o .:? "lenient"
2978instance ToJSON MultiMatchQueryType where
2979 toJSON MultiMatchBestFields = "best_fields"
2980 toJSON MultiMatchMostFields = "most_fields"
2981 toJSON MultiMatchCrossFields = "cross_fields"
2982 toJSON MultiMatchPhrase = "phrase"
2983 toJSON MultiMatchPhrasePrefix = "phrase_prefix"
2985instance FromJSON MultiMatchQueryType where
2986 parseJSON = withText "MultiMatchPhrasePrefix" parse
2987 where parse "best_fields" = pure MultiMatchBestFields
2988 parse "most_fields" = pure MultiMatchMostFields
2989 parse "cross_fields" = pure MultiMatchCrossFields
2990 parse "phrase" = pure MultiMatchPhrase
2991 parse "phrase_prefix" = pure MultiMatchPhrasePrefix
2992 parse t = fail ("Unexpected MultiMatchPhrasePrefix: " <> show t)
2994instance ToJSON BooleanOperator where
2995 toJSON And = String "and"
2996 toJSON Or = String "or"
2998instance FromJSON BooleanOperator where
2999 parseJSON = withText "BooleanOperator" parse
3000 where parse "and" = pure And
3001 parse "or" = pure Or
3002 parse o = fail ("Unexpected BooleanOperator: " <> show o)
3004instance ToJSON ZeroTermsQuery where
3005 toJSON ZeroTermsNone = String "none"
3006 toJSON ZeroTermsAll = String "all"
3008instance FromJSON ZeroTermsQuery where
3009 parseJSON = withText "ZeroTermsQuery" parse
3010 where parse "none" = pure ZeroTermsNone
3011 parse "all" = pure ZeroTermsAll
3012 parse q = fail ("Unexpected ZeroTermsQuery: " <> show q)
3014instance ToJSON MatchQueryType where
3015 toJSON MatchPhrase = "phrase"
3016 toJSON MatchPhrasePrefix = "phrase_prefix"
3018instance FromJSON MatchQueryType where
3019 parseJSON = withText "MatchQueryType" parse
3020 where parse "phrase" = pure MatchPhrase
3021 parse "phrase_prefix" = pure MatchPhrasePrefix
3022 parse t = fail ("Unexpected MatchQueryType: " <> show t)
3024instance FromJSON Status where
3025 parseJSON (Object v) = Status <$>
3026 v .:? "ok" <*>
3027 (v .:? "status" .!= 200) <*>
3028 v .: "name" <*>
3029 v .: "version" <*>
3030 v .: "tagline"
3031 parseJSON _ = empty
3034instance ToJSON IndexSettings where
3035 toJSON (IndexSettings s r) = object ["settings" .=
3036 object ["index" .=
3037 object ["number_of_shards" .= s, "number_of_replicas" .= r]
3041instance FromJSON IndexSettings where
3042 parseJSON = withObject "IndexSettings" parse
3043 where parse o = do s <- o .: "settings"
3044 i <- s .: "index"
3045 IndexSettings <$> i .: "number_of_shards"
3046 <*> i .: "number_of_replicas"
3048instance ToJSON UpdatableIndexSetting where
3049 toJSON (NumberOfReplicas x) = oPath ("index" :| ["number_of_replicas"]) x
3050 toJSON (AutoExpandReplicas x) = oPath ("index" :| ["auto_expand_replicas"]) x
3051 toJSON (RefreshInterval x) = oPath ("index" :| ["refresh_interval"]) (NominalDiffTimeJSON x)
3052 toJSON (IndexConcurrency x) = oPath ("index" :| ["concurrency"]) x
3053 toJSON (FailOnMergeFailure x) = oPath ("index" :| ["fail_on_merge_failure"]) x
3054 toJSON (TranslogFlushThresholdOps x) = oPath ("index" :| ["translog", "flush_threshold_ops"]) x
3055 toJSON (TranslogFlushThresholdSize x) = oPath ("index" :| ["translog", "flush_threshold_size"]) x
3056 toJSON (TranslogFlushThresholdPeriod x) = oPath ("index" :| ["translog", "flush_threshold_period"]) (NominalDiffTimeJSON x)
3057 toJSON (TranslogDisableFlush x) = oPath ("index" :| ["translog", "disable_flush"]) x
3058 toJSON (CacheFilterMaxSize x) = oPath ("index" :| ["cache", "filter", "max_size"]) x
3059 toJSON (CacheFilterExpire x) = oPath ("index" :| ["cache", "filter", "expire"]) (NominalDiffTimeJSON <$> x)
3060 toJSON (GatewaySnapshotInterval x) = oPath ("index" :| ["gateway", "snapshot_interval"]) (NominalDiffTimeJSON x)
3061 toJSON (RoutingAllocationInclude fs) = oPath ("index" :| ["routing", "allocation", "include"]) (attrFilterJSON fs)
3062 toJSON (RoutingAllocationExclude fs) = oPath ("index" :| ["routing", "allocation", "exclude"]) (attrFilterJSON fs)
3063 toJSON (RoutingAllocationRequire fs) = oPath ("index" :| ["routing", "allocation", "require"]) (attrFilterJSON fs)
3064 toJSON (RoutingAllocationEnable x) = oPath ("index" :| ["routing", "allocation", "enable"]) x
3065 toJSON (RoutingAllocationShardsPerNode x) = oPath ("index" :| ["routing", "allocation", "total_shards_per_node"]) x
3066 toJSON (RecoveryInitialShards x) = oPath ("index" :| ["recovery", "initial_shards"]) x
3067 toJSON (GCDeletes x) = oPath ("index" :| ["gc_deletes"]) (NominalDiffTimeJSON x)
3068 toJSON (TTLDisablePurge x) = oPath ("index" :| ["ttl", "disable_purge"]) x
3069 toJSON (TranslogFSType x) = oPath ("index" :| ["translog", "fs", "type"]) x
3070 toJSON (IndexCompoundFormat x) = oPath ("index" :| ["compound_format"]) x
3071 toJSON (IndexCompoundOnFlush x) = oPath ("index" :| ["compound_on_flush"]) x
3072 toJSON (WarmerEnabled x) = oPath ("index" :| ["warmer", "enabled"]) x
3073 toJSON (BlocksReadOnly x) = oPath ("blocks" :| ["read_only"]) x
3074 toJSON (BlocksRead x) = oPath ("blocks" :| ["read"]) x
3075 toJSON (BlocksWrite x) = oPath ("blocks" :| ["write"]) x
3076 toJSON (BlocksMetaData x) = oPath ("blocks" :| ["metadata"]) x
3078instance FromJSON UpdatableIndexSetting where
3079 parseJSON = withObject "UpdatableIndexSetting" parse
3080 where parse o = numberOfReplicas `taggedAt` ["index", "number_of_replicas"]
3081 <|> autoExpandReplicas `taggedAt` ["index", "auto_expand_replicas"]
3082 <|> refreshInterval `taggedAt` ["index", "refresh_interval"]
3083 <|> indexConcurrency `taggedAt` ["index", "concurrency"]
3084 <|> failOnMergeFailure `taggedAt` ["index", "fail_on_merge_failure"]
3085 <|> translogFlushThresholdOps `taggedAt` ["index", "translog", "flush_threshold_ops"]
3086 <|> translogFlushThresholdSize `taggedAt` ["index", "translog", "flush_threshold_size"]
3087 <|> translogFlushThresholdPeriod `taggedAt` ["index", "translog", "flush_threshold_period"]
3088 <|> translogDisableFlush `taggedAt` ["index", "translog", "disable_flush"]
3089 <|> cacheFilterMaxSize `taggedAt` ["index", "cache", "filter", "max_size"]
3090 <|> cacheFilterExpire `taggedAt` ["index", "cache", "filter", "expire"]
3091 <|> gatewaySnapshotInterval `taggedAt` ["index", "gateway", "snapshot_interval"]
3092 <|> routingAllocationInclude `taggedAt` ["index", "routing", "allocation", "include"]
3093 <|> routingAllocationExclude `taggedAt` ["index", "routing", "allocation", "exclude"]
3094 <|> routingAllocationRequire `taggedAt` ["index", "routing", "allocation", "require"]
3095 <|> routingAllocationEnable `taggedAt` ["index", "routing", "allocation", "enable"]
3096 <|> routingAllocationShardsPerNode `taggedAt` ["index", "routing", "allocation", "total_shards_per_node"]
3097 <|> recoveryInitialShards `taggedAt` ["index", "recovery", "initial_shards"]
3098 <|> gcDeletes `taggedAt` ["index", "gc_deletes"]
3099 <|> ttlDisablePurge `taggedAt` ["index", "ttl", "disable_purge"]
3100 <|> translogFSType `taggedAt` ["index", "translog", "fs", "type"]
3101 <|> compoundFormat `taggedAt` ["index", "compound_format"]
3102 <|> compoundOnFlush `taggedAt` ["index", "compound_on_flush"]
3103 <|> warmerEnabled `taggedAt` ["index", "warmer", "enabled"]
3104 <|> blocksReadOnly `taggedAt` ["blocks", "read_only"]
3105 <|> blocksRead `taggedAt` ["blocks", "read"]
3106 <|> blocksWrite `taggedAt` ["blocks", "write"]
3107 <|> blocksMetaData `taggedAt` ["blocks", "metadata"]
3108 where taggedAt f ks = taggedAt' f (Object o) ks
3109 taggedAt' f v [] = f =<< (parseJSON v <|> (parseJSON (unStringlyTypeJSON v)))
3110 taggedAt' f v (k:ks) = withObject "Object" (\o -> do v' <- o .: k
3111 taggedAt' f v' ks) v
3112 numberOfReplicas = pure . NumberOfReplicas
3113 autoExpandReplicas = pure . AutoExpandReplicas
3114 refreshInterval = pure . RefreshInterval . ndtJSON
3115 indexConcurrency = pure . IndexConcurrency
3116 failOnMergeFailure = pure . FailOnMergeFailure
3117 translogFlushThresholdOps = pure . TranslogFlushThresholdOps
3118 translogFlushThresholdSize = pure . TranslogFlushThresholdSize
3119 translogFlushThresholdPeriod = pure . TranslogFlushThresholdPeriod . ndtJSON
3120 translogDisableFlush = pure . TranslogDisableFlush
3121 cacheFilterMaxSize = pure . CacheFilterMaxSize
3122 cacheFilterExpire = pure . CacheFilterExpire . fmap ndtJSON
3123 gatewaySnapshotInterval = pure . GatewaySnapshotInterval . ndtJSON
3124 routingAllocationInclude = fmap RoutingAllocationInclude . parseAttrFilter
3125 routingAllocationExclude = fmap RoutingAllocationExclude . parseAttrFilter
3126 routingAllocationRequire = fmap RoutingAllocationRequire . parseAttrFilter
3127 routingAllocationEnable = pure . RoutingAllocationEnable
3128 routingAllocationShardsPerNode = pure . RoutingAllocationShardsPerNode
3129 recoveryInitialShards = pure . RecoveryInitialShards
3130 gcDeletes = pure . GCDeletes . ndtJSON
3131 ttlDisablePurge = pure . TTLDisablePurge
3132 translogFSType = pure . TranslogFSType
3133 compoundFormat = pure . IndexCompoundFormat
3134 compoundOnFlush = pure . IndexCompoundOnFlush
3135 warmerEnabled = pure . WarmerEnabled
3136 blocksReadOnly = pure . BlocksReadOnly
3137 blocksRead = pure . BlocksRead
3138 blocksWrite = pure . BlocksWrite
3139 blocksMetaData = pure . BlocksMetaData
3141instance FromJSON IndexSettingsSummary where
3142 parseJSON = withObject "IndexSettingsSummary" parse
3143 where parse o = case HM.toList o of
3144 [(ixn, v@(Object o'))] -> IndexSettingsSummary (IndexName ixn)
3145 <$> parseJSON v
3146 <*> (fmap (filter (not . redundant)) . parseSettings =<< o' .: "settings")
3147 _ -> fail "Expected single-key object with index name"
3148 redundant (NumberOfReplicas _) = True
3149 redundant _ = False
3151-- | For some reason in several settings APIs, all leaf values get returned
3152-- as strings. This function attepmts to recover from this for all
3153-- non-recursive JSON types. If nothing can be done, the value is left alone.
3154unStringlyTypeJSON :: Value -> Value
3155unStringlyTypeJSON (String "true") = Bool True
3156unStringlyTypeJSON (String "false") = Bool False
3157unStringlyTypeJSON (String "null") = Null
3158unStringlyTypeJSON v@(String t) = case readMay (T.unpack t) of
3159 Just n -> Number n
3160 Nothing -> v
3161unStringlyTypeJSON v = v
3164parseSettings :: Object -> Parser [UpdatableIndexSetting]
3165parseSettings o = do
3166 o' <- o .: "index"
3167 -- slice the index object into singleton hashmaps and try to parse each
3168 parses <- forM (HM.toList o') $ \(k, v) -> do
3169 -- blocks are now nested into the "index" key, which is not how they're serialized
3170 let atRoot = Object (HM.singleton k v)
3171 let atIndex = Object (HM.singleton "index" atRoot)
3172 optional (parseJSON atRoot <|> parseJSON atIndex)
3173 return (catMaybes parses)
3175oPath :: ToJSON a => NonEmpty Text -> a -> Value
3176oPath (k :| []) v = object [k .= v]
3177oPath (k:| (h:t)) v = object [k .= oPath (h :| t) v]
3179attrFilterJSON :: NonEmpty NodeAttrFilter -> Value
3180attrFilterJSON fs = object [ n .= T.intercalate "," (toList vs)
3181 | NodeAttrFilter (NodeAttrName n) vs <- toList fs]
3183parseAttrFilter :: Value -> Parser (NonEmpty NodeAttrFilter)
3184parseAttrFilter = withObject "NonEmpty NodeAttrFilter" parse
3185 where parse o = case HM.toList o of
3186 [] -> fail "Expected non-empty list of NodeAttrFilters"
3187 x:xs -> DT.mapM (uncurry parse') (x :| xs)
3188 parse' n = withText "Text" $ \t ->
3189 case T.splitOn "," t of
3190 fv:fvs -> return (NodeAttrFilter (NodeAttrName n) (fv :| fvs))
3191 [] -> fail "Expected non-empty list of filter values"
3193instance ToJSON ReplicaBounds where
3194 toJSON (ReplicasBounded a b) = String (showText a <> "-" <> showText b)
3195 toJSON (ReplicasLowerBounded a) = String (showText a <> "-all")
3196 toJSON ReplicasUnbounded = Bool False
3198instance FromJSON ReplicaBounds where
3199 parseJSON v = withText "ReplicaBounds" parseText v
3200 <|> withBool "ReplicaBounds" parseBool v
3201 where parseText t = case T.splitOn "-" t of
3202 [a, "all"] -> ReplicasLowerBounded <$> parseReadText a
3203 [a, b] -> ReplicasBounded <$> parseReadText a
3204 <*> parseReadText b
3205 _ -> fail ("Could not parse ReplicaBounds: " <> show t)
3206 parseBool False = pure ReplicasUnbounded
3207 parseBool _ = fail "ReplicasUnbounded cannot be represented with True"
3209instance ToJSON AllocationPolicy where
3210 toJSON AllocAll = String "all"
3211 toJSON AllocPrimaries = String "primaries"
3212 toJSON AllocNewPrimaries = String "new_primaries"
3213 toJSON AllocNone = String "none"
3215instance FromJSON AllocationPolicy where
3216 parseJSON = withText "AllocationPolicy" parse
3217 where parse "all" = pure AllocAll
3218 parse "primaries" = pure AllocPrimaries
3219 parse "new_primaries" = pure AllocNewPrimaries
3220 parse "none" = pure AllocNone
3221 parse t = fail ("Invlaid AllocationPolicy: " <> show t)
3223instance ToJSON InitialShardCount where
3224 toJSON QuorumShards = String "quorum"
3225 toJSON QuorumMinus1Shards = String "quorum-1"
3226 toJSON FullShards = String "full"
3227 toJSON FullMinus1Shards = String "full-1"
3228 toJSON (ExplicitShards x) = toJSON x
3230instance FromJSON InitialShardCount where
3231 parseJSON v = withText "InitialShardCount" parseText v
3232 <|> ExplicitShards <$> parseJSON v
3233 where parseText "quorum" = pure QuorumShards
3234 parseText "quorum-1" = pure QuorumMinus1Shards
3235 parseText "full" = pure FullShards
3236 parseText "full-1" = pure FullMinus1Shards
3237 parseText _ = mzero
3239instance ToJSON FSType where
3240 toJSON FSSimple = "simple"
3241 toJSON FSBuffered = "buffered"
3243instance FromJSON FSType where
3244 parseJSON = withText "FSType" parse
3245 where parse "simple" = pure FSSimple
3246 parse "buffered" = pure FSBuffered
3247 parse t = fail ("Invalid FSType: " <> show t)
3249instance ToJSON CompoundFormat where
3250 toJSON (CompoundFileFormat x) = Bool x
3251 toJSON (MergeSegmentVsTotalIndex x) = toJSON x
3253instance FromJSON CompoundFormat where
3254 parseJSON v = CompoundFileFormat <$> parseJSON v
3255 <|> MergeSegmentVsTotalIndex <$> parseJSON v
3257instance ToJSON NominalDiffTimeJSON where
3258 toJSON (NominalDiffTimeJSON t) = String (showText (round t :: Integer) <> "s")
3260instance FromJSON NominalDiffTimeJSON where
3261 parseJSON = withText "NominalDiffTime" parse
3262 where parse t = case T.takeEnd 1 t of
3263 "s" -> NominalDiffTimeJSON . fromInteger <$> parseReadText (T.dropEnd 1 t)
3264 _ -> fail "Invalid or missing NominalDiffTime unit (expected s)"
3266instance ToJSON IndexTemplate where
3267 toJSON (IndexTemplate p s m) = merge
3268 (object [ "template" .= p
3269 , "mappings" .= foldl' merge (object []) m
3270 ])
3271 (toJSON s)
3272 where
3273 merge (Object o1) (Object o2) = toJSON $ HM.union o1 o2
3274 merge o Null = o
3275 merge _ _ = undefined
3277instance (FromJSON a) => FromJSON (EsResult a) where
3278 parseJSON jsonVal@(Object v) = do
3279 found <- v .:? "found" .!= False
3280 fr <- if found
3281 then parseJSON jsonVal
3282 else return Nothing
3283 EsResult <$> v .: "_index" <*>
3284 v .: "_type" <*>
3285 v .: "_id" <*>
3286 pure fr
3287 parseJSON _ = empty
3289instance (FromJSON a) => FromJSON (EsResultFound a) where
3290 parseJSON (Object v) = EsResultFound <$>
3291 v .: "_version" <*>
3292 v .: "_source"
3293 parseJSON _ = empty
3295instance FromJSON EsError where
3296 parseJSON (Object v) = EsError <$>
3297 v .: "status" <*>
3298 (v .: "error" <|> (v .: "error" >>= (.: "reason")))
3299 parseJSON _ = empty
3301instance FromJSON IndexAliasesSummary where
3302 parseJSON = withObject "IndexAliasesSummary" parse
3303 where parse o = IndexAliasesSummary . mconcat <$> mapM (uncurry go) (HM.toList o)
3304 go ixn = withObject "index aliases" $ \ia -> do
3305 aliases <- ia .:? "aliases" .!= mempty
3306 forM (HM.toList aliases) $ \(aName, v) -> do
3307 let indexAlias = IndexAlias (IndexName ixn) (IndexAliasName (IndexName aName))
3308 IndexAliasSummary indexAlias <$> parseJSON v
3311instance ToJSON IndexAliasAction where
3312 toJSON (AddAlias ia opts) = object ["add" .= (iaObj <> optsObj)]
3313 where Object iaObj = toJSON ia
3314 Object optsObj = toJSON opts
3315 toJSON (RemoveAlias ia) = object ["remove" .= iaObj]
3316 where Object iaObj = toJSON ia
3318instance ToJSON IndexAlias where
3319 toJSON IndexAlias {..} = object ["index" .= srcIndex
3320 , "alias" .= indexAlias
3323instance ToJSON IndexAliasCreate where
3324 toJSON IndexAliasCreate {..} = Object (filterObj <> routingObj)
3325 where filterObj = maybe mempty (HM.singleton "filter" . toJSON) aliasCreateFilter
3326 Object routingObj = maybe (Object mempty) toJSON aliasCreateRouting
3328instance ToJSON AliasRouting where
3329 toJSON (AllAliasRouting v) = object ["routing" .= v]
3330 toJSON (GranularAliasRouting srch idx) = object (catMaybes prs)
3331 where prs = [("search_routing" .=) <$> srch
3332 ,("index_routing" .=) <$> idx]
3334instance FromJSON AliasRouting where
3335 parseJSON = withObject "AliasRouting" parse
3336 where parse o = parseAll o <|> parseGranular o
3337 parseAll o = AllAliasRouting <$> o .: "routing"
3338 parseGranular o = do
3339 sr <- o .:? "search_routing"
3340 ir <- o .:? "index_routing"
3341 if isNothing sr && isNothing ir
3342 then fail "Both search_routing and index_routing can't be blank"
3343 else return (GranularAliasRouting sr ir)
3345instance FromJSON IndexAliasCreate where
3346 parseJSON v = withObject "IndexAliasCreate" parse v
3347 where parse o = IndexAliasCreate <$> optional (parseJSON v)
3348 <*> o .:? "filter"
3350instance ToJSON SearchAliasRouting where
3351 toJSON (SearchAliasRouting rvs) = toJSON (T.intercalate "," (routingValue <$> toList rvs))
3353instance FromJSON SearchAliasRouting where
3354 parseJSON = withText "SearchAliasRouting" parse
3355 where parse t = SearchAliasRouting <$> parseNEJSON (String <$> T.splitOn "," t)
3357instance ToJSON Search where
3358 toJSON (Search query sFilter sort searchAggs highlight sTrackSortScores sFrom sSize _ sFields sSource) =
3359 omitNulls [ "query" .= query
3360 , "filter" .= sFilter
3361 , "sort" .= sort
3362 , "aggregations" .= searchAggs
3363 , "highlight" .= highlight
3364 , "from" .= sFrom
3365 , "size" .= sSize
3366 , "track_scores" .= sTrackSortScores
3367 , "fields" .= sFields
3368 , "_source" .= sSource]
3371instance ToJSON Source where
3372 toJSON NoSource = toJSON False
3373 toJSON (SourcePatterns patterns) = toJSON patterns
3374 toJSON (SourceIncludeExclude incl excl) = object [ "include" .= incl, "exclude" .= excl ]
3376instance ToJSON PatternOrPatterns where
3377 toJSON (PopPattern pattern) = toJSON pattern
3378 toJSON (PopPatterns patterns) = toJSON patterns
3380instance ToJSON Include where
3381 toJSON (Include patterns) = toJSON patterns
3383instance ToJSON Exclude where
3384 toJSON (Exclude patterns) = toJSON patterns
3386instance ToJSON Pattern where
3387 toJSON (Pattern pattern) = toJSON pattern
3390instance ToJSON FieldHighlight where
3391 toJSON (FieldHighlight (FieldName fName) (Just fSettings)) =
3392 object [ fName .= fSettings ]
3393 toJSON (FieldHighlight (FieldName fName) Nothing) =
3394 object [ fName .= emptyObject ]
3396instance ToJSON Highlights where
3397 toJSON (Highlights global fields) =
3398 omitNulls (("fields" .= fields)
3399 : highlightSettingsPairs global)
3401instance ToJSON HighlightSettings where
3402 toJSON hs = omitNulls (highlightSettingsPairs (Just hs))
3404highlightSettingsPairs :: Maybe HighlightSettings -> [Pair]
3405highlightSettingsPairs Nothing = []
3406highlightSettingsPairs (Just (Plain plh)) = plainHighPairs (Just plh)
3407highlightSettingsPairs (Just (Postings ph)) = postHighPairs (Just ph)
3408highlightSettingsPairs (Just (FastVector fvh)) = fastVectorHighPairs (Just fvh)
3411plainHighPairs :: Maybe PlainHighlight -> [Pair]
3412plainHighPairs Nothing = []
3413plainHighPairs (Just (PlainHighlight plCom plNonPost)) =
3414 [ "type" .= String "plain"]
3415 ++ commonHighlightPairs plCom
3416 ++ nonPostingsToPairs plNonPost
3418postHighPairs :: Maybe PostingsHighlight -> [Pair]
3419postHighPairs Nothing = []
3420postHighPairs (Just (PostingsHighlight pCom)) =
3421 ("type" .= String "postings")
3422 : commonHighlightPairs pCom
3424fastVectorHighPairs :: Maybe FastVectorHighlight -> [Pair]
3425fastVectorHighPairs Nothing = []
3426fastVectorHighPairs (Just
3427 (FastVectorHighlight fvCom fvNonPostSettings fvBoundChars
3428 fvBoundMaxScan fvFragOff fvMatchedFields
3429 fvPhraseLim)) =
3430 [ "type" .= String "fvh"
3431 , "boundary_chars" .= fvBoundChars
3432 , "boundary_max_scan" .= fvBoundMaxScan
3433 , "fragment_offset" .= fvFragOff
3434 , "matched_fields" .= fvMatchedFields
3435 , "phraseLimit" .= fvPhraseLim]
3436 ++ commonHighlightPairs fvCom
3437 ++ nonPostingsToPairs fvNonPostSettings
3439deleteSeveral :: (Eq k, Hashable k) => [k] -> HM.HashMap k v -> HM.HashMap k v
3440deleteSeveral ks hm = foldr HM.delete hm ks
3442commonHighlightPairs :: Maybe CommonHighlight -> [Pair]
3443commonHighlightPairs Nothing = []
3444commonHighlightPairs (Just (CommonHighlight chScore chForceSource chTag chEncoder
3445 chNoMatchSize chHighlightQuery
3446 chRequireFieldMatch)) =
3447 [ "order" .= chScore
3448 , "force_source" .= chForceSource
3449 , "encoder" .= chEncoder
3450 , "no_match_size" .= chNoMatchSize
3451 , "highlight_query" .= chHighlightQuery
3452 , "require_fieldMatch" .= chRequireFieldMatch]
3453 ++ highlightTagToPairs chTag
3456nonPostingsToPairs :: Maybe NonPostings -> [Pair]
3457nonPostingsToPairs Nothing = []
3458nonPostingsToPairs (Just (NonPostings npFragSize npNumOfFrags)) =
3459 [ "fragment_size" .= npFragSize
3460 , "number_of_fragments" .= npNumOfFrags]
3462parseNEJSON :: (FromJSON a) => [Value] -> Parser (NonEmpty a)
3463parseNEJSON [] = fail "Expected non-empty list"
3464parseNEJSON (x:xs) = DT.mapM parseJSON (x :| xs)
3467instance ToJSON HighlightEncoder where
3468 toJSON DefaultEncoder = String "default"
3469 toJSON HTMLEncoder = String "html"
3471highlightTagToPairs :: Maybe HighlightTag -> [Pair]
3472highlightTagToPairs (Just (TagSchema _)) = [ "scheme" .= String "default"]
3473highlightTagToPairs (Just (CustomTags (pre, post))) = [ "pre_tags" .= pre
3474 , "post_tags" .= post]
3475highlightTagToPairs Nothing = []
3477instance ToJSON SortSpec where
3478 toJSON (DefaultSortSpec
3479 (DefaultSort (FieldName dsSortFieldName) dsSortOrder dsIgnoreUnmapped
3480 dsSortMode dsMissingSort dsNestedFilter)) =
3481 object [dsSortFieldName .= omitNulls base] where
3482 base = [ "order" .= dsSortOrder
3483 , "ignore_unmapped" .= dsIgnoreUnmapped
3484 , "mode" .= dsSortMode
3485 , "missing" .= dsMissingSort
3486 , "nested_filter" .= dsNestedFilter ]
3488 toJSON (GeoDistanceSortSpec gdsSortOrder (GeoPoint (FieldName field) gdsLatLon) units) =
3489 object [ "unit" .= units
3490 , field .= gdsLatLon
3491 , "order" .= gdsSortOrder ]
3494instance ToJSON SortOrder where
3495 toJSON Ascending = String "asc"
3496 toJSON Descending = String "desc"
3499instance ToJSON SortMode where
3500 toJSON SortMin = String "min"
3501 toJSON SortMax = String "max"
3502 toJSON SortSum = String "sum"
3503 toJSON SortAvg = String "avg"
3506instance ToJSON Missing where
3507 toJSON LastMissing = String "_last"
3508 toJSON FirstMissing = String "_first"
3509 toJSON (CustomMissing txt) = String txt
3512instance ToJSON ScoreType where
3513 toJSON ScoreTypeMax = "max"
3514 toJSON ScoreTypeAvg = "avg"
3515 toJSON ScoreTypeSum = "sum"
3516 toJSON ScoreTypeNone = "none"
3518instance FromJSON ScoreType where
3519 parseJSON = withText "ScoreType" parse
3520 where parse "max" = pure ScoreTypeMax
3521 parse "avg" = pure ScoreTypeAvg
3522 parse "sum" = pure ScoreTypeSum
3523 parse "none" = pure ScoreTypeNone
3524 parse t = fail ("Unexpected ScoreType: " <> show t)
3526instance ToJSON Distance where
3527 toJSON (Distance dCoefficient dUnit) =
3528 String boltedTogether where
3529 coefText = showText dCoefficient
3530 (String unitText) = toJSON dUnit
3531 boltedTogether = mappend coefText unitText
3533instance FromJSON Distance where
3534 parseJSON = withText "Distance" parse
3535 where parse t = Distance <$> parseCoeff nT
3536 <*> parseJSON (String unitT)
3537 where (nT, unitT) = T.span validForNumber t
3538 -- may be a better way to do this
3539 validForNumber '-' = True
3540 validForNumber '.' = True
3541 validForNumber 'e' = True
3542 validForNumber c = isNumber c
3543 parseCoeff "" = fail "Empty string cannot be parsed as number"
3544 parseCoeff s = return (read (T.unpack s))
3546instance ToJSON DistanceUnit where
3547 toJSON Miles = String "mi"
3548 toJSON Yards = String "yd"
3549 toJSON Feet = String "ft"
3550 toJSON Inches = String "in"
3551 toJSON Kilometers = String "km"
3552 toJSON Meters = String "m"
3553 toJSON Centimeters = String "cm"
3554 toJSON Millimeters = String "mm"
3555 toJSON NauticalMiles = String "nmi"
3558instance FromJSON DistanceUnit where
3559 parseJSON = withText "DistanceUnit" parse
3560 where parse "mi" = pure Miles
3561 parse "yd" = pure Yards
3562 parse "ft" = pure Feet
3563 parse "in" = pure Inches
3564 parse "km" = pure Kilometers
3565 parse "m" = pure Meters
3566 parse "cm" = pure Centimeters
3567 parse "mm" = pure Millimeters
3568 parse "nmi" = pure NauticalMiles
3569 parse u = fail ("Unrecognized DistanceUnit: " <> show u)
3571instance ToJSON DistanceType where
3572 toJSON Arc = String "arc"
3573 toJSON SloppyArc = String "sloppy_arc"
3574 toJSON Plane = String "plane"
3576instance FromJSON DistanceType where
3577 parseJSON = withText "DistanceType" parse
3578 where parse "arc" = pure Arc
3579 parse "sloppy_arc" = pure SloppyArc
3580 parse "plane" = pure Plane
3581 parse t = fail ("Unrecognized DistanceType: " <> show t)
3584instance ToJSON OptimizeBbox where
3585 toJSON NoOptimizeBbox = String "none"
3586 toJSON (OptimizeGeoFilterType gft) = toJSON gft
3588instance FromJSON OptimizeBbox where
3589 parseJSON v = withText "NoOptimizeBbox" parseNoOptimize v
3590 <|> parseOptimize v
3591 where parseNoOptimize "none" = pure NoOptimizeBbox
3592 parseNoOptimize _ = mzero
3593 parseOptimize = fmap OptimizeGeoFilterType . parseJSON
3595instance ToJSON GeoBoundingBoxConstraint where
3596 toJSON (GeoBoundingBoxConstraint
3597 (FieldName gbbcGeoBBField) gbbcConstraintBox cache type') =
3598 object [gbbcGeoBBField .= gbbcConstraintBox
3599 , "_cache" .= cache
3600 , "type" .= type']
3602instance FromJSON GeoBoundingBoxConstraint where
3603 parseJSON = withObject "GeoBoundingBoxConstraint" parse
3604 where parse o = case HM.toList (deleteSeveral ["type", "_cache"] o) of
3605 [(fn, v)] -> GeoBoundingBoxConstraint (FieldName fn)
3606 <$> parseJSON v
3607 <*> o .:? "_cache" .!= defaultCache
3608 <*> o .: "type"
3609 _ -> fail "Could not find field name for GeoBoundingBoxConstraint"
3611instance ToJSON GeoFilterType where
3612 toJSON GeoFilterMemory = String "memory"
3613 toJSON GeoFilterIndexed = String "indexed"
3615instance FromJSON GeoFilterType where
3616 parseJSON = withText "GeoFilterType" parse
3617 where parse "memory" = pure GeoFilterMemory
3618 parse "indexed" = pure GeoFilterIndexed
3619 parse t = fail ("Unrecognized GeoFilterType: " <> show t)
3621instance ToJSON GeoBoundingBox where
3622 toJSON (GeoBoundingBox gbbTopLeft gbbBottomRight) =
3623 object ["top_left" .= gbbTopLeft
3624 , "bottom_right" .= gbbBottomRight]
3626instance FromJSON GeoBoundingBox where
3627 parseJSON = withObject "GeoBoundingBox" parse
3628 where parse o = GeoBoundingBox
3629 <$> o .: "top_left"
3630 <*> o .: "bottom_right"
3632instance ToJSON LatLon where
3633 toJSON (LatLon lLat lLon) =
3634 object ["lat" .= lLat
3635 , "lon" .= lLon]
3637instance FromJSON LatLon where
3638 parseJSON = withObject "LatLon" parse
3639 where parse o = LatLon <$> o .: "lat"
3640 <*> o .: "lon"
3642-- index for smaller ranges, fielddata for longer ranges
3643instance ToJSON RangeExecution where
3644 toJSON RangeExecutionIndex = "index"
3645 toJSON RangeExecutionFielddata = "fielddata"
3648instance FromJSON RangeExecution where
3649 parseJSON = withText "RangeExecution" parse
3650 where parse "index" = pure RangeExecutionIndex
3651 parse "fielddata" = pure RangeExecutionFielddata
3652 parse t = error ("Unrecognized RangeExecution " <> show t)
3654instance ToJSON RegexpFlags where
3655 toJSON AllRegexpFlags = String "ALL"
3656 toJSON NoRegexpFlags = String "NONE"
3657 toJSON (SomeRegexpFlags (h :| fs)) = String $ T.intercalate "|" flagStrs
3658 where flagStrs = map flagStr . nub $ h:fs
3659 flagStr AnyString = "ANYSTRING"
3660 flagStr Automaton = "AUTOMATON"
3661 flagStr Complement = "COMPLEMENT"
3662 flagStr Empty = "EMPTY"
3663 flagStr Intersection = "INTERSECTION"
3664 flagStr Interval = "INTERVAL"
3666instance FromJSON RegexpFlags where
3667 parseJSON = withText "RegexpFlags" parse
3668 where parse "ALL" = pure AllRegexpFlags
3669 parse "NONE" = pure NoRegexpFlags
3670 parse t = SomeRegexpFlags <$> parseNEJSON (String <$> T.splitOn "|" t)
3672instance FromJSON RegexpFlag where
3673 parseJSON = withText "RegexpFlag" parse
3674 where parse "ANYSTRING" = pure AnyString
3675 parse "AUTOMATON" = pure Automaton
3676 parse "COMPLEMENT" = pure Complement
3677 parse "EMPTY" = pure Empty
3678 parse "INTERSECTION" = pure Intersection
3679 parse "INTERVAL" = pure Interval
3680 parse f = fail ("Unknown RegexpFlag: " <> show f)
3682instance ToJSON Term where
3683 toJSON (Term field value) = object ["term" .= object
3684 [field .= value]]
3686instance FromJSON Term where
3687 parseJSON = withObject "Term" parse
3688 where parse o = do termObj <- o .: "term"
3689 case HM.toList termObj of
3690 [(fn, v)] -> Term fn <$> parseJSON v
3691 _ -> fail "Expected object with 1 field-named key"
3693instance ToJSON BoolMatch where
3694 toJSON (MustMatch term cache) = object ["must" .= term,
3695 "_cache" .= cache]
3696 toJSON (MustNotMatch term cache) = object ["must_not" .= term,
3697 "_cache" .= cache]
3698 toJSON (ShouldMatch terms cache) = object ["should" .= fmap toJSON terms,
3699 "_cache" .= cache]
3701instance FromJSON BoolMatch where
3702 parseJSON = withObject "BoolMatch" parse
3703 where parse o = mustMatch `taggedWith` "must"
3704 <|> mustNotMatch `taggedWith` "must_not"
3705 <|> shouldMatch `taggedWith` "should"
3706 where taggedWith parser k = parser =<< o .: k
3707 mustMatch t = MustMatch t <$> o .:? "_cache" .!= defaultCache
3708 mustNotMatch t = MustNotMatch t <$> o .:? "_cache" .!= defaultCache
3709 shouldMatch t = ShouldMatch t <$> o .:? "_cache" .!= defaultCache
3711instance (FromJSON a) => FromJSON (SearchResult a) where
3712 parseJSON (Object v) = SearchResult <$>
3713 v .: "took" <*>
3714 v .: "timed_out" <*>
3715 v .: "_shards" <*>
3716 v .: "hits" <*>
3717 v .:? "aggregations" <*>
3718 v .:? "_scroll_id"
3719 parseJSON _ = empty
3721instance (FromJSON a) => FromJSON (SearchHits a) where
3722 parseJSON (Object v) = SearchHits <$>
3723 v .: "total" <*>
3724 v .: "max_score" <*>
3725 v .: "hits"
3726 parseJSON _ = empty
3728instance (FromJSON a) => FromJSON (Hit a) where
3729 parseJSON (Object v) = Hit <$>
3730 v .: "_index" <*>
3731 v .: "_type" <*>
3732 v .: "_id" <*>
3733 v .: "_score" <*>
3734 v .:? "_source" <*>
3735 v .:? "highlight"
3736 parseJSON _ = empty
3738instance FromJSON ShardResult where
3739 parseJSON (Object v) = ShardResult <$>
3740 v .: "total" <*>
3741 v .: "successful" <*>
3742 v .: "failed"
3743 parseJSON _ = empty
3746instance FromJSON DocVersion where
3747 parseJSON v = do
3748 i <- parseJSON v
3749 maybe (fail "DocVersion out of range") return $ mkDocVersion i
3751-- This insanity is because ES *sometimes* returns Replica/Shard counts as strings
3752instance FromJSON ReplicaCount where
3753 parseJSON v = parseAsInt v
3754 <|> parseAsString v
3755 where parseAsInt = fmap ReplicaCount . parseJSON
3756 parseAsString = withText "ReplicaCount" (fmap ReplicaCount . parseReadText)
3758instance FromJSON ShardCount where
3759 parseJSON v = parseAsInt v
3760 <|> parseAsString v
3761 where parseAsInt = fmap ShardCount . parseJSON
3762 parseAsString = withText "ShardCount" (fmap ShardCount . parseReadText)
3764instance Bounded DocVersion where
3765 minBound = DocVersion 1
3766 maxBound = DocVersion 9200000000000000000 -- 9.2e+18
3768instance Enum DocVersion where
3769 succ x
3770 | x /= maxBound = DocVersion (succ $ docVersionNumber x)
3771 | otherwise = succError "DocVersion"
3772 pred x
3773 | x /= minBound = DocVersion (pred $ docVersionNumber x)
3774 | otherwise = predError "DocVersion"
3775 toEnum i =
3776 fromMaybe (error $ show i ++ " out of DocVersion range") $ mkDocVersion i
3777 fromEnum = docVersionNumber
3778 enumFrom = boundedEnumFrom
3779 enumFromThen = boundedEnumFromThen
3781-- | Username type used for HTTP Basic authentication. See 'basicAuthHook'.
3782newtype EsUsername = EsUsername { esUsername :: Text } deriving (Read, Show, Eq)
3784-- | Password type used for HTTP Basic authentication. See 'basicAuthHook'.
3785newtype EsPassword = EsPassword { esPassword :: Text } deriving (Read, Show, Eq)
3788data SnapshotRepoSelection = SnapshotRepoList (NonEmpty SnapshotRepoPattern)
3789 | AllSnapshotRepos deriving (Eq, Generic, Show, Typeable)
3792-- | Either specifies an exact repo name or one with globs in it,
3793-- e.g. @RepoPattern "foo*"@ __NOTE__: Patterns are not supported on ES < 1.7
3794data SnapshotRepoPattern = ExactRepo SnapshotRepoName
3795 | RepoPattern Text
3796 deriving (Eq, Generic, Show, Typeable)
3798-- | The unique name of a snapshot repository.
3799newtype SnapshotRepoName = SnapshotRepoName { snapshotRepoName :: Text }
3800 deriving (Eq, Ord, Generic, Show, Typeable, ToJSON, FromJSON)
3803-- | A generic representation of a snapshot repo. This is what gets
3804-- sent to and parsed from the server. For repo types enabled by
3805-- plugins that aren't exported by this library, consider making a
3806-- custom type which implements 'SnapshotRepo'. If it is a common repo
3807-- type, consider submitting a pull request to have it included in the
3808-- library proper
3809data GenericSnapshotRepo = GenericSnapshotRepo {
3810 gSnapshotRepoName :: SnapshotRepoName
3811 , gSnapshotRepoType :: SnapshotRepoType
3812 , gSnapshotRepoSettings :: GenericSnapshotRepoSettings
3813 } deriving (Eq, Generic, Show, Typeable)
3816instance SnapshotRepo GenericSnapshotRepo where
3817 toGSnapshotRepo = id
3818 fromGSnapshotRepo = Right
3821newtype SnapshotRepoType = SnapshotRepoType { snapshotRepoType :: Text }
3822 deriving (Eq, Ord, Generic, Show, Typeable, ToJSON, FromJSON)
3825-- | Opaque representation of snapshot repo settings. Instances of
3826-- 'SnapshotRepo' will produce this.
3827newtype GenericSnapshotRepoSettings = GenericSnapshotRepoSettings { gSnapshotRepoSettingsObject :: Object }
3828 deriving (Eq, Generic, Show, Typeable, ToJSON)
3831 -- Regardless of whether you send strongly typed json, my version of
3832 -- ES sends back stringly typed json in the settings, e.g. booleans
3833 -- as strings, so we'll try to convert them.
3834instance FromJSON GenericSnapshotRepoSettings where
3835 parseJSON = fmap (GenericSnapshotRepoSettings . fmap unStringlyTypeJSON). parseJSON
3837-- | The result of running 'verifySnapshotRepo'.
3838newtype SnapshotVerification = SnapshotVerification { snapshotNodeVerifications :: [SnapshotNodeVerification] }
3839 deriving (Eq, Generic, Show, Typeable)
3842instance FromJSON SnapshotVerification where
3843 parseJSON = withObject "SnapshotVerification" parse
3844 where
3845 parse o = do
3846 o2 <- o .: "nodes"
3847 SnapshotVerification <$> mapM (uncurry parse') (HM.toList o2)
3848 parse' rawFullId = withObject "SnapshotNodeVerification" $ \o ->
3849 SnapshotNodeVerification (FullNodeId rawFullId) <$> o .: "name"
3852-- | A node that has verified a snapshot
3853data SnapshotNodeVerification = SnapshotNodeVerification {
3854 snvFullId :: FullNodeId
3855 , snvNodeName :: NodeName
3856 } deriving (Eq, Generic, Show, Typeable)
3859-- | Unique, automatically-generated name assigned to nodes that are
3860-- usually returned in node-oriented APIs.
3861newtype FullNodeId = FullNodeId { fullNodeId :: Text }
3862 deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
3865-- | A human-readable node name that is supplied by the user in the
3866-- node config or automatically generated by ElasticSearch.
3867newtype NodeName = NodeName { nodeName :: Text }
3868 deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
3870newtype ClusterName = ClusterName { clusterName :: Text }
3871 deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
3873data NodesInfo = NodesInfo {
3874 nodesInfo :: [NodeInfo]
3875 , nodesClusterName :: ClusterName
3876 } deriving (Eq, Show, Generic, Typeable)
3878data NodesStats = NodesStats {
3879 nodesStats :: [NodeStats]
3880 , nodesStatsClusterName :: ClusterName
3881 } deriving (Eq, Show, Generic, Typeable)
3883data NodeStats = NodeStats {
3884 nodeStatsName :: NodeName
3885 , nodeStatsFullId :: FullNodeId
3886 , nodeStatsBreakersStats :: Maybe NodeBreakersStats
3887 , nodeStatsHTTP :: NodeHTTPStats
3888 , nodeStatsTransport :: NodeTransportStats
3889 , nodeStatsFS :: NodeFSStats
3890 , nodeStatsNetwork :: NodeNetworkStats
3891 , nodeStatsThreadPool :: NodeThreadPoolsStats
3892 , nodeStatsJVM :: NodeJVMStats
3893 , nodeStatsProcess :: NodeProcessStats
3894 , nodeStatsOS :: NodeOSStats
3895 , nodeStatsIndices :: NodeIndicesStats
3896 } deriving (Eq, Show, Generic, Typeable)
3898data NodeBreakersStats = NodeBreakersStats {
3899 nodeStatsParentBreaker :: NodeBreakerStats
3900 , nodeStatsRequestBreaker :: NodeBreakerStats
3901 , nodeStatsFieldDataBreaker :: NodeBreakerStats
3902 } deriving (Eq, Show, Generic, Typeable)
3904data NodeBreakerStats = NodeBreakerStats {
3905 nodeBreakersTripped :: Int
3906 , nodeBreakersOverhead :: Double
3907 , nodeBreakersEstSize :: Bytes
3908 , nodeBreakersLimitSize :: Bytes
3909 } deriving (Eq, Show, Generic, Typeable)
3911data NodeHTTPStats = NodeHTTPStats {
3912 nodeHTTPTotalOpened :: Int
3913 , nodeHTTPCurrentOpen :: Int
3914 } deriving (Eq, Show, Generic, Typeable)
3916data NodeTransportStats = NodeTransportStats {
3917 nodeTransportTXSize :: Bytes
3918 , nodeTransportCount :: Int
3919 , nodeTransportRXSize :: Bytes
3920 , nodeTransportRXCount :: Int
3921 , nodeTransportServerOpen :: Int
3922 } deriving (Eq, Show, Generic, Typeable)
3924data NodeFSStats = NodeFSStats {
3925 nodeFSDataPaths :: [NodeDataPathStats]
3926 , nodeFSTotal :: NodeFSTotalStats
3927 , nodeFSTimestamp :: UTCTime
3928 } deriving (Eq, Show, Generic, Typeable)
3930data NodeDataPathStats = NodeDataPathStats {
3931 nodeDataPathDiskServiceTime :: Maybe Double
3932 , nodeDataPathDiskQueue :: Maybe Double
3933 , nodeDataPathIOSize :: Maybe Bytes
3934 , nodeDataPathWriteSize :: Maybe Bytes
3935 , nodeDataPathReadSize :: Maybe Bytes
3936 , nodeDataPathIOOps :: Maybe Int
3937 , nodeDataPathWrites :: Maybe Int
3938 , nodeDataPathReads :: Maybe Int
3939 , nodeDataPathAvailable :: Bytes
3940 , nodeDataPathFree :: Bytes
3941 , nodeDataPathTotal :: Bytes
3942 , nodeDataPathType :: Maybe Text
3943 , nodeDataPathDevice :: Text
3944 , nodeDataPathMount :: Text
3945 , nodeDataPathPath :: Text
3946 } deriving (Eq, Show, Generic, Typeable)
3948data NodeFSTotalStats = NodeFSTotalStats {
3949 nodeFSTotalDiskServiceTime :: Maybe Double
3950 , nodeFSTotalDiskQueue :: Maybe Double
3951 , nodeFSTotalIOSize :: Maybe Bytes
3952 , nodeFSTotalWriteSize :: Maybe Bytes
3953 , nodeFSTotalReadSize :: Maybe Bytes
3954 , nodeFSTotalIOOps :: Maybe Int
3955 , nodeFSTotalWrites :: Maybe Int
3956 , nodeFSTotalReads :: Maybe Int
3957 , nodeFSTotalAvailable :: Bytes
3958 , nodeFSTotalFree :: Bytes
3959 , nodeFSTotalTotal :: Bytes
3960 } deriving (Eq, Show, Generic, Typeable)
3962data NodeNetworkStats = NodeNetworkStats {
3963 nodeNetTCPOutRSTs :: Int
3964 , nodeNetTCPInErrs :: Int
3965 , nodeNetTCPAttemptFails :: Int
3966 , nodeNetTCPEstabResets :: Int
3967 , nodeNetTCPRetransSegs :: Int
3968 , nodeNetTCPOutSegs :: Int
3969 , nodeNetTCPInSegs :: Int
3970 , nodeNetTCPCurrEstab :: Int
3971 , nodeNetTCPPassiveOpens :: Int
3972 , nodeNetTCPActiveOpens :: Int
3973 } deriving (Eq, Show, Generic, Typeable)
3975data NodeThreadPoolsStats = NodeThreadPoolsStats {
3976 nodeThreadPoolsStatsSnapshot :: NodeThreadPoolStats
3977 , nodeThreadPoolsStatsBulk :: NodeThreadPoolStats
3978 , nodeThreadPoolsStatsMerge :: NodeThreadPoolStats
3979 , nodeThreadPoolsStatsGet :: NodeThreadPoolStats
3980 , nodeThreadPoolsStatsManagement :: NodeThreadPoolStats
3981 , nodeThreadPoolsStatsFetchShardStore :: Maybe NodeThreadPoolStats
3982 , nodeThreadPoolsStatsOptimize :: NodeThreadPoolStats
3983 , nodeThreadPoolsStatsFlush :: NodeThreadPoolStats
3984 , nodeThreadPoolsStatsSearch :: NodeThreadPoolStats
3985 , nodeThreadPoolsStatsWarmer :: NodeThreadPoolStats
3986 , nodeThreadPoolsStatsGeneric :: NodeThreadPoolStats
3987 , nodeThreadPoolsStatsSuggest :: NodeThreadPoolStats
3988 , nodeThreadPoolsStatsRefresh :: NodeThreadPoolStats
3989 , nodeThreadPoolsStatsIndex :: NodeThreadPoolStats
3990 , nodeThreadPoolsStatsListener :: Maybe NodeThreadPoolStats
3991 , nodeThreadPoolsStatsFetchShardStarted :: Maybe NodeThreadPoolStats
3992 , nodeThreadPoolsStatsPercolate :: NodeThreadPoolStats
3993 } deriving (Eq, Show, Generic, Typeable)
3995data NodeThreadPoolStats = NodeThreadPoolStats {
3996 nodeThreadPoolCompleted :: Int
3997 , nodeThreadPoolLargest :: Int
3998 , nodeThreadPoolRejected :: Int
3999 , nodeThreadPoolActive :: Int
4000 , nodeThreadPoolQueue :: Int
4001 , nodeThreadPoolThreads :: Int
4002 } deriving (Eq, Show, Generic, Typeable)
4004data NodeJVMStats = NodeJVMStats {
4005 nodeJVMStatsMappedBufferPool :: JVMBufferPoolStats
4006 , nodeJVMStatsDirectBufferPool :: JVMBufferPoolStats
4007 , nodeJVMStatsGCOldCollector :: JVMGCStats
4008 , nodeJVMStatsGCYoungCollector :: JVMGCStats
4009 , nodeJVMStatsPeakThreadsCount :: Int
4010 , nodeJVMStatsThreadsCount :: Int
4011 , nodeJVMStatsOldPool :: JVMPoolStats
4012 , nodeJVMStatsSurvivorPool :: JVMPoolStats
4013 , nodeJVMStatsYoungPool :: JVMPoolStats
4014 , nodeJVMStatsNonHeapCommitted :: Bytes
4015 , nodeJVMStatsNonHeapUsed :: Bytes
4016 , nodeJVMStatsHeapMax :: Bytes
4017 , nodeJVMStatsHeapCommitted :: Bytes
4018 , nodeJVMStatsHeapUsedPercent :: Int
4019 , nodeJVMStatsHeapUsed :: Bytes
4020 , nodeJVMStatsUptime :: NominalDiffTime
4021 , nodeJVMStatsTimestamp :: UTCTime
4022 } deriving (Eq, Show, Generic, Typeable)
4024data JVMBufferPoolStats = JVMBufferPoolStats {
4025 jvmBufferPoolStatsTotalCapacity :: Bytes
4026 , jvmBufferPoolStatsUsed :: Bytes
4027 , jvmBufferPoolStatsCount :: Int
4028 } deriving (Eq, Show, Generic, Typeable)
4030data JVMGCStats = JVMGCStats {
4031 jvmGCStatsCollectionTime :: NominalDiffTime
4032 , jvmGCStatsCollectionCount :: Int
4033 } deriving (Eq, Show, Generic, Typeable)
4035data JVMPoolStats = JVMPoolStats {
4036 jvmPoolStatsPeakMax :: Bytes
4037 , jvmPoolStatsPeakUsed :: Bytes
4038 , jvmPoolStatsMax :: Bytes
4039 , jvmPoolStatsUsed :: Bytes
4040 } deriving (Eq, Show, Generic, Typeable)
4042data NodeProcessStats = NodeProcessStats {
4043 nodeProcessMemTotalVirtual :: Bytes
4044 , nodeProcessMemShare :: Bytes
4045 , nodeProcessMemResident :: Bytes
4046 , nodeProcessCPUTotal :: NominalDiffTime
4047 , nodeProcessCPUUser :: NominalDiffTime
4048 , nodeProcessCPUSys :: NominalDiffTime
4049 , nodeProcessCPUPercent :: Int
4050 , nodeProcessOpenFDs :: Int
4051 , nodeProcessTimestamp :: UTCTime
4052 } deriving (Eq, Show, Generic, Typeable)
4054data NodeOSStats = NodeOSStats {
4055 nodeOSSwapFree :: Bytes
4056 , nodeOSSwapUsed :: Bytes
4057 , nodeOSMemActualUsed :: Bytes
4058 , nodeOSMemActualFree :: Bytes
4059 , nodeOSMemUsedPercent :: Int
4060 , nodeOSMemFreePercent :: Int
4061 , nodeOSMemUsed :: Bytes
4062 , nodeOSMemFree :: Bytes
4063 , nodeOSCPUStolen :: Int
4064 , nodeOSCPUUsage :: Int
4065 , nodeOSCPUIdle :: Int
4066 , nodeOSCPUUser :: Int
4067 , nodeOSCPUSys :: Int
4068 , nodeOSLoad :: Maybe LoadAvgs
4069 , nodeOSUptime :: NominalDiffTime
4070 , nodeOSTimestamp :: UTCTime
4071 } deriving (Eq, Show, Generic, Typeable)
4073data LoadAvgs = LoadAvgs {
4074 loadAvg1Min :: Double
4075 , loadAvg5Min :: Double
4076 , loadAvg15Min :: Double
4077 } deriving (Eq, Show, Generic, Typeable)
4079data NodeIndicesStats = NodeIndicesStats {
4080 nodeIndicesStatsRecoveryThrottleTime :: Maybe NominalDiffTime
4081 , nodeIndicesStatsRecoveryCurrentAsTarget :: Maybe Int
4082 , nodeIndicesStatsRecoveryCurrentAsSource :: Maybe Int
4083 , nodeIndicesStatsQueryCacheMisses :: Maybe Int
4084 , nodeIndicesStatsQueryCacheHits :: Maybe Int
4085 , nodeIndicesStatsQueryCacheEvictions :: Maybe Int
4086 , nodeIndicesStatsQueryCacheSize :: Maybe Bytes
4087 , nodeIndicesStatsSuggestCurrent :: Int
4088 , nodeIndicesStatsSuggestTime :: NominalDiffTime
4089 , nodeIndicesStatsSuggestTotal :: Int
4090 , nodeIndicesStatsTranslogSize :: Bytes
4091 , nodeIndicesStatsTranslogOps :: Int
4092 , nodeIndicesStatsSegFixedBitSetMemory :: Maybe Bytes
4093 , nodeIndicesStatsSegVersionMapMemory :: Bytes
4094 , nodeIndicesStatsSegIndexWriterMaxMemory :: Maybe Bytes
4095 , nodeIndicesStatsSegIndexWriterMemory :: Bytes
4096 , nodeIndicesStatsSegMemory :: Bytes
4097 , nodeIndicesStatsSegCount :: Int
4098 , nodeIndicesStatsCompletionSize :: Bytes
4099 , nodeIndicesStatsPercolateQueries :: Int
4100 , nodeIndicesStatsPercolateMemory :: Bytes
4101 , nodeIndicesStatsPercolateCurrent :: Int
4102 , nodeIndicesStatsPercolateTime :: NominalDiffTime
4103 , nodeIndicesStatsPercolateTotal :: Int
4104 , nodeIndicesStatsFieldDataEvictions :: Int
4105 , nodeIndicesStatsFieldDataMemory :: Bytes
4106 , nodeIndicesStatsIDCacheMemory :: Bytes
4107 , nodeIndicesStatsFilterCacheEvictions :: Int
4108 , nodeIndicesStatsFilterCacheMemory :: Bytes
4109 , nodeIndicesStatsWarmerTotalTime :: NominalDiffTime
4110 , nodeIndicesStatsWarmerTotal :: Int
4111 , nodeIndicesStatsWarmerCurrent :: Int
4112 , nodeIndicesStatsFlushTotalTime :: NominalDiffTime
4113 , nodeIndicesStatsFlushTotal :: Int
4114 , nodeIndicesStatsRefreshTotalTime :: NominalDiffTime
4115 , nodeIndicesStatsRefreshTotal :: Int
4116 , nodeIndicesStatsMergesTotalSize :: Bytes
4117 , nodeIndicesStatsMergesTotalDocs :: Int
4118 , nodeIndicesStatsMergesTotalTime :: NominalDiffTime
4119 , nodeIndicesStatsMergesTotal :: Int
4120 , nodeIndicesStatsMergesCurrentSize :: Bytes
4121 , nodeIndicesStatsMergesCurrentDocs :: Int
4122 , nodeIndicesStatsMergesCurrent :: Int
4123 , nodeIndicesStatsSearchFetchCurrent :: Int
4124 , nodeIndicesStatsSearchFetchTime :: NominalDiffTime
4125 , nodeIndicesStatsSearchFetchTotal :: Int
4126 , nodeIndicesStatsSearchQueryCurrent :: Int
4127 , nodeIndicesStatsSearchQueryTime :: NominalDiffTime
4128 , nodeIndicesStatsSearchQueryTotal :: Int
4129 , nodeIndicesStatsSearchOpenContexts :: Int
4130 , nodeIndicesStatsGetCurrent :: Int
4131 , nodeIndicesStatsGetMissingTime :: NominalDiffTime
4132 , nodeIndicesStatsGetMissingTotal :: Int
4133 , nodeIndicesStatsGetExistsTime :: NominalDiffTime
4134 , nodeIndicesStatsGetExistsTotal :: Int
4135 , nodeIndicesStatsGetTime :: NominalDiffTime
4136 , nodeIndicesStatsGetTotal :: Int
4137 , nodeIndicesStatsIndexingThrottleTime :: Maybe NominalDiffTime
4138 , nodeIndicesStatsIndexingIsThrottled :: Maybe Bool
4139 , nodeIndicesStatsIndexingNoopUpdateTotal :: Maybe Int
4140 , nodeIndicesStatsIndexingDeleteCurrent :: Int
4141 , nodeIndicesStatsIndexingDeleteTime :: NominalDiffTime
4142 , nodeIndicesStatsIndexingDeleteTotal :: Int
4143 , nodeIndicesStatsIndexingIndexCurrent :: Int
4144 , nodeIndicesStatsIndexingIndexTime :: NominalDiffTime
4145 , nodeIndicesStatsIndexingTotal :: Int
4146 , nodeIndicesStatsStoreThrottleTime :: NominalDiffTime
4147 , nodeIndicesStatsStoreSize :: Bytes
4148 , nodeIndicesStatsDocsDeleted :: Int
4149 , nodeIndicesStatsDocsCount :: Int
4150 } deriving (Eq, Show, Generic, Typeable)
4152-- | A quirky address format used throughout ElasticSearch. An example
4153-- would be inet[/1.1.1.1:9200]. inet may be a placeholder for a
4154-- <https://en.wikipedia.org/wiki/Fully_qualified_domain_name FQDN>.
4155newtype EsAddress = EsAddress { esAddress :: Text }
4156 deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
4158-- | Typically a 7 character hex string.
4159newtype BuildHash = BuildHash { buildHash :: Text }
4160 deriving (Eq, Ord, Generic, Read, Show, Typeable, FromJSON, ToJSON)
4162newtype PluginName = PluginName { pluginName :: Text }
4163 deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
4165data NodeInfo = NodeInfo {
4166 nodeInfoHTTPAddress :: EsAddress
4167 , nodeInfoBuild :: BuildHash
4168 , nodeInfoESVersion :: VersionNumber
4169 , nodeInfoIP :: Server
4170 , nodeInfoHost :: Server
4171 , nodeInfoTransportAddress :: EsAddress
4172 , nodeInfoName :: NodeName
4173 , nodeInfoFullId :: FullNodeId
4174 , nodeInfoPlugins :: [NodePluginInfo]
4175 , nodeInfoHTTP :: NodeHTTPInfo
4176 , nodeInfoTransport :: NodeTransportInfo
4177 , nodeInfoNetwork :: NodeNetworkInfo
4178 , nodeInfoThreadPool :: NodeThreadPoolsInfo
4179 , nodeInfoJVM :: NodeJVMInfo
4180 , nodeInfoProcess :: NodeProcessInfo
4181 , nodeInfoOS :: NodeOSInfo
4182 , nodeInfoSettings :: Object
4183 -- ^ The members of the settings objects are not consistent,
4184 -- dependent on plugins, etc.
4185 } deriving (Eq, Show, Generic, Typeable)
4187data NodePluginInfo = NodePluginInfo {
4188 nodePluginSite :: Bool
4189 -- ^ Is this a site plugin?
4190 , nodePluginJVM :: Bool
4191 -- ^ Is this plugin running on the JVM
4192 , nodePluginDescription :: Text
4193 , nodePluginVersion :: MaybeNA VersionNumber
4194 , nodePluginName :: PluginName
4195 } deriving (Eq, Show, Generic, Typeable)
4197data NodeHTTPInfo = NodeHTTPInfo {
4198 nodeHTTPMaxContentLength :: Bytes
4199 , nodeHTTPTransportAddress :: BoundTransportAddress
4200 } deriving (Eq, Show, Generic, Typeable)
4202data NodeTransportInfo = NodeTransportInfo {
4203 nodeTransportProfiles :: [BoundTransportAddress]
4204 , nodeTransportAddress :: BoundTransportAddress
4205 } deriving (Eq, Show, Generic, Typeable)
4207data BoundTransportAddress = BoundTransportAddress {
4208 publishAddress :: EsAddress
4209 , boundAddress :: EsAddress
4210 } deriving (Eq, Show, Generic, Typeable)
4212data NodeNetworkInfo = NodeNetworkInfo {
4213 nodeNetworkPrimaryInterface :: NodeNetworkInterface
4214 , nodeNetworkRefreshInterval :: NominalDiffTime
4215 } deriving (Eq, Show, Generic, Typeable)
4217newtype MacAddress = MacAddress { macAddress :: Text }
4218 deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
4220newtype NetworkInterfaceName = NetworkInterfaceName { networkInterfaceName :: Text }
4221 deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
4223data NodeNetworkInterface = NodeNetworkInterface {
4224 nodeNetIfaceMacAddress :: MacAddress
4225 , nodeNetIfaceName :: NetworkInterfaceName
4226 , nodeNetIfaceAddress :: Server
4227 } deriving (Eq, Show, Generic, Typeable)
4229data NodeThreadPoolsInfo = NodeThreadPoolsInfo {
4230 nodeThreadPoolsRefresh :: NodeThreadPoolInfo
4231 , nodeThreadPoolsManagement :: NodeThreadPoolInfo
4232 , nodeThreadPoolsPercolate :: NodeThreadPoolInfo
4233 , nodeThreadPoolsListener :: Maybe NodeThreadPoolInfo
4234 , nodeThreadPoolsFetchShardStarted :: Maybe NodeThreadPoolInfo
4235 , nodeThreadPoolsSearch :: NodeThreadPoolInfo
4236 , nodeThreadPoolsFlush :: NodeThreadPoolInfo
4237 , nodeThreadPoolsWarmer :: NodeThreadPoolInfo
4238 , nodeThreadPoolsOptimize :: NodeThreadPoolInfo
4239 , nodeThreadPoolsBulk :: NodeThreadPoolInfo
4240 , nodeThreadPoolsSuggest :: NodeThreadPoolInfo
4241 , nodeThreadPoolsMerge :: NodeThreadPoolInfo
4242 , nodeThreadPoolsSnapshot :: NodeThreadPoolInfo
4243 , nodeThreadPoolsGet :: NodeThreadPoolInfo
4244 , nodeThreadPoolsFetchShardStore :: Maybe NodeThreadPoolInfo
4245 , nodeThreadPoolsIndex :: NodeThreadPoolInfo
4246 , nodeThreadPoolsGeneric :: NodeThreadPoolInfo
4247 } deriving (Eq, Show, Generic, Typeable)
4249data NodeThreadPoolInfo = NodeThreadPoolInfo {
4250 nodeThreadPoolQueueSize :: ThreadPoolSize
4251 , nodeThreadPoolKeepalive :: Maybe NominalDiffTime
4252 , nodeThreadPoolMin :: Maybe Int
4253 , nodeThreadPoolMax :: Maybe Int
4254 , nodeThreadPoolType :: ThreadPoolType
4255 } deriving (Eq, Show, Generic, Typeable)
4257data ThreadPoolSize = ThreadPoolBounded Int
4258 | ThreadPoolUnbounded
4259 deriving (Eq, Show, Generic, Typeable)
4261data ThreadPoolType = ThreadPoolScaling
4262 | ThreadPoolFixed
4263 | ThreadPoolCached
4264 deriving (Eq, Show, Generic, Typeable)
4266data NodeJVMInfo = NodeJVMInfo {
4267 nodeJVMInfoMemoryPools :: [JVMMemoryPool]
4268 , nodeJVMInfoMemoryPoolsGCCollectors :: [JVMGCCollector]
4269 , nodeJVMInfoMemoryInfo :: JVMMemoryInfo
4270 , nodeJVMInfoStartTime :: UTCTime
4271 , nodeJVMInfoVMVendor :: Text
4272 , nodeJVMVMVersion :: VersionNumber
4273 -- ^ JVM doesn't seme to follow normal version conventions
4274 , nodeJVMVMName :: Text
4275 , nodeJVMVersion :: VersionNumber
4276 , nodeJVMPID :: PID
4277 } deriving (Eq, Show, Generic, Typeable)
4279-- | Handles quirks in the way JVM versions are rendered (1.7.0_101 -> 1.7.0.101)
4280newtype JVMVersion = JVMVersion { unJVMVersion :: VersionNumber }
4282data JVMMemoryInfo = JVMMemoryInfo {
4283 jvmMemoryInfoDirectMax :: Bytes
4284 , jvmMemoryInfoNonHeapMax :: Bytes
4285 , jvmMemoryInfoNonHeapInit :: Bytes
4286 , jvmMemoryInfoHeapMax :: Bytes
4287 , jvmMemoryInfoHeapInit :: Bytes
4288 } deriving (Eq, Show, Generic, Typeable)
4290newtype JVMMemoryPool = JVMMemoryPool {
4291 jvmMemoryPool :: Text
4292 } deriving (Eq, Show, Generic, Typeable, FromJSON)
4294newtype JVMGCCollector = JVMGCCollector {
4295 jvmGCCollector :: Text
4296 } deriving (Eq, Show, Generic, Typeable, FromJSON)
4298newtype PID = PID {
4299 pid :: Int
4300 } deriving (Eq, Show, Generic, Typeable, FromJSON)
4302data NodeOSInfo = NodeOSInfo {
4303 nodeOSSwap :: Bytes
4304 , nodeOSMem :: Bytes
4305 , nodeOSCPUInfo :: CPUInfo
4306 , nodeOSAvailableProcessors :: Int
4307 , nodeOSRefreshInterval :: NominalDiffTime
4308 } deriving (Eq, Show, Generic, Typeable)
4310data CPUInfo = CPUInfo {
4311 cpuCacheSize :: Bytes
4312 , cpuCoresPerSocket :: Int
4313 , cpuTotalSockets :: Int
4314 , cpuTotalCores :: Int
4315 , cpuMHZ :: Int
4316 , cpuModel :: Text
4317 , cpuVendor :: Text
4318 } deriving (Eq, Show, Generic, Typeable)
4320data NodeProcessInfo = NodeProcessInfo {
4321 nodeProcessMLockAll :: Bool
4322 -- ^ See <https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration.html>
4323 , nodeProcessMaxFileDescriptors :: Int
4324 , nodeProcessId :: PID
4325 , nodeProcessRefreshInterval :: NominalDiffTime
4326 } deriving (Eq, Show, Generic, Typeable)
4328data SnapshotRepoUpdateSettings = SnapshotRepoUpdateSettings {
4329 repoUpdateVerify :: Bool
4330 -- ^ After creation/update, synchronously check that nodes can
4331 -- write to this repo. Defaults to True. You may use False if you
4332 -- need a faster response and plan on verifying manually later
4333 -- with 'verifySnapshotRepo'.
4334 } deriving (Eq, Show, Generic, Typeable)
4337-- | Reasonable defaults for repo creation/update
4339-- * repoUpdateVerify True
4340defaultSnapshotRepoUpdateSettings :: SnapshotRepoUpdateSettings
4341defaultSnapshotRepoUpdateSettings = SnapshotRepoUpdateSettings True
4344-- | A filesystem-based snapshot repo that ships with
4345-- ElasticSearch. This is an instance of 'SnapshotRepo' so it can be
4346-- used with 'updateSnapshotRepo'
4347data FsSnapshotRepo = FsSnapshotRepo {
4348 fsrName :: SnapshotRepoName
4349 , fsrLocation :: FilePath
4350 , fsrCompressMetadata :: Bool
4351 , fsrChunkSize :: Maybe Bytes
4352 -- ^ Size by which to split large files during snapshotting.
4353 , fsrMaxRestoreBytesPerSec :: Maybe Bytes
4354 -- ^ Throttle node restore rate. If not supplied, defaults to 40mb/sec
4355 , fsrMaxSnapshotBytesPerSec :: Maybe Bytes
4356 -- ^ Throttle node snapshot rate. If not supplied, defaults to 40mb/sec
4357 } deriving (Eq, Generic, Show, Typeable)
4360instance SnapshotRepo FsSnapshotRepo where
4361 toGSnapshotRepo FsSnapshotRepo {..} =
4362 GenericSnapshotRepo fsrName fsRepoType (GenericSnapshotRepoSettings settings)
4363 where
4364 Object settings = object $ [ "location" .= fsrLocation
4365 , "compress" .= fsrCompressMetadata
4366 ] ++ optionalPairs
4367 optionalPairs = catMaybes [ ("chunk_size" .=) <$> fsrChunkSize
4368 , ("max_restore_bytes_per_sec" .=) <$> fsrMaxRestoreBytesPerSec
4369 , ("max_snapshot_bytes_per_sec" .=) <$> fsrMaxSnapshotBytesPerSec
4371 fromGSnapshotRepo GenericSnapshotRepo {..}
4372 | gSnapshotRepoType == fsRepoType = do
4373 let o = gSnapshotRepoSettingsObject gSnapshotRepoSettings
4374 parseRepo $ do
4375 FsSnapshotRepo gSnapshotRepoName <$> o .: "location"
4376 <*> o .:? "compress" .!= False
4377 <*> o .:? "chunk_size"
4378 <*> o .:? "max_restore_bytes_per_sec"
4379 <*> o .:? "max_snapshot_bytes_per_sec"
4380 | otherwise = Left (RepoTypeMismatch fsRepoType gSnapshotRepoType)
4383parseRepo :: Parser a -> Either SnapshotRepoConversionError a
4384parseRepo parser = case parseEither (const parser) () of
4385 Left e -> Left (OtherRepoConversionError (T.pack e))
4386 Right a -> Right a
4389fsRepoType :: SnapshotRepoType
4390fsRepoType = SnapshotRepoType "fs"
4392-- | Law: fromGSnapshotRepo (toGSnapshotRepo r) == Right r
4393class SnapshotRepo r where
4394 toGSnapshotRepo :: r -> GenericSnapshotRepo
4395 fromGSnapshotRepo :: GenericSnapshotRepo -> Either SnapshotRepoConversionError r
4398data SnapshotRepoConversionError = RepoTypeMismatch SnapshotRepoType SnapshotRepoType
4399 -- ^ Expected type and actual type
4400 | OtherRepoConversionError Text
4401 deriving (Show, Eq, Generic, Typeable)
4404instance Exception SnapshotRepoConversionError
4407data SnapshotCreateSettings = SnapshotCreateSettings {
4408 snapWaitForCompletion :: Bool
4409 -- ^ Should the API call return immediately after initializing
4410 -- the snapshot or wait until completed? Note that if this is
4411 -- enabled it could wait a long time, so you should adjust your
4412 -- 'ManagerSettings' accordingly to set long timeouts or
4413 -- explicitly handle timeouts.
4414 , snapIndices :: Maybe IndexSelection
4415 -- ^ Nothing will snapshot all indices. Just [] is permissable and
4416 -- will essentially be a no-op snapshot.
4417 , snapIgnoreUnavailable :: Bool
4418 -- ^ If set to True, any matched indices that don't exist will be
4419 -- ignored. Otherwise it will be an error and fail.
4420 , snapIncludeGlobalState :: Bool
4421 , snapPartial :: Bool
4422 -- ^ If some indices failed to snapshot (e.g. if not all primary
4423 -- shards are available), should the process proceed?
4424 } deriving (Eq, Generic, Show, Typeable)
4427-- | Reasonable defaults for snapshot creation
4429-- * snapWaitForCompletion False
4430-- * snapIndices Nothing
4431-- * snapIgnoreUnavailable False
4432-- * snapIncludeGlobalState True
4433-- * snapPartial False
4434defaultSnapshotCreateSettings :: SnapshotCreateSettings
4435defaultSnapshotCreateSettings = SnapshotCreateSettings {
4436 snapWaitForCompletion = False
4437 , snapIndices = Nothing
4438 , snapIgnoreUnavailable = False
4439 , snapIncludeGlobalState = True
4440 , snapPartial = False
4444data SnapshotSelection = SnapshotList (NonEmpty SnapshotPattern)
4445 | AllSnapshots deriving (Eq, Generic, Show, Typeable)
4448-- | Either specifies an exact snapshot name or one with globs in it,
4449-- e.g. @SnapPattern "foo*"@ __NOTE__: Patterns are not supported on
4450-- ES < 1.7
4451data SnapshotPattern = ExactSnap SnapshotName
4452 | SnapPattern Text
4453 deriving (Eq, Generic, Show, Typeable)
4456-- | General information about the state of a snapshot. Has some
4457-- redundancies with 'SnapshotStatus'
4458data SnapshotInfo = SnapshotInfo {
4459 snapInfoShards :: ShardResult
4460 , snapInfoFailures :: [SnapshotShardFailure]
4461 , snapInfoDuration :: NominalDiffTime
4462 , snapInfoEndTime :: UTCTime
4463 , snapInfoStartTime :: UTCTime
4464 , snapInfoState :: SnapshotState
4465 , snapInfoIndices :: [IndexName]
4466 , snapInfoName :: SnapshotName
4467 } deriving (Eq, Generic, Show, Typeable)
4470instance FromJSON SnapshotInfo where
4471 parseJSON = withObject "SnapshotInfo" parse
4472 where
4473 parse o = SnapshotInfo <$> o .: "shards"
4474 <*> o .: "failures"
4475 <*> (unMS <$> o .: "duration_in_millis")
4476 <*> (posixMS <$> o .: "end_time_in_millis")
4477 <*> (posixMS <$> o .: "start_time_in_millis")
4478 <*> o .: "state"
4479 <*> o .: "indices"
4480 <*> o .: "snapshot"
4482data SnapshotShardFailure = SnapshotShardFailure {
4483 snapShardFailureIndex :: IndexName
4484 , snapShardFailureNodeId :: Maybe NodeName -- I'm not 100% sure this isn't actually 'FullNodeId'
4485 , snapShardFailureReason :: Text
4486 , snapShardFailureShardId :: ShardId
4487 } deriving (Eq, Show, Generic, Typeable)
4490instance FromJSON SnapshotShardFailure where
4491 parseJSON = withObject "SnapshotShardFailure" parse
4492 where
4493 parse o = SnapshotShardFailure <$> o .: "index"
4494 <*> o .:? "node_id"
4495 <*> o .: "reason"
4496 <*> o .: "shard_id"
4499newtype ShardId = ShardId { shardId :: Int }
4500 deriving (Eq, Show, Generic, Typeable, FromJSON)
4502-- | Milliseconds
4503newtype MS = MS NominalDiffTime
4506-- keeps the unexported constructor warnings at bay
4507unMS :: MS -> NominalDiffTime
4508unMS (MS t) = t
4511instance FromJSON MS where
4512 parseJSON = withScientific "MS" (return . MS . parse)
4513 where
4514 parse n = fromInteger ((truncate n) * 1000)
4517data SnapshotState = SnapshotInit
4518 | SnapshotStarted
4519 | SnapshotSuccess
4520 | SnapshotFailed
4521 | SnapshotAborted
4522 | SnapshotMissing
4523 | SnapshotWaiting
4524 deriving (Show, Eq, Generic, Typeable)
4526instance FromJSON SnapshotState where
4527 parseJSON = withText "SnapshotState" parse
4528 where
4529 parse "INIT" = return SnapshotInit
4530 parse "STARTED" = return SnapshotStarted
4531 parse "SUCCESS" = return SnapshotSuccess
4532 parse "FAILED" = return SnapshotFailed
4533 parse "ABORTED" = return SnapshotAborted
4534 parse "MISSING" = return SnapshotMissing
4535 parse "WAITING" = return SnapshotWaiting
4536 parse t = fail ("Invalid snapshot state " <> T.unpack t)
4539newtype SnapshotName = SnapshotName { snapshotName :: Text }
4540 deriving (Show, Eq, Ord, Generic, Typeable, ToJSON, FromJSON)
4543data SnapshotRestoreSettings = SnapshotRestoreSettings {
4544 snapRestoreWaitForCompletion :: Bool
4545 -- ^ Should the API call return immediately after initializing
4546 -- the restore or wait until completed? Note that if this is
4547 -- enabled, it could wait a long time, so you should adjust your
4548 -- 'ManagerSettings' accordingly to set long timeouts or
4549 -- explicitly handle timeouts.
4550 , snapRestoreIndices :: Maybe IndexSelection
4551 -- ^ Nothing will restore all indices in the snapshot. Just [] is
4552 -- permissable and will essentially be a no-op restore.
4553 , snapRestoreIgnoreUnavailable :: Bool
4554 -- ^ If set to True, any indices that do not exist will be ignored
4555 -- during snapshot rather than failing the restore.
4556 , snapRestoreIncludeGlobalState :: Bool
4557 -- ^ If set to false, will ignore any global state in the snapshot
4558 -- and will not restore it.
4559 , snapRestoreRenamePattern :: Maybe RestoreRenamePattern
4560 -- ^ A regex pattern for matching indices. Used with
4561 -- 'snapRestoreRenameReplacement', the restore can reference the
4562 -- matched index and create a new index name upon restore.
4563 , snapRestoreRenameReplacement :: Maybe (NonEmpty RestoreRenameToken)
4564 -- ^ Expression of how index renames should be constructed.
4565 , snapRestorePartial :: Bool
4566 -- ^ If some indices fail to restore, should the process proceed?
4567 , snapRestoreIncludeAliases :: Bool
4568 -- ^ Should the restore also restore the aliases captured in the
4569 -- snapshot.
4570 , snapRestoreIndexSettingsOverrides :: Maybe RestoreIndexSettings
4571 -- ^ Settings to apply during the restore process. __NOTE:__ This
4572 -- option is not supported in ES < 1.5 and should be set to
4573 -- Nothing in that case.
4574 , snapRestoreIgnoreIndexSettings :: Maybe (NonEmpty Text)
4575 -- ^ This type could be more rich but it isn't clear which
4576 -- settings are allowed to be ignored during restore, so we're
4577 -- going with including this feature in a basic form rather than
4578 -- omitting it. One example here would be
4579 -- "index.refresh_interval". Any setting specified here will
4580 -- revert back to the server default during the restore process.
4581 } deriving (Eq, Generic, Show, Typeable)
4583-- | Regex-stype pattern, e.g. "index_(.+)" to match index names
4584newtype RestoreRenamePattern = RestoreRenamePattern { rrPattern :: Text }
4585 deriving (Show, Eq, Generic, Typeable, Ord, ToJSON)
4588-- | A single token in a index renaming scheme for a restore. These
4589-- are concatenated into a string before being sent to
4590-- ElasticSearch. Check out these Java
4591-- <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.
4592data RestoreRenameToken = RRTLit Text
4593 -- ^ Just a literal string of characters
4594 | RRSubWholeMatch
4595 -- ^ Equivalent to $0. The entire matched pattern, not any subgroup
4596 | RRSubGroup RRGroupRefNum
4597 -- ^ A specific reference to a group number
4598 deriving (Show, Eq, Generic, Typeable)
4601-- | A group number for regex matching. Only values from 1-9 are
4602-- supported. Construct with 'mkRRGroupRefNum'
4603newtype RRGroupRefNum = RRGroupRefNum { rrGroupRefNum :: Int }
4604 deriving (Show, Eq, Generic, Typeable, Ord)
4606instance Bounded RRGroupRefNum where
4607 minBound = RRGroupRefNum 1
4608 maxBound = RRGroupRefNum 9
4611-- | Only allows valid group number references (1-9).
4612mkRRGroupRefNum :: Int -> Maybe RRGroupRefNum
4613mkRRGroupRefNum i
4614 | i >= (rrGroupRefNum minBound) && i <= (rrGroupRefNum maxBound) =
4615 Just $ RRGroupRefNum i
4616 | otherwise = Nothing
4619-- | Reasonable defaults for snapshot restores
4621-- * snapRestoreWaitForCompletion False
4622-- * snapRestoreIndices Nothing
4623-- * snapRestoreIgnoreUnavailable False
4624-- * snapRestoreIncludeGlobalState True
4625-- * snapRestoreRenamePattern Nothing
4626-- * snapRestoreRenameReplacement Nothing
4627-- * snapRestorePartial False
4628-- * snapRestoreIncludeAliases True
4629-- * snapRestoreIndexSettingsOverrides Nothing
4630-- * snapRestoreIgnoreIndexSettings Nothing
4631defaultSnapshotRestoreSettings :: SnapshotRestoreSettings
4632defaultSnapshotRestoreSettings = SnapshotRestoreSettings {
4633 snapRestoreWaitForCompletion = False
4634 , snapRestoreIndices = Nothing
4635 , snapRestoreIgnoreUnavailable = False
4636 , snapRestoreIncludeGlobalState = True
4637 , snapRestoreRenamePattern = Nothing
4638 , snapRestoreRenameReplacement = Nothing
4639 , snapRestorePartial = False
4640 , snapRestoreIncludeAliases = True
4641 , snapRestoreIndexSettingsOverrides = Nothing
4642 , snapRestoreIgnoreIndexSettings = Nothing
4646-- | Index settings that can be overridden. The docs only mention you
4647-- can update number of replicas, but there may be more. You
4648-- definitely cannot override shard count.
4649data RestoreIndexSettings = RestoreIndexSettings {
4650 restoreOverrideReplicas :: Maybe ReplicaCount
4651 } deriving (Show, Eq, Generic, Typeable)
4654instance ToJSON RestoreIndexSettings where
4655 toJSON RestoreIndexSettings {..} = object prs
4656 where
4657 prs = catMaybes [("index.number_of_replicas" .=) <$> restoreOverrideReplicas]
4660instance FromJSON NodesInfo where
4661 parseJSON = withObject "NodesInfo" parse
4662 where
4663 parse o = do
4664 nodes <- o .: "nodes"
4665 infos <- forM (HM.toList nodes) $ \(fullNID, v) -> do
4666 node <- parseJSON v
4667 parseNodeInfo (FullNodeId fullNID) node
4668 cn <- o .: "cluster_name"
4669 return (NodesInfo infos cn)
4671instance FromJSON NodesStats where
4672 parseJSON = withObject "NodesStats" parse
4673 where
4674 parse o = do
4675 nodes <- o .: "nodes"
4676 stats <- forM (HM.toList nodes) $ \(fullNID, v) -> do
4677 node <- parseJSON v
4678 parseNodeStats (FullNodeId fullNID) node
4679 cn <- o .: "cluster_name"
4680 return (NodesStats stats cn)
4682instance FromJSON NodeBreakerStats where
4683 parseJSON = withObject "NodeBreakerStats" parse
4684 where
4685 parse o = NodeBreakerStats <$> o .: "tripped"
4686 <*> o .: "overhead"
4687 <*> o .: "estimated_size_in_bytes"
4688 <*> o .: "limit_size_in_bytes"
4690instance FromJSON NodeHTTPStats where
4691 parseJSON = withObject "NodeHTTPStats" parse
4692 where
4693 parse o = NodeHTTPStats <$> o .: "total_opened"
4694 <*> o .: "current_open"
4696instance FromJSON NodeTransportStats where
4697 parseJSON = withObject "NodeTransportStats" parse
4698 where
4699 parse o = NodeTransportStats <$> o .: "tx_size_in_bytes"
4700 <*> o .: "tx_count"
4701 <*> o .: "rx_size_in_bytes"
4702 <*> o .: "rx_count"
4703 <*> o .: "server_open"
4705instance FromJSON NodeFSStats where
4706 parseJSON = withObject "NodeFSStats" parse
4707 where
4708 parse o = NodeFSStats <$> o .: "data"
4709 <*> o .: "total"
4710 <*> (posixMS <$> o .: "timestamp")
4712instance FromJSON NodeDataPathStats where
4713 parseJSON = withObject "NodeDataPathStats" parse
4714 where
4715 parse o =
4716 NodeDataPathStats <$> (fmap unStringlyTypedDouble <$> o .:? "disk_service_time")
4717 <*> (fmap unStringlyTypedDouble <$> o .:? "disk_queue")
4718 <*> o .:? "disk_io_size_in_bytes"
4719 <*> o .:? "disk_write_size_in_bytes"
4720 <*> o .:? "disk_read_size_in_bytes"
4721 <*> o .:? "disk_io_op"
4722 <*> o .:? "disk_writes"
4723 <*> o .:? "disk_reads"
4724 <*> o .: "available_in_bytes"
4725 <*> o .: "free_in_bytes"
4726 <*> o .: "total_in_bytes"
4727 <*> o .:? "type"
4728 <*> o .: "dev"
4729 <*> o .: "mount"
4730 <*> o .: "path"
4732newtype StringlyTypedDouble = StringlyTypedDouble { unStringlyTypedDouble :: Double }
4735instance FromJSON StringlyTypedDouble where
4736 parseJSON = fmap StringlyTypedDouble . parseJSON . unStringlyTypeJSON
4739instance FromJSON NodeFSTotalStats where
4740 parseJSON = withObject "NodeFSTotalStats" parse
4741 where
4742 parse o = NodeFSTotalStats <$> (fmap unStringlyTypedDouble <$> o .:? "disk_service_time")
4743 <*> (fmap unStringlyTypedDouble <$> o .:? "disk_queue")
4744 <*> o .:? "disk_io_size_in_bytes"
4745 <*> o .:? "disk_write_size_in_bytes"
4746 <*> o .:? "disk_read_size_in_bytes"
4747 <*> o .:? "disk_io_op"
4748 <*> o .:? "disk_writes"
4749 <*> o .:? "disk_reads"
4750 <*> o .: "available_in_bytes"
4751 <*> o .: "free_in_bytes"
4752 <*> o .: "total_in_bytes"
4754instance FromJSON NodeNetworkStats where
4755 parseJSON = withObject "NodeNetworkStats" parse
4756 where
4757 parse o = do
4758 tcp <- o .: "tcp"
4759 NodeNetworkStats <$> tcp .: "out_rsts"
4760 <*> tcp .: "in_errs"
4761 <*> tcp .: "attempt_fails"
4762 <*> tcp .: "estab_resets"
4763 <*> tcp .: "retrans_segs"
4764 <*> tcp .: "out_segs"
4765 <*> tcp .: "in_segs"
4766 <*> tcp .: "curr_estab"
4767 <*> tcp .: "passive_opens"
4768 <*> tcp .: "active_opens"
4770instance FromJSON NodeThreadPoolsStats where
4771 parseJSON = withObject "NodeThreadPoolsStats" parse
4772 where
4773 parse o = NodeThreadPoolsStats <$> o .: "snapshot"
4774 <*> o .: "bulk"
4775 <*> o .: "merge"
4776 <*> o .: "get"
4777 <*> o .: "management"
4778 <*> o .:? "fetch_shard_store"
4779 <*> o .: "optimize"
4780 <*> o .: "flush"
4781 <*> o .: "search"
4782 <*> o .: "warmer"
4783 <*> o .: "generic"
4784 <*> o .: "suggest"
4785 <*> o .: "refresh"
4786 <*> o .: "index"
4787 <*> o .:? "listener"
4788 <*> o .:? "fetch_shard_started"
4789 <*> o .: "percolate"
4790instance FromJSON NodeThreadPoolStats where
4791 parseJSON = withObject "NodeThreadPoolStats" parse
4792 where
4793 parse o = NodeThreadPoolStats <$> o .: "completed"
4794 <*> o .: "largest"
4795 <*> o .: "rejected"
4796 <*> o .: "active"
4797 <*> o .: "queue"
4798 <*> o .: "threads"
4800instance FromJSON NodeJVMStats where
4801 parseJSON = withObject "NodeJVMStats" parse
4802 where
4803 parse o = do
4804 bufferPools <- o .: "buffer_pools"
4805 mapped <- bufferPools .: "mapped"
4806 direct <- bufferPools .: "direct"
4807 gc <- o .: "gc"
4808 collectors <- gc .: "collectors"
4809 oldC <- collectors .: "old"
4810 youngC <- collectors .: "young"
4811 threads <- o .: "threads"
4812 mem <- o .: "mem"
4813 pools <- mem .: "pools"
4814 oldM <- pools .: "old"
4815 survivorM <- pools .: "survivor"
4816 youngM <- pools .: "young"
4817 NodeJVMStats <$> pure mapped
4818 <*> pure direct
4819 <*> pure oldC
4820 <*> pure youngC
4821 <*> threads .: "peak_count"
4822 <*> threads .: "count"
4823 <*> pure oldM
4824 <*> pure survivorM
4825 <*> pure youngM
4826 <*> mem .: "non_heap_committed_in_bytes"
4827 <*> mem .: "non_heap_used_in_bytes"
4828 <*> mem .: "heap_max_in_bytes"
4829 <*> mem .: "heap_committed_in_bytes"
4830 <*> mem .: "heap_used_percent"
4831 <*> mem .: "heap_used_in_bytes"
4832 <*> (unMS <$> o .: "uptime_in_millis")
4833 <*> (posixMS <$> o .: "timestamp")
4835instance FromJSON JVMBufferPoolStats where
4836 parseJSON = withObject "JVMBufferPoolStats" parse
4837 where
4838 parse o = JVMBufferPoolStats <$> o .: "total_capacity_in_bytes"
4839 <*> o .: "used_in_bytes"
4840 <*> o .: "count"
4842instance FromJSON JVMGCStats where
4843 parseJSON = withObject "JVMGCStats" parse
4844 where
4845 parse o = JVMGCStats <$> (unMS <$> o .: "collection_time_in_millis")
4846 <*> o .: "collection_count"
4848instance FromJSON JVMPoolStats where
4849 parseJSON = withObject "JVMPoolStats" parse
4850 where
4851 parse o = JVMPoolStats <$> o .: "peak_max_in_bytes"
4852 <*> o .: "peak_used_in_bytes"
4853 <*> o .: "max_in_bytes"
4854 <*> o .: "used_in_bytes"
4856instance FromJSON NodeProcessStats where
4857 parseJSON = withObject "NodeProcessStats" parse
4858 where
4859 parse o = do
4860 mem <- o .: "mem"
4861 cpu <- o .: "cpu"
4862 NodeProcessStats <$> mem .: "total_virtual_in_bytes"
4863 <*> mem .: "share_in_bytes"
4864 <*> mem .: "resident_in_bytes"
4865 <*> (unMS <$> cpu .: "total_in_millis")
4866 <*> (unMS <$> cpu .: "user_in_millis")
4867 <*> (unMS <$> cpu .: "sys_in_millis")
4868 <*> cpu .: "percent"
4869 <*> o .: "open_file_descriptors"
4870 <*> (posixMS <$> o .: "timestamp")
4872instance FromJSON NodeOSStats where
4873 parseJSON = withObject "NodeOSStats" parse
4874 where
4875 parse o = do
4876 swap <- o .: "swap"
4877 mem <- o .: "mem"
4878 cpu <- o .: "cpu"
4879 load <- o .:? "load_average"
4880 NodeOSStats <$> swap .: "free_in_bytes"
4881 <*> swap .: "used_in_bytes"
4882 <*> mem .: "actual_used_in_bytes"
4883 <*> mem .: "actual_free_in_bytes"
4884 <*> mem .: "used_percent"
4885 <*> mem .: "free_percent"
4886 <*> mem .: "used_in_bytes"
4887 <*> mem .: "free_in_bytes"
4888 <*> cpu .: "stolen"
4889 <*> cpu .: "usage"
4890 <*> cpu .: "idle"
4891 <*> cpu .: "user"
4892 <*> cpu .: "sys"
4893 <*> pure load
4894 <*> (unMS <$> o .: "uptime_in_millis")
4895 <*> (posixMS <$> o .: "timestamp")
4897instance FromJSON LoadAvgs where
4898 parseJSON = withArray "LoadAvgs" parse
4899 where
4900 parse v = case V.toList v of
4901 [one, five, fifteen] -> LoadAvgs <$> parseJSON one
4902 <*> parseJSON five
4903 <*> parseJSON fifteen
4904 _ -> fail "Expecting a triple of Doubles"
4906instance FromJSON NodeIndicesStats where
4907 parseJSON = withObject "NodeIndicesStats" parse
4908 where
4909 parse o = do
4910 let (.::) mv k = case mv of
4911 Just v -> Just <$> v .: k
4912 Nothing -> pure Nothing
4913 mRecovery <- o .:? "recovery"
4914 mQueryCache <- o .:? "query_cache"
4915 suggest <- o .: "suggest"
4916 translog <- o .: "translog"
4917 segments <- o .: "segments"
4918 completion <- o .: "completion"
4919 percolate <- o .: "percolate"
4920 fielddata <- o .: "fielddata"
4921 idCache <- o .: "id_cache"
4922 filterCache <- o .: "filter_cache"
4923 warmer <- o .: "warmer"
4924 flush <- o .: "flush"
4925 refresh <- o .: "refresh"
4926 merges <- o .: "merges"
4927 search <- o .: "search"
4928 getStats <- o .: "get"
4929 indexing <- o .: "indexing"
4930 store <- o .: "store"
4931 docs <- o .: "docs"
4932 NodeIndicesStats <$> (fmap unMS <$> mRecovery .:: "throttle_time_in_millis")
4933 <*> mRecovery .:: "current_as_target"
4934 <*> mRecovery .:: "current_as_source"
4935 <*> mQueryCache .:: "miss_count"
4936 <*> mQueryCache .:: "hit_count"
4937 <*> mQueryCache .:: "evictions"
4938 <*> mQueryCache .:: "memory_size_in_bytes"
4939 <*> suggest .: "current"
4940 <*> (unMS <$> suggest .: "time_in_millis")
4941 <*> suggest .: "total"
4942 <*> translog .: "size_in_bytes"
4943 <*> translog .: "operations"
4944 <*> segments .:? "fixed_bit_set_memory_in_bytes"
4945 <*> segments .: "version_map_memory_in_bytes"
4946 <*> segments .:? "index_writer_max_memory_in_bytes"
4947 <*> segments .: "index_writer_memory_in_bytes"
4948 <*> segments .: "memory_in_bytes"
4949 <*> segments .: "count"
4950 <*> completion .: "size_in_bytes"
4951 <*> percolate .: "queries"
4952 <*> percolate .: "memory_size_in_bytes"
4953 <*> percolate .: "current"
4954 <*> (unMS <$> percolate .: "time_in_millis")
4955 <*> percolate .: "total"
4956 <*> fielddata .: "evictions"
4957 <*> fielddata .: "memory_size_in_bytes"
4958 <*> idCache .: "memory_size_in_bytes"
4959 <*> filterCache .: "evictions"
4960 <*> filterCache .: "memory_size_in_bytes"
4961 <*> (unMS <$> warmer .: "total_time_in_millis")
4962 <*> warmer .: "total"
4963 <*> warmer .: "current"
4964 <*> (unMS <$> flush .: "total_time_in_millis")
4965 <*> flush .: "total"
4966 <*> (unMS <$> refresh .: "total_time_in_millis")
4967 <*> refresh .: "total"
4968 <*> merges .: "total_size_in_bytes"
4969 <*> merges .: "total_docs"
4970 <*> (unMS <$> merges .: "total_time_in_millis")
4971 <*> merges .: "total"
4972 <*> merges .: "current_size_in_bytes"
4973 <*> merges .: "current_docs"
4974 <*> merges .: "current"
4975 <*> search .: "fetch_current"
4976 <*> (unMS <$> search .: "fetch_time_in_millis")
4977 <*> search .: "fetch_total"
4978 <*> search .: "query_current"
4979 <*> (unMS <$> search .: "query_time_in_millis")
4980 <*> search .: "query_total"
4981 <*> search .: "open_contexts"
4982 <*> getStats .: "current"
4983 <*> (unMS <$> getStats .: "missing_time_in_millis")
4984 <*> getStats .: "missing_total"
4985 <*> (unMS <$> getStats .: "exists_time_in_millis")
4986 <*> getStats .: "exists_total"
4987 <*> (unMS <$> getStats .: "time_in_millis")
4988 <*> getStats .: "total"
4989 <*> (fmap unMS <$> indexing .:? "throttle_time_in_millis")
4990 <*> indexing .:? "is_throttled"
4991 <*> indexing .:? "noop_update_total"
4992 <*> indexing .: "delete_current"
4993 <*> (unMS <$> indexing .: "delete_time_in_millis")
4994 <*> indexing .: "delete_total"
4995 <*> indexing .: "index_current"
4996 <*> (unMS <$> indexing .: "index_time_in_millis")
4997 <*> indexing .: "index_total"
4998 <*> (unMS <$> store .: "throttle_time_in_millis")
4999 <*> store .: "size_in_bytes"
5000 <*> docs .: "deleted"
5001 <*> docs .: "count"
5003instance FromJSON NodeBreakersStats where
5004 parseJSON = withObject "NodeBreakersStats" parse
5005 where
5006 parse o = NodeBreakersStats <$> o .: "parent"
5007 <*> o .: "request"
5008 <*> o .: "fielddata"
5010parseNodeStats :: FullNodeId -> Object -> Parser NodeStats
5011parseNodeStats fnid o = do
5012 NodeStats <$> o .: "name"
5013 <*> pure fnid
5014 <*> o .:? "breakers"
5015 <*> o .: "http"
5016 <*> o .: "transport"
5017 <*> o .: "fs"
5018 <*> o .: "network"
5019 <*> o .: "thread_pool"
5020 <*> o .: "jvm"
5021 <*> o .: "process"
5022 <*> o .: "os"
5023 <*> o .: "indices"
5025parseNodeInfo :: FullNodeId -> Object -> Parser NodeInfo
5026parseNodeInfo nid o =
5027 NodeInfo <$> o .: "http_address"
5028 <*> o .: "build"
5029 <*> o .: "version"
5030 <*> o .: "ip"
5031 <*> o .: "host"
5032 <*> o .: "transport_address"
5033 <*> o .: "name"
5034 <*> pure nid
5035 <*> o .: "plugins"
5036 <*> o .: "http"
5037 <*> o .: "transport"
5038 <*> o .: "network"
5039 <*> o .: "thread_pool"
5040 <*> o .: "jvm"
5041 <*> o .: "process"
5042 <*> o .: "os"
5043 <*> o .: "settings"
5045instance FromJSON NodePluginInfo where
5046 parseJSON = withObject "NodePluginInfo" parse
5047 where
5048 parse o = NodePluginInfo <$> o .: "site"
5049 <*> o .: "jvm"
5050 <*> o .: "description"
5051 <*> o .: "version"
5052 <*> o .: "name"
5054instance FromJSON NodeHTTPInfo where
5055 parseJSON = withObject "NodeHTTPInfo" parse
5056 where
5057 parse o = NodeHTTPInfo <$> o .: "max_content_length_in_bytes"
5058 <*> parseJSON (Object o)
5060instance FromJSON BoundTransportAddress where
5061 parseJSON = withObject "BoundTransportAddress" parse
5062 where
5063 parse o = BoundTransportAddress <$> o .: "publish_address"
5064 <*> o .: "bound_address"
5066instance FromJSON NodeOSInfo where
5067 parseJSON = withObject "NodeOSInfo" parse
5068 where
5069 parse o = do
5070 swap <- o .: "swap"
5071 mem <- o .: "mem"
5072 NodeOSInfo <$> swap .: "total_in_bytes"
5073 <*> mem .: "total_in_bytes"
5074 <*> o .: "cpu"
5075 <*> o .: "available_processors"
5076 <*> (unMS <$> o .: "refresh_interval_in_millis")
5079instance FromJSON CPUInfo where
5080 parseJSON = withObject "CPUInfo" parse
5081 where
5082 parse o = CPUInfo <$> o .: "cache_size_in_bytes"
5083 <*> o .: "cores_per_socket"
5084 <*> o .: "total_sockets"
5085 <*> o .: "total_cores"
5086 <*> o .: "mhz"
5087 <*> o .: "model"
5088 <*> o .: "vendor"
5090instance FromJSON NodeProcessInfo where
5091 parseJSON = withObject "NodeProcessInfo" parse
5092 where
5093 parse o = NodeProcessInfo <$> o .: "mlockall"
5094 <*> o .: "max_file_descriptors"
5095 <*> o .: "id"
5096 <*> (unMS <$> o .: "refresh_interval_in_millis")
5098instance FromJSON NodeJVMInfo where
5099 parseJSON = withObject "NodeJVMInfo" parse
5100 where
5101 parse o = NodeJVMInfo <$> o .: "memory_pools"
5102 <*> o .: "gc_collectors"
5103 <*> o .: "mem"
5104 <*> (posixMS <$> o .: "start_time_in_millis")
5105 <*> o .: "vm_vendor"
5106 <*> o .: "vm_version"
5107 <*> o .: "vm_name"
5108 <*> (unJVMVersion <$> o .: "version")
5109 <*> o .: "pid"
5111instance FromJSON JVMVersion where
5112 parseJSON (String t) =
5113 JVMVersion <$> parseJSON (String (T.replace "_" "." t))
5114 parseJSON v = JVMVersion <$> parseJSON v
5116instance FromJSON JVMMemoryInfo where
5117 parseJSON = withObject "JVMMemoryInfo" parse
5118 where
5119 parse o = JVMMemoryInfo <$> o .: "direct_max_in_bytes"
5120 <*> o .: "non_heap_max_in_bytes"
5121 <*> o .: "non_heap_init_in_bytes"
5122 <*> o .: "heap_max_in_bytes"
5123 <*> o .: "heap_init_in_bytes"
5125instance FromJSON NodeThreadPoolsInfo where
5126 parseJSON = withObject "NodeThreadPoolsInfo" parse
5127 where
5128 parse o = NodeThreadPoolsInfo <$> o .: "refresh"
5129 <*> o .: "management"
5130 <*> o .: "percolate"
5131 <*> o .:? "listener"
5132 <*> o .:? "fetch_shard_started"
5133 <*> o .: "search"
5134 <*> o .: "flush"
5135 <*> o .: "warmer"
5136 <*> o .: "optimize"
5137 <*> o .: "bulk"
5138 <*> o .: "suggest"
5139 <*> o .: "merge"
5140 <*> o .: "snapshot"
5141 <*> o .: "get"
5142 <*> o .:? "fetch_shard_store"
5143 <*> o .: "index"
5144 <*> o .: "generic"
5146instance FromJSON NodeThreadPoolInfo where
5147 parseJSON = withObject "NodeThreadPoolInfo" parse
5148 where
5149 parse o = do
5150 ka <- maybe (return Nothing) (fmap Just . parseStringInterval) =<< o .:? "keep_alive"
5151 NodeThreadPoolInfo <$> (parseJSON . unStringlyTypeJSON =<< o .: "queue_size")
5152 <*> pure ka
5153 <*> o .:? "min"
5154 <*> o .:? "max"
5155 <*> o .: "type"
5157parseStringInterval :: (Monad m) => String -> m NominalDiffTime
5158parseStringInterval s = case span isNumber s of
5159 ("", _) -> fail "Invalid interval"
5160 (nS, unitS) -> case (readMay nS, readMay unitS) of
5161 (Just n, Just unit) -> return (fromInteger (n * unitNDT unit))
5162 (Nothing, _) -> fail "Invalid interval number"
5163 (_, Nothing) -> fail "Invalid interval unit"
5164 where
5165 unitNDT Seconds = 1
5166 unitNDT Minutes = 60
5167 unitNDT Hours = 60 * 60
5168 unitNDT Days = 24 * 60 * 60
5169 unitNDT Weeks = 7 * 24 * 60 * 60
5171instance FromJSON ThreadPoolSize where
5172 parseJSON v = parseAsNumber v <|> parseAsString v
5173 where
5174 parseAsNumber = parseAsInt <=< parseJSON
5175 parseAsInt (-1) = return ThreadPoolUnbounded
5176 parseAsInt n
5177 | n >= 0 = return (ThreadPoolBounded n)
5178 | otherwise = fail "Thread pool size must be >= -1."
5179 parseAsString = withText "ThreadPoolSize" $ \t ->
5180 case first (readMay . T.unpack) (T.span isNumber t) of
5181 (Just n, "k") -> return (ThreadPoolBounded (n * 1000))
5182 (Just n, "") -> return (ThreadPoolBounded n)
5183 _ -> fail ("Invalid thread pool size " <> T.unpack t)
5185instance FromJSON ThreadPoolType where
5186 parseJSON = withText "ThreadPoolType" parse
5187 where
5188 parse "scaling" = return ThreadPoolScaling
5189 parse "fixed" = return ThreadPoolFixed
5190 parse "cached" = return ThreadPoolCached
5191 parse e = fail ("Unexpected thread pool type" <> T.unpack e)
5193instance FromJSON NodeTransportInfo where
5194 parseJSON = withObject "NodeTransportInfo" parse
5195 where
5196 parse o = NodeTransportInfo <$> (maybe (return mempty) parseProfiles =<< o .:? "profiles")
5197 <*> parseJSON (Object o)
5198 parseProfiles (Object o) | HM.null o = return []
5199 parseProfiles v@(Array _) = parseJSON v
5200 parseProfiles Null = return []
5201 parseProfiles _ = fail "Could not parse profiles"
5203instance FromJSON NodeNetworkInfo where
5204 parseJSON = withObject "NodeNetworkInfo" parse
5205 where
5206 parse o = NodeNetworkInfo <$> o .: "primary_interface"
5207 <*> (unMS <$> o .: "refresh_interval_in_millis")
5210instance FromJSON NodeNetworkInterface where
5211 parseJSON = withObject "NodeNetworkInterface" parse
5212 where
5213 parse o = NodeNetworkInterface <$> o .: "mac_address"
5214 <*> o .: "name"
5215 <*> o .: "address"
5217newtype MaybeNA a = MaybeNA { unMaybeNA :: Maybe a }
5218 deriving (Show, Eq)
5220instance FromJSON a => FromJSON (MaybeNA a) where
5221 parseJSON (String "NA") = pure $ MaybeNA Nothing
5222 parseJSON o = MaybeNA . Just <$> parseJSON o