git.iko.soy/typeable/bloodhound
on 86-sub-aggregation-parsing help sign in
3598 lines 156 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 OverloadedStrings #-}
9{-# LANGUAGE RecordWildCards #-}
10{-# LANGUAGE UndecidableInstances #-}
11{-# LANGUAGE NamedFieldPuns #-}
13-------------------------------------------------------------------------------
14-- |
15-- Module : Database.Bloodhound.Types
16-- Copyright : (C) 2014 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 , mkDocVersion
49 , docVersionNumber
50 , toTerms
51 , toDateHistogram
52 , omitNulls
53 , BH(..)
54 , runBH
55 , BHEnv
56 , bhServer
57 , bhManager
58 , bhRequestHook
59 , mkBHEnv
60 , MonadBH(..)
61 , Version(..)
62 , Status(..)
63 , Existence(..)
64 , NullValue(..)
65 , IndexSettings(..)
66 , UpdatableIndexSetting(..)
67 , IndexSettingsSummary(..)
68 , AllocationPolicy(..)
69 , ReplicaBounds(..)
70 , Bytes(..)
71 , FSType(..)
72 , InitialShardCount(..)
73 , NodeAttrFilter(..)
74 , NodeAttrName(..)
75 , CompoundFormat(..)
76 , IndexTemplate(..)
77 , Server(..)
78 , Reply
79 , EsResult(..)
80 , EsResultFound(..)
81 , EsError(..)
82 , EsProtocolException(..)
83 , IndexAlias(..)
84 , IndexAliasName(..)
85 , IndexAliasAction(..)
86 , IndexAliasCreate(..)
87 , IndexAliasSummary(..)
88 , IndexAliasesSummary(..)
89 , AliasRouting(..)
90 , SearchAliasRouting(..)
91 , IndexAliasRouting(..)
92 , RoutingValue(..)
93 , DocVersion
94 , ExternalDocVersion(..)
95 , VersionControl(..)
96 , DocumentParent(..)
97 , IndexDocumentSettings(..)
98 , Query(..)
99 , Search(..)
100 , SearchType(..)
101 , SearchResult(..)
102 , ScrollId(..)
103 , SearchHits(..)
104 , TrackSortScores
105 , From(..)
106 , Size(..)
107 , Source(..)
108 , PatternOrPatterns(..)
109 , Include(..)
110 , Exclude(..)
111 , Pattern(..)
112 , ShardResult(..)
113 , Hit(..)
114 , Filter(..)
115 , Seminearring(..)
116 , BoolMatch(..)
117 , Term(..)
118 , GeoPoint(..)
119 , GeoBoundingBoxConstraint(..)
120 , GeoBoundingBox(..)
121 , GeoFilterType(..)
122 , Distance(..)
123 , DistanceUnit(..)
124 , DistanceType(..)
125 , DistanceRange(..)
126 , OptimizeBbox(..)
127 , LatLon(..)
128 , RangeValue(..)
129 , RangeExecution(..)
130 , LessThan(..)
131 , LessThanEq(..)
132 , GreaterThan(..)
133 , GreaterThanEq(..)
134 , LessThanD(..)
135 , LessThanEqD(..)
136 , GreaterThanD(..)
137 , GreaterThanEqD(..)
138 , Regexp(..)
139 , RegexpFlags(..)
140 , RegexpFlag(..)
141 , FieldName(..)
142 , Script(..)
143 , IndexName(..)
144 , IndexSelection(..)
145 , IndexOptimizationSettings(..)
146 , defaultIndexOptimizationSettings
147 , TemplateName(..)
148 , TemplatePattern(..)
149 , MappingName(..)
150 , DocId(..)
151 , CacheName(..)
152 , CacheKey(..)
153 , BulkOperation(..)
154 , ReplicaCount(..)
155 , ShardCount(..)
156 , Sort
157 , SortMode(..)
158 , SortOrder(..)
159 , SortSpec(..)
160 , DefaultSort(..)
161 , Missing(..)
162 , OpenCloseIndex(..)
163 , Method
164 , Boost(..)
165 , MatchQuery(..)
166 , MultiMatchQuery(..)
167 , BoolQuery(..)
168 , BoostingQuery(..)
169 , CommonTermsQuery(..)
170 , DisMaxQuery(..)
171 , FilteredQuery(..)
172 , FuzzyLikeThisQuery(..)
173 , FuzzyLikeFieldQuery(..)
174 , FuzzyQuery(..)
175 , HasChildQuery(..)
176 , HasParentQuery(..)
177 , IndicesQuery(..)
178 , MoreLikeThisQuery(..)
179 , MoreLikeThisFieldQuery(..)
180 , NestedQuery(..)
181 , PrefixQuery(..)
182 , QueryStringQuery(..)
183 , SimpleQueryStringQuery(..)
184 , RangeQuery(..)
185 , RegexpQuery(..)
186 , QueryString(..)
187 , BooleanOperator(..)
188 , ZeroTermsQuery(..)
189 , CutoffFrequency(..)
190 , Analyzer(..)
191 , MaxExpansions(..)
192 , Lenient(..)
193 , MatchQueryType(..)
194 , MultiMatchQueryType(..)
195 , Tiebreaker(..)
196 , MinimumMatch(..)
197 , DisableCoord(..)
198 , CommonMinimumMatch(..)
199 , MinimumMatchHighLow(..)
200 , PrefixLength(..)
201 , Fuzziness(..)
202 , IgnoreTermFrequency(..)
203 , MaxQueryTerms(..)
204 , ScoreType(..)
205 , Score
206 , Cache
207 , TypeName(..)
208 , BoostTerms(..)
209 , MaxWordLength(..)
210 , MinWordLength(..)
211 , MaxDocFrequency(..)
212 , MinDocFrequency(..)
213 , PhraseSlop(..)
214 , StopWord(..)
215 , QueryPath(..)
216 , MinimumTermFrequency(..)
217 , PercentMatch(..)
218 , FieldDefinition(..)
219 , MappingField(..)
220 , Mapping(..)
221 , AllowLeadingWildcard(..)
222 , LowercaseExpanded(..)
223 , GeneratePhraseQueries(..)
224 , Locale(..)
225 , AnalyzeWildcard(..)
226 , EnablePositionIncrements(..)
227 , SimpleQueryFlag(..)
228 , FieldOrFields(..)
229 , Monoid(..)
230 , ToJSON(..)
231 , Interval(..)
232 , TimeInterval(..)
233 , ExecutionHint(..)
234 , CollectionMode(..)
235 , TermOrder(..)
236 , TermInclusion(..)
238 , Aggregation(..)
239 , Aggregations
240 , AggregationResults
241 , BucketValue(..)
242 , Bucket(..)
243 , BucketAggregation(..)
244 , TermsAggregation(..)
245 , MissingAggregation(..)
246 , ValueCountAggregation(..)
247 , FilterAggregation(..)
248 , DateHistogramAggregation(..)
249 , DateRangeAggregation(..)
250 , DateRangeAggRange(..)
251 , DateMathExpr(..)
252 , DateMathAnchor(..)
253 , DateMathModifier(..)
254 , DateMathUnit(..)
256 , Highlights(..)
257 , FieldHighlight(..)
258 , HighlightSettings(..)
259 , PlainHighlight(..)
260 , PostingsHighlight(..)
261 , FastVectorHighlight(..)
262 , CommonHighlight(..)
263 , NonPostings(..)
264 , HighlightEncoder(..)
265 , HighlightTag(..)
266 , HitHighlight
268 , TermsResult(..)
269 , DateHistogramResult(..)
270 , DateRangeResult(..)
272 , EsUsername(..)
273 , EsPassword(..)
274 ) where
276import Control.Applicative
277import Control.Monad.Catch
278import Control.Monad.Except
279import Control.Monad.Reader
280import Control.Monad.State
281import Control.Monad.Writer
282import Data.Aeson
283import Data.Aeson.Types (Pair, Parser, emptyObject,
284 parseMaybe)
285import qualified Data.ByteString.Lazy.Char8 as L
286import Data.Char
287import Data.Hashable (Hashable)
288import qualified Data.HashMap.Strict as HM
289import Data.List (foldl', nub)
290import Data.List.NonEmpty (NonEmpty (..), toList)
291import qualified Data.Map.Strict as M
292import Data.Maybe
293import Data.Scientific (Scientific)
294import Data.Text (Text)
295import qualified Data.Text as T
296import Data.Time.Calendar
297import Data.Time.Clock (NominalDiffTime, UTCTime)
298import Data.Time.Clock.POSIX
299import qualified Data.Traversable as DT
300import Data.Typeable (Typeable)
301import qualified Data.Vector as V
302import GHC.Enum
303import GHC.Generics (Generic)
304import Network.HTTP.Client
305import qualified Network.HTTP.Types.Method as NHTM
307import Database.Bloodhound.Types.Class
308import Database.Bloodhound.Types.Internal
310-- $setup
311-- >>> :set -XOverloadedStrings
312-- >>> import Database.Bloodhound
313-- >>> let testServer = (Server "http://localhost:9200")
314-- >>> let testIndex = IndexName "twitter"
315-- >>> let testMapping = MappingName "tweet"
316-- >>> let defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
318-- defaultIndexSettings is exported by Database.Bloodhound as well
319-- no trailing slashes in servers, library handles building the path.
321-- | Create a 'BHEnv' with all optional fields defaulted. HTTP hook
322-- will be a noop. You can use the exported fields to customize it further, e.g.:
323--
324-- >> (mkBHEnv myServer myManager) { bhRequestHook = customHook }
325mkBHEnv :: Server -> Manager -> BHEnv
326mkBHEnv s m = BHEnv s m return
328newtype BH m a = BH {
329 unBH :: ReaderT BHEnv m a
330 } deriving ( Functor
331 , Applicative
332 , Monad
333 , MonadIO
334 , MonadState s
335 , MonadWriter w
336 , MonadError e
337 , Alternative
338 , MonadPlus
339 , MonadFix
340 , MonadThrow
341 , MonadCatch
342 , MonadMask)
344instance MonadTrans BH where
345 lift = BH . lift
347instance (MonadReader r m) => MonadReader r (BH m) where
348 ask = lift ask
349 local f (BH (ReaderT m)) = BH $ ReaderT $ \r ->
350 local f (m r)
352instance (Functor m, Applicative m, MonadIO m) => MonadBH (BH m) where
353 getBHEnv = BH getBHEnv
355runBH :: BHEnv -> BH m a -> m a
356runBH e f = runReaderT (unBH f) e
358{-| 'Version' is embedded in 'Status' -}
359data Version = Version { number :: Text
360 , build_hash :: Text
361 , build_timestamp :: UTCTime
362 , build_snapshot :: Bool
363 , lucene_version :: Text } deriving (Eq, Show, Generic, Typeable)
365{-| 'Status' is a data type for describing the JSON body returned by
366 Elasticsearch when you query its status. This was deprecated in 1.2.0.
368 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-status.html#indices-status>
369-}
371data Status = Status { ok :: Maybe Bool
372 , status :: Int
373 , name :: Text
374 , version :: Version
375 , tagline :: Text } deriving (Eq, Show, Generic)
377{-| 'IndexSettings' is used to configure the shards and replicas when you create
378 an Elasticsearch Index.
380 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html>
381-}
383data IndexSettings =
384 IndexSettings { indexShards :: ShardCount
385 , indexReplicas :: ReplicaCount } deriving (Eq, Show, Generic, Typeable)
387{-| 'defaultIndexSettings' is an 'IndexSettings' with 3 shards and 2 replicas. -}
388defaultIndexSettings :: IndexSettings
389defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
392{-| 'IndexOptimizationSettings' is used to configure index optimization. See
393 <https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-optimize.html>
394 for more info.
395-}
396data IndexOptimizationSettings =
397 IndexOptimizationSettings { maxNumSegments :: Maybe Int
398 -- ^ 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.
399 , onlyExpungeDeletes :: Bool
400 -- ^ 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.
401 , flushAfterOptimize :: Bool
402 -- ^ Should a flush be performed after the optimize.
403 } deriving (Eq, Show, Generic, Typeable)
406{-| 'defaultIndexOptimizationSettings' implements the default settings that
407 ElasticSearch uses for index optimization. 'maxNumSegments' is Nothing,
408 'onlyExpungeDeletes' is False, and flushAfterOptimize is True.
409-}
410defaultIndexOptimizationSettings :: IndexOptimizationSettings
411defaultIndexOptimizationSettings = IndexOptimizationSettings Nothing False True
413{-| 'UpdatableIndexSetting' are settings which may be updated after an index is created.
415 <https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html>
416-}
417data UpdatableIndexSetting = NumberOfReplicas ReplicaCount
418 -- ^ The number of replicas each shard has.
419 | AutoExpandReplicas ReplicaBounds
420 | BlocksReadOnly Bool
421 -- ^ Set to True to have the index read only. False to allow writes and metadata changes.
422 | BlocksRead Bool
423 -- ^ Set to True to disable read operations against the index.
424 | BlocksWrite Bool
425 -- ^ Set to True to disable write operations against the index.
426 | BlocksMetaData Bool
427 -- ^ Set to True to disable metadata operations against the index.
428 | RefreshInterval NominalDiffTime
429 -- ^ The async refresh interval of a shard
430 | IndexConcurrency Int
431 | FailOnMergeFailure Bool
432 | TranslogFlushThresholdOps Int
433 -- ^ When to flush on operations.
434 | TranslogFlushThresholdSize Bytes
435 -- ^ When to flush based on translog (bytes) size.
436 | TranslogFlushThresholdPeriod NominalDiffTime
437 -- ^ When to flush based on a period of not flushing.
438 | TranslogDisableFlush Bool
439 -- ^ Disables flushing. Note, should be set for a short interval and then enabled.
440 | CacheFilterMaxSize (Maybe Bytes)
441 -- ^ The maximum size of filter cache (per segment in shard).
442 | CacheFilterExpire (Maybe NominalDiffTime)
443 -- ^ The expire after access time for filter cache.
444 | GatewaySnapshotInterval NominalDiffTime
445 -- ^ The gateway snapshot interval (only applies to shared gateways).
446 | RoutingAllocationInclude (NonEmpty NodeAttrFilter)
447 -- ^ A node matching any rule will be allowed to host shards from the index.
448 | RoutingAllocationExclude (NonEmpty NodeAttrFilter)
449 -- ^ A node matching any rule will NOT be allowed to host shards from the index.
450 | RoutingAllocationRequire (NonEmpty NodeAttrFilter)
451 -- ^ Only nodes matching all rules will be allowed to host shards from the index.
452 | RoutingAllocationEnable AllocationPolicy
453 -- ^ Enables shard allocation for a specific index.
454 | RoutingAllocationShardsPerNode ShardCount
455 -- ^ Controls the total number of shards (replicas and primaries) allowed to be allocated on a single node.
456 | RecoveryInitialShards InitialShardCount
457 -- ^ When using local gateway a particular shard is recovered only if there can be allocated quorum shards in the cluster.
458 | GCDeletes NominalDiffTime
459 | TTLDisablePurge Bool
460 -- ^ Disables temporarily the purge of expired docs.
461 | TranslogFSType FSType
462 | IndexCompoundFormat CompoundFormat
463 | IndexCompoundOnFlush Bool
464 | WarmerEnabled Bool
465 deriving (Eq, Show, Generic, Typeable)
467data AllocationPolicy = AllocAll
468 -- ^ Allows shard allocation for all shards.
469 | AllocPrimaries
470 -- ^ Allows shard allocation only for primary shards.
471 | AllocNewPrimaries
472 -- ^ Allows shard allocation only for primary shards for new indices.
473 | AllocNone
474 -- ^ No shard allocation is allowed
475 deriving (Eq, Show, Generic, Typeable)
477data ReplicaBounds = ReplicasBounded Int Int
478 | ReplicasLowerBounded Int
479 | ReplicasUnbounded
480 deriving (Eq, Show, Generic, Typeable)
482newtype Bytes = Bytes Int deriving (Eq, Show, Generic, Typeable, Ord, ToJSON, FromJSON)
484data FSType = FSSimple
485 | FSBuffered deriving (Eq, Show, Generic, Typeable, Ord)
487data InitialShardCount = QuorumShards
488 | QuorumMinus1Shards
489 | FullShards
490 | FullMinus1Shards
491 | ExplicitShards Int
492 deriving (Eq, Show, Generic, Typeable)
494data NodeAttrFilter = NodeAttrFilter { nodeAttrFilterName :: NodeAttrName
495 , nodeAttrFilterValues :: NonEmpty Text}
496 deriving (Eq, Show, Generic, Ord)
498newtype NodeAttrName = NodeAttrName Text deriving (Eq, Show, Ord, Generic, Typeable)
500data CompoundFormat = CompoundFileFormat Bool
501 | MergeSegmentVsTotalIndex Double
502 -- ^ percentage between 0 and 1 where 0 is false, 1 is true
503 deriving (Eq, Show, Generic, Typeable)
505newtype NominalDiffTimeJSON = NominalDiffTimeJSON { ndtJSON :: NominalDiffTime }
507data IndexSettingsSummary = IndexSettingsSummary { sSummaryIndexName :: IndexName
508 , sSummaryFixedSettings :: IndexSettings
509 , sSummaryUpdateable :: [UpdatableIndexSetting]}
510 deriving (Eq, Show, Generic, Typeable)
512{-| 'Reply' and 'Method' are type synonyms from 'Network.HTTP.Types.Method.Method' -}
513type Reply = Network.HTTP.Client.Response L.ByteString
514type Method = NHTM.Method
516{-| 'OpenCloseIndex' is a sum type for opening and closing indices.
518 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-open-close.html>
519-}
520data OpenCloseIndex = OpenIndex | CloseIndex deriving (Eq, Show, Generic, Typeable)
522data FieldType = GeoPointType
523 | GeoShapeType
524 | FloatType
525 | IntegerType
526 | LongType
527 | ShortType
528 | ByteType deriving (Eq, Show, Generic, Typeable)
530data FieldDefinition =
531 FieldDefinition { fieldType :: FieldType } deriving (Eq, Show, Generic, Typeable)
533{-| An 'IndexTemplate' defines a template that will automatically be
534 applied to new indices created. The templates include both
535 'IndexSettings' and mappings, and a simple 'TemplatePattern' that
536 controls if the template will be applied to the index created.
537 Specify mappings as follows: @[toJSON TweetMapping, ...]@
539 https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-templates.html
540-}
541data IndexTemplate =
542 IndexTemplate { templatePattern :: TemplatePattern
543 , templateSettings :: Maybe IndexSettings
544 , templateMappings :: [Value]
545 }
547data MappingField =
548 MappingField { mappingFieldName :: FieldName
549 , fieldDefinition :: FieldDefinition } deriving (Eq, Show, Generic, Typeable)
551{-| Support for type reification of 'Mapping's is currently incomplete, for
552 now the mapping API verbiage expects a 'ToJSON'able blob.
554 Indexes have mappings, mappings are schemas for the documents contained in the
555 index. I'd recommend having only one mapping per index, always having a mapping,
556 and keeping different kinds of documents separated if possible.
557-}
558data Mapping = Mapping { typeName :: TypeName
559 , mappingFields :: [MappingField] } deriving (Eq, Show, Generic, Typeable)
561{-| 'BulkOperation' is a sum type for expressing the four kinds of bulk
562 operation index, create, delete, and update. 'BulkIndex' behaves like an
563 "upsert", 'BulkCreate' will fail if a document already exists at the DocId.
565 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-bulk.html#docs-bulk>
566-}
567data BulkOperation =
568 BulkIndex IndexName MappingName DocId Value
569 | BulkCreate IndexName MappingName DocId Value
570 | BulkDelete IndexName MappingName DocId
571 | BulkUpdate IndexName MappingName DocId Value deriving (Eq, Show, Generic, Typeable)
573{-| 'EsResult' describes the standard wrapper JSON document that you see in
574 successful Elasticsearch lookups or lookups that couldn't find the document.
575-}
576data EsResult a = EsResult { _index :: Text
577 , _type :: Text
578 , _id :: Text
579 , foundResult :: Maybe (EsResultFound a)} deriving (Eq, Show, Generic, Typeable)
581{-| 'EsResultFound' contains the document and its metadata inside of an
582 'EsResult' when the document was successfully found.
583-}
584data EsResultFound a = EsResultFound { _version :: DocVersion
585 , _source :: a } deriving (Eq, Show, Generic, Typeable)
587{-| 'EsError' is the generic type that will be returned when there was a
588 problem. If you can't parse the expected response, its a good idea to
589 try parsing this.
590-}
591data EsError = EsError { errorStatus :: Int
592 , errorMessage :: Text } deriving (Eq, Show, Generic, Typeable)
594{-| 'EsProtocolException' will be thrown if Bloodhound cannot parse a response
595returned by the ElasticSearch server. If you encounter this error, please
596verify that your domain data types and FromJSON instances are working properly
597(for example, the 'a' of '[Hit a]' in 'SearchResult.searchHits.hits'). If you're
598sure that your mappings are correct, then this error may be an indication of an
599incompatibility between Bloodhound and ElasticSearch. Please open a bug report
600and be sure to include the exception body.
601-}
602data EsProtocolException = EsProtocolException { esProtoExBody :: L.ByteString }
603 deriving (Eq, Show, Generic, Typeable)
605instance Exception EsProtocolException
607data IndexAlias = IndexAlias { srcIndex :: IndexName
608 , indexAlias :: IndexAliasName } deriving (Eq, Show, Generic, Typeable)
610newtype IndexAliasName = IndexAliasName { indexAliasName :: IndexName } deriving (Eq, Show, Generic, ToJSON)
612data IndexAliasAction = AddAlias IndexAlias IndexAliasCreate
613 | RemoveAlias IndexAlias deriving (Show, Eq, Generic, Typeable)
615data IndexAliasCreate = IndexAliasCreate { aliasCreateRouting :: Maybe AliasRouting
616 , aliasCreateFilter :: Maybe Filter}
617 deriving (Show, Eq, Generic, Typeable)
619data AliasRouting = AllAliasRouting RoutingValue
620 | GranularAliasRouting (Maybe SearchAliasRouting) (Maybe IndexAliasRouting)
621 deriving (Show, Eq, Generic, Typeable)
623newtype SearchAliasRouting = SearchAliasRouting (NonEmpty RoutingValue) deriving (Show, Eq, Generic, Typeable)
625newtype IndexAliasRouting = IndexAliasRouting RoutingValue deriving (Show, Eq, Generic, ToJSON, FromJSON, Typeable)
627newtype RoutingValue = RoutingValue { routingValue :: Text } deriving (Show, Eq, Generic, ToJSON, FromJSON, Typeable)
629newtype IndexAliasesSummary = IndexAliasesSummary { indexAliasesSummary :: [IndexAliasSummary] } deriving (Show, Eq, Generic, Typeable)
631{-| 'IndexAliasSummary' is a summary of an index alias configured for a server. -}
632data IndexAliasSummary = IndexAliasSummary { indexAliasSummaryAlias :: IndexAlias
633 , indexAliasSummaryCreate :: IndexAliasCreate} deriving (Show, Eq, Generic, Typeable)
635{-| 'DocVersion' is an integer version number for a document between 1
636and 9.2e+18 used for <<https://www.elastic.co/guide/en/elasticsearch/guide/current/optimistic-concurrency-control.html optimistic concurrency control>>.
637-}
638newtype DocVersion = DocVersion {
639 docVersionNumber :: Int
640 } deriving (Eq, Show, Generic, Ord, ToJSON)
642-- | Smart constructor for in-range doc version
643mkDocVersion :: Int -> Maybe DocVersion
644mkDocVersion i
645 | i >= (docVersionNumber minBound) && i <= (docVersionNumber maxBound) =
646 Just $ DocVersion i
647 | otherwise = Nothing
650{-| 'ExternalDocVersion' is a convenience wrapper if your code uses its
651own version numbers instead of ones from ES.
652-}
653newtype ExternalDocVersion = ExternalDocVersion DocVersion
654 deriving (Eq, Show, Generic, Ord, Bounded, Enum, ToJSON)
656{-| 'VersionControl' is specified when indexing documents as a
657optimistic concurrency control.
658-}
659data VersionControl = NoVersionControl
660 -- ^ Don't send a version. This is a pure overwrite.
661 | InternalVersion DocVersion
662 -- ^ Use the default ES versioning scheme. Only
663 -- index the document if the version is the same
664 -- as the one specified. Only applicable to
665 -- updates, as you should be getting Version from
666 -- a search result.
667 | ExternalGT ExternalDocVersion
668 -- ^ Use your own version numbering. Only index
669 -- the document if the version is strictly higher
670 -- OR the document doesn't exist. The given
671 -- version will be used as the new version number
672 -- for the stored document. N.B. All updates must
673 -- increment this number, meaning there is some
674 -- global, external ordering of updates.
675 | ExternalGTE ExternalDocVersion
676 -- ^ Use your own version numbering. Only index
677 -- the document if the version is equal or higher
678 -- than the stored version. Will succeed if there
679 -- is no existing document. The given version will
680 -- be used as the new version number for the
681 -- stored document. Use with care, as this could
682 -- result in data loss.
683 | ForceVersion ExternalDocVersion
684 -- ^ The document will always be indexed and the
685 -- given version will be the new version. This is
686 -- typically used for correcting errors. Use with
687 -- care, as this could result in data loss.
688 deriving (Show, Eq, Generic, Ord)
690{-| 'DocumentParent' is used to specify a parent document.
691-}
692newtype DocumentParent = DocumentParent DocId
693 deriving (Eq, Show, Generic, Typeable)
695{-| 'IndexDocumentSettings' are special settings supplied when indexing
696a document. For the best backwards compatiblity when new fields are
697added, you should probably prefer to start with 'defaultIndexDocumentSettings'
698-}
699data IndexDocumentSettings =
700 IndexDocumentSettings { idsVersionControl :: VersionControl
701 , idsParent :: Maybe DocumentParent
702 } deriving (Eq, Show, Generic, Typeable)
704{-| Reasonable default settings. Chooses no version control and no parent.
705-}
706defaultIndexDocumentSettings :: IndexDocumentSettings
707defaultIndexDocumentSettings = IndexDocumentSettings NoVersionControl Nothing
709{-| 'Sort' is a synonym for a list of 'SortSpec's. Sort behavior is order
710 dependent with later sorts acting as tie-breakers for earlier sorts.
711-}
712type Sort = [SortSpec]
714{-| The two main kinds of 'SortSpec' are 'DefaultSortSpec' and
715 'GeoDistanceSortSpec'. The latter takes a 'SortOrder', 'GeoPoint', and
716 'DistanceUnit' to express "nearness" to a single geographical point as a
717 sort specification.
719<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
720-}
721data SortSpec = DefaultSortSpec DefaultSort
722 | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit deriving (Eq, Show, Generic, Typeable)
724{-| 'DefaultSort' is usually the kind of 'SortSpec' you'll want. There's a
725 'mkSort' convenience function for when you want to specify only the most
726 common parameters.
728<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
729-}
730data DefaultSort =
731 DefaultSort { sortFieldName :: FieldName
732 , sortOrder :: SortOrder
733 -- default False
734 , ignoreUnmapped :: Bool
735 , sortMode :: Maybe SortMode
736 , missingSort :: Maybe Missing
737 , nestedFilter :: Maybe Filter } deriving (Eq, Show, Generic, Typeable)
739{-| 'SortOrder' is 'Ascending' or 'Descending', as you might expect. These get
740 encoded into "asc" or "desc" when turned into JSON.
742<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
743-}
744data SortOrder = Ascending
745 | Descending deriving (Eq, Show, Generic, Typeable)
747{-| 'Missing' prescribes how to handle missing fields. A missing field can be
748 sorted last, first, or using a custom value as a substitute.
750<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_missing_values>
751-}
752data Missing = LastMissing
753 | FirstMissing
754 | CustomMissing Text deriving (Eq, Show, Generic, Typeable)
756{-| 'SortMode' prescribes how to handle sorting array/multi-valued fields.
758http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_sort_mode_option
759-}
760data SortMode = SortMin
761 | SortMax
762 | SortSum
763 | SortAvg deriving (Eq, Show, Generic, Typeable)
765{-| 'mkSort' defaults everything but the 'FieldName' and the 'SortOrder' so
766 that you can concisely describe the usual kind of 'SortSpec's you want.
767-}
768mkSort :: FieldName -> SortOrder -> DefaultSort
769mkSort fieldName sOrder = DefaultSort fieldName sOrder False Nothing Nothing Nothing
771{-| 'Cache' is for telling ES whether it should cache a 'Filter' not.
772 'Query's cannot be cached.
773-}
774type Cache = Bool -- caching on/off
775defaultCache :: Cache
776defaultCache = False
778{-| 'PrefixValue' is used in 'PrefixQuery' as the main query component.
779-}
780type PrefixValue = Text
782{-| 'BooleanOperator' is the usual And/Or operators with an ES compatible
783 JSON encoding baked in. Used all over the place.
784-}
785data BooleanOperator = And | Or deriving (Eq, Show, Generic, Typeable)
787{-| 'ShardCount' is part of 'IndexSettings'
788-}
789newtype ShardCount = ShardCount Int deriving (Eq, Show, Generic, ToJSON, Typeable)
791{-| 'ReplicaCount' is part of 'IndexSettings'
792-}
793newtype ReplicaCount = ReplicaCount Int deriving (Eq, Show, Generic, ToJSON, Typeable)
795{-| 'IndexName' is used to describe which index to query/create/delete
796-}
797newtype IndexName = IndexName Text deriving (Eq, Generic, Show, ToJSON, FromJSON, Typeable)
799{-| 'IndexSelection' is used for APIs which take a single index, a list of
800 indexes, or the special @_all@ index.
801-}
802data IndexSelection = IndexList (NonEmpty IndexName)
803 | AllIndexes deriving (Eq, Generic, Show, Typeable)
805{-| 'TemplateName' is used to describe which template to query/create/delete
806-}
807newtype TemplateName = TemplateName Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
809{-| 'TemplatePattern' represents a pattern which is matched against index names
810-}
811newtype TemplatePattern = TemplatePattern Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
813{-| 'MappingName' is part of mappings which are how ES describes and schematizes
814 the data in the indices.
815-}
816newtype MappingName = MappingName Text deriving (Eq, Generic, Show, ToJSON, FromJSON, Typeable)
818{-| 'DocId' is a generic wrapper value for expressing unique Document IDs.
819 Can be set by the user or created by ES itself. Often used in client
820 functions for poking at specific documents.
821-}
822newtype DocId = DocId Text deriving (Eq, Generic, Show, ToJSON, FromJSON, Typeable)
824{-| 'QueryString' is used to wrap query text bodies, be they human written or not.
825-}
826newtype QueryString = QueryString Text deriving (Eq, Generic, Show, ToJSON, FromJSON, Typeable)
828{-| 'FieldName' is used all over the place wherever a specific field within
829 a document needs to be specified, usually in 'Query's or 'Filter's.
830-}
831newtype FieldName = FieldName Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
834{-| 'Script' is often used in place of 'FieldName' to specify more
835complex ways of extracting a value from a document.
836-}
837newtype Script = Script { scriptText :: Text } deriving (Eq, Show, Generic, Typeable)
839{-| 'CacheName' is used in 'RegexpFilter' for describing the
840 'CacheKey' keyed caching behavior.
841-}
842newtype CacheName = CacheName Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
844{-| 'CacheKey' is used in 'RegexpFilter' to key regex caching.
845-}
846newtype CacheKey =
847 CacheKey Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
848newtype Existence =
849 Existence Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
850newtype NullValue =
851 NullValue Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
852newtype CutoffFrequency =
853 CutoffFrequency Double deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
854newtype Analyzer =
855 Analyzer Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
856newtype MaxExpansions =
857 MaxExpansions Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
859{-| 'Lenient', if set to true, will cause format based failures to be
860 ignored. I don't know what the bloody default is, Elasticsearch
861 documentation didn't say what it was. Let me know if you figure it out.
862-}
863newtype Lenient =
864 Lenient Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
865newtype Tiebreaker =
866 Tiebreaker Double deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
867newtype Boost =
868 Boost Double deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
869newtype BoostTerms =
870 BoostTerms Double deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
872{-| 'MinimumMatch' controls how many should clauses in the bool query should
873 match. Can be an absolute value (2) or a percentage (30%) or a
874 combination of both.
875-}
876newtype MinimumMatch =
877 MinimumMatch Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
878newtype DisableCoord =
879 DisableCoord Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
880newtype IgnoreTermFrequency =
881 IgnoreTermFrequency Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
882newtype MinimumTermFrequency =
883 MinimumTermFrequency Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
884newtype MaxQueryTerms =
885 MaxQueryTerms Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
886newtype Fuzziness =
887 Fuzziness Double deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
889{-| 'PrefixLength' is the prefix length used in queries, defaults to 0. -}
890newtype PrefixLength =
891 PrefixLength Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
892newtype TypeName =
893 TypeName Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
894newtype PercentMatch =
895 PercentMatch Double deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
896newtype StopWord =
897 StopWord Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
898newtype QueryPath =
899 QueryPath Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
901{-| Allowing a wildcard at the beginning of a word (eg "*ing") is particularly
902 heavy, because all terms in the index need to be examined, just in case
903 they match. Leading wildcards can be disabled by setting
904 'AllowLeadingWildcard' to false. -}
905newtype AllowLeadingWildcard =
906 AllowLeadingWildcard Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
907newtype LowercaseExpanded =
908 LowercaseExpanded Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
909newtype EnablePositionIncrements =
910 EnablePositionIncrements Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
912{-| By default, wildcard terms in a query are not analyzed.
913 Setting 'AnalyzeWildcard' to true enables best-effort analysis.
914-}
915newtype AnalyzeWildcard = AnalyzeWildcard Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
917{-| 'GeneratePhraseQueries' defaults to false.
918-}
919newtype GeneratePhraseQueries =
920 GeneratePhraseQueries Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
922{-| 'Locale' is used for string conversions - defaults to ROOT.
923-}
924newtype Locale = Locale Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
925newtype MaxWordLength = MaxWordLength Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
926newtype MinWordLength = MinWordLength Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
928{-| 'PhraseSlop' sets the default slop for phrases, 0 means exact
929 phrase matches. Default is 0.
930-}
931newtype PhraseSlop = PhraseSlop Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
932newtype MinDocFrequency = MinDocFrequency Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
933newtype MaxDocFrequency = MaxDocFrequency Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
935-- | Newtype wrapper to parse ES's concerning tendency to in some APIs return a floating point number of milliseconds since epoch ಠ_ಠ
936newtype POSIXMS = POSIXMS { posixMS :: UTCTime }
938{-| 'unpackId' is a silly convenience function that gets used once.
939-}
940unpackId :: DocId -> Text
941unpackId (DocId docId) = docId
943type TrackSortScores = Bool
944newtype From = From Int deriving (Eq, Show, Generic, ToJSON)
945newtype Size = Size Int deriving (Eq, Show, Generic, ToJSON)
947data Search = Search { queryBody :: Maybe Query
948 , filterBody :: Maybe Filter
949 , sortBody :: Maybe Sort
950 , aggBody :: Maybe Aggregations
951 , highlight :: Maybe Highlights
952 -- default False
953 , trackSortScores :: TrackSortScores
954 , from :: From
955 , size :: Size
956 , searchType :: SearchType
957 , fields :: Maybe [FieldName]
958 , source :: Maybe Source } deriving (Eq, Show, Generic, Typeable)
960data SearchType = SearchTypeQueryThenFetch
961 | SearchTypeDfsQueryThenFetch
962 | SearchTypeCount
963 | SearchTypeScan
964 | SearchTypeQueryAndFetch
965 | SearchTypeDfsQueryAndFetch
966 deriving (Eq, Show, Generic, Typeable)
968data Source =
969 NoSource
970 | SourcePatterns PatternOrPatterns
971 | SourceIncludeExclude Include Exclude
972 deriving (Show, Eq, Generic, Typeable)
974data PatternOrPatterns = PopPattern Pattern
975 | PopPatterns [Pattern] deriving (Eq, Show, Generic, Typeable)
977data Include = Include [Pattern] deriving (Eq, Show, Generic, Typeable)
978data Exclude = Exclude [Pattern] deriving (Eq, Show, Generic, Typeable)
980newtype Pattern = Pattern Text deriving (Eq, Show, Generic, Typeable)
982data Highlights = Highlights { globalsettings :: Maybe HighlightSettings
983 , highlightFields :: [FieldHighlight]
984 } deriving (Show, Eq, Generic, Typeable)
986data FieldHighlight = FieldHighlight FieldName (Maybe HighlightSettings)
987 deriving (Show, Eq, Generic, Typeable)
990data HighlightSettings = Plain PlainHighlight
991 | Postings PostingsHighlight
992 | FastVector FastVectorHighlight
993 deriving (Show, Eq, Generic, Typeable)
994data PlainHighlight =
995 PlainHighlight { plainCommon :: Maybe CommonHighlight
996 , plainNonPost :: Maybe NonPostings } deriving (Show, Eq, Generic, Typeable)
998 -- This requires that index_options are set to 'offset' in the mapping.
999data PostingsHighlight = PostingsHighlight (Maybe CommonHighlight) deriving (Show, Eq, Generic, Typeable)
1001-- This requires that term_vector is set to 'with_positions_offsets' in the mapping.
1002data FastVectorHighlight =
1003 FastVectorHighlight { fvCommon :: Maybe CommonHighlight
1004 , fvNonPostSettings :: Maybe NonPostings
1005 , boundaryChars :: Maybe Text
1006 , boundaryMaxScan :: Maybe Int
1007 , fragmentOffset :: Maybe Int
1008 , matchedFields :: [Text]
1009 , phraseLimit :: Maybe Int
1010 } deriving (Show, Eq, Generic, Typeable)
1012data CommonHighlight =
1013 CommonHighlight { order :: Maybe Text
1014 , forceSource :: Maybe Bool
1015 , tag :: Maybe HighlightTag
1016 , encoder :: Maybe HighlightEncoder
1017 , noMatchSize :: Maybe Int
1018 , highlightQuery :: Maybe Query
1019 , requireFieldMatch :: Maybe Bool
1020 } deriving (Show, Eq, Generic, Typeable)
1022-- Settings that are only applicable to FastVector and Plain highlighters.
1023data NonPostings =
1024 NonPostings { fragmentSize :: Maybe Int
1025 , numberOfFragments :: Maybe Int} deriving (Show, Eq, Generic, Typeable)
1027data HighlightEncoder = DefaultEncoder
1028 | HTMLEncoder
1029 deriving (Show, Eq, Generic, Typeable)
1031-- NOTE: Should the tags use some kind of HTML type, rather than Text?
1032data HighlightTag = TagSchema Text
1033 | CustomTags ([Text], [Text]) -- Only uses more than the first value in the lists if fvh
1034 deriving (Show, Eq, Generic, Typeable)
1037data Query =
1038 TermQuery Term (Maybe Boost)
1039 | TermsQuery Text (NonEmpty Text)
1040 | QueryMatchQuery MatchQuery
1041 | QueryMultiMatchQuery MultiMatchQuery
1042 | QueryBoolQuery BoolQuery
1043 | QueryBoostingQuery BoostingQuery
1044 | QueryCommonTermsQuery CommonTermsQuery
1045 | ConstantScoreFilter Filter Boost
1046 | ConstantScoreQuery Query Boost
1047 | QueryDisMaxQuery DisMaxQuery
1048 | QueryFilteredQuery FilteredQuery
1049 | QueryFuzzyLikeThisQuery FuzzyLikeThisQuery
1050 | QueryFuzzyLikeFieldQuery FuzzyLikeFieldQuery
1051 | QueryFuzzyQuery FuzzyQuery
1052 | QueryHasChildQuery HasChildQuery
1053 | QueryHasParentQuery HasParentQuery
1054 | IdsQuery MappingName [DocId]
1055 | QueryIndicesQuery IndicesQuery
1056 | MatchAllQuery (Maybe Boost)
1057 | QueryMoreLikeThisQuery MoreLikeThisQuery
1058 | QueryMoreLikeThisFieldQuery MoreLikeThisFieldQuery
1059 | QueryNestedQuery NestedQuery
1060 | QueryPrefixQuery PrefixQuery
1061 | QueryQueryStringQuery QueryStringQuery
1062 | QuerySimpleQueryStringQuery SimpleQueryStringQuery
1063 | QueryRangeQuery RangeQuery
1064 | QueryRegexpQuery RegexpQuery
1065 deriving (Eq, Show, Generic, Typeable)
1067data RegexpQuery =
1068 RegexpQuery { regexpQueryField :: FieldName
1069 , regexpQuery :: Regexp
1070 , regexpQueryFlags :: RegexpFlags
1071 , regexpQueryBoost :: Maybe Boost
1072 } deriving (Eq, Show, Generic, Typeable)
1074data RangeQuery =
1075 RangeQuery { rangeQueryField :: FieldName
1076 , rangeQueryRange :: RangeValue
1077 , rangeQueryBoost :: Boost } deriving (Eq, Show, Generic, Typeable)
1079mkRangeQuery :: FieldName -> RangeValue -> RangeQuery
1080mkRangeQuery f r = RangeQuery f r (Boost 1.0)
1082data SimpleQueryStringQuery =
1083 SimpleQueryStringQuery
1084 { simpleQueryStringQuery :: QueryString
1085 , simpleQueryStringField :: Maybe FieldOrFields
1086 , simpleQueryStringOperator :: Maybe BooleanOperator
1087 , simpleQueryStringAnalyzer :: Maybe Analyzer
1088 , simpleQueryStringFlags :: Maybe (NonEmpty SimpleQueryFlag)
1089 , simpleQueryStringLowercaseExpanded :: Maybe LowercaseExpanded
1090 , simpleQueryStringLocale :: Maybe Locale
1091 } deriving (Eq, Show, Generic, Typeable)
1093data SimpleQueryFlag =
1094 SimpleQueryAll
1095 | SimpleQueryNone
1096 | SimpleQueryAnd
1097 | SimpleQueryOr
1098 | SimpleQueryPrefix
1099 | SimpleQueryPhrase
1100 | SimpleQueryPrecedence
1101 | SimpleQueryEscape
1102 | SimpleQueryWhitespace
1103 | SimpleQueryFuzzy
1104 | SimpleQueryNear
1105 | SimpleQuerySlop deriving (Eq, Show, Generic, Typeable)
1107-- use_dis_max and tie_breaker when fields are plural?
1108data QueryStringQuery =
1109 QueryStringQuery
1110 { queryStringQuery :: QueryString
1111 , queryStringDefaultField :: Maybe FieldName
1112 , queryStringOperator :: Maybe BooleanOperator
1113 , queryStringAnalyzer :: Maybe Analyzer
1114 , queryStringAllowLeadingWildcard :: Maybe AllowLeadingWildcard
1115 , queryStringLowercaseExpanded :: Maybe LowercaseExpanded
1116 , queryStringEnablePositionIncrements :: Maybe EnablePositionIncrements
1117 , queryStringFuzzyMaxExpansions :: Maybe MaxExpansions
1118 , queryStringFuzziness :: Maybe Fuzziness
1119 , queryStringFuzzyPrefixLength :: Maybe PrefixLength
1120 , queryStringPhraseSlop :: Maybe PhraseSlop
1121 , queryStringBoost :: Maybe Boost
1122 , queryStringAnalyzeWildcard :: Maybe AnalyzeWildcard
1123 , queryStringGeneratePhraseQueries :: Maybe GeneratePhraseQueries
1124 , queryStringMinimumShouldMatch :: Maybe MinimumMatch
1125 , queryStringLenient :: Maybe Lenient
1126 , queryStringLocale :: Maybe Locale
1127 } deriving (Eq, Show, Generic, Typeable)
1129mkQueryStringQuery :: QueryString -> QueryStringQuery
1130mkQueryStringQuery qs =
1131 QueryStringQuery qs Nothing Nothing
1132 Nothing Nothing Nothing Nothing
1133 Nothing Nothing Nothing Nothing
1134 Nothing Nothing Nothing Nothing
1135 Nothing Nothing
1137data FieldOrFields = FofField FieldName
1138 | FofFields (NonEmpty FieldName) deriving (Eq, Show, Generic, Typeable)
1140data PrefixQuery =
1141 PrefixQuery
1142 { prefixQueryField :: FieldName
1143 , prefixQueryPrefixValue :: Text
1144 , prefixQueryBoost :: Maybe Boost } deriving (Eq, Show, Generic, Typeable)
1146data NestedQuery =
1147 NestedQuery
1148 { nestedQueryPath :: QueryPath
1149 , nestedQueryScoreType :: ScoreType
1150 , nestedQuery :: Query } deriving (Eq, Show, Generic, Typeable)
1152data MoreLikeThisFieldQuery =
1153 MoreLikeThisFieldQuery
1154 { moreLikeThisFieldText :: Text
1155 , moreLikeThisFieldFields :: FieldName
1156 -- default 0.3 (30%)
1157 , moreLikeThisFieldPercentMatch :: Maybe PercentMatch
1158 , moreLikeThisFieldMinimumTermFreq :: Maybe MinimumTermFrequency
1159 , moreLikeThisFieldMaxQueryTerms :: Maybe MaxQueryTerms
1160 , moreLikeThisFieldStopWords :: Maybe (NonEmpty StopWord)
1161 , moreLikeThisFieldMinDocFrequency :: Maybe MinDocFrequency
1162 , moreLikeThisFieldMaxDocFrequency :: Maybe MaxDocFrequency
1163 , moreLikeThisFieldMinWordLength :: Maybe MinWordLength
1164 , moreLikeThisFieldMaxWordLength :: Maybe MaxWordLength
1165 , moreLikeThisFieldBoostTerms :: Maybe BoostTerms
1166 , moreLikeThisFieldBoost :: Maybe Boost
1167 , moreLikeThisFieldAnalyzer :: Maybe Analyzer
1168 } deriving (Eq, Show, Generic, Typeable)
1170data MoreLikeThisQuery =
1171 MoreLikeThisQuery
1172 { moreLikeThisText :: Text
1173 , moreLikeThisFields :: Maybe (NonEmpty FieldName)
1174 -- default 0.3 (30%)
1175 , moreLikeThisPercentMatch :: Maybe PercentMatch
1176 , moreLikeThisMinimumTermFreq :: Maybe MinimumTermFrequency
1177 , moreLikeThisMaxQueryTerms :: Maybe MaxQueryTerms
1178 , moreLikeThisStopWords :: Maybe (NonEmpty StopWord)
1179 , moreLikeThisMinDocFrequency :: Maybe MinDocFrequency
1180 , moreLikeThisMaxDocFrequency :: Maybe MaxDocFrequency
1181 , moreLikeThisMinWordLength :: Maybe MinWordLength
1182 , moreLikeThisMaxWordLength :: Maybe MaxWordLength
1183 , moreLikeThisBoostTerms :: Maybe BoostTerms
1184 , moreLikeThisBoost :: Maybe Boost
1185 , moreLikeThisAnalyzer :: Maybe Analyzer
1186 } deriving (Eq, Show, Generic, Typeable)
1188data IndicesQuery =
1189 IndicesQuery
1190 { indicesQueryIndices :: [IndexName]
1191 , indicesQuery :: Query
1192 -- default "all"
1193 , indicesQueryNoMatch :: Maybe Query } deriving (Eq, Show, Generic, Typeable)
1195data HasParentQuery =
1196 HasParentQuery
1197 { hasParentQueryType :: TypeName
1198 , hasParentQuery :: Query
1199 , hasParentQueryScoreType :: Maybe ScoreType } deriving (Eq, Show, Generic, Typeable)
1201data HasChildQuery =
1202 HasChildQuery
1203 { hasChildQueryType :: TypeName
1204 , hasChildQuery :: Query
1205 , hasChildQueryScoreType :: Maybe ScoreType } deriving (Eq, Show, Generic, Typeable)
1207data ScoreType =
1208 ScoreTypeMax
1209 | ScoreTypeSum
1210 | ScoreTypeAvg
1211 | ScoreTypeNone deriving (Eq, Show, Generic, Typeable)
1213data FuzzyQuery =
1214 FuzzyQuery { fuzzyQueryField :: FieldName
1215 , fuzzyQueryValue :: Text
1216 , fuzzyQueryPrefixLength :: PrefixLength
1217 , fuzzyQueryMaxExpansions :: MaxExpansions
1218 , fuzzyQueryFuzziness :: Fuzziness
1219 , fuzzyQueryBoost :: Maybe Boost
1220 } deriving (Eq, Show, Generic, Typeable)
1222data FuzzyLikeFieldQuery =
1223 FuzzyLikeFieldQuery
1224 { fuzzyLikeField :: FieldName
1225 -- anaphora is good for the soul.
1226 , fuzzyLikeFieldText :: Text
1227 , fuzzyLikeFieldMaxQueryTerms :: MaxQueryTerms
1228 , fuzzyLikeFieldIgnoreTermFrequency :: IgnoreTermFrequency
1229 , fuzzyLikeFieldFuzziness :: Fuzziness
1230 , fuzzyLikeFieldPrefixLength :: PrefixLength
1231 , fuzzyLikeFieldBoost :: Boost
1232 , fuzzyLikeFieldAnalyzer :: Maybe Analyzer
1233 } deriving (Eq, Show, Generic, Typeable)
1235data FuzzyLikeThisQuery =
1236 FuzzyLikeThisQuery
1237 { fuzzyLikeFields :: [FieldName]
1238 , fuzzyLikeText :: Text
1239 , fuzzyLikeMaxQueryTerms :: MaxQueryTerms
1240 , fuzzyLikeIgnoreTermFrequency :: IgnoreTermFrequency
1241 , fuzzyLikeFuzziness :: Fuzziness
1242 , fuzzyLikePrefixLength :: PrefixLength
1243 , fuzzyLikeBoost :: Boost
1244 , fuzzyLikeAnalyzer :: Maybe Analyzer
1245 } deriving (Eq, Show, Generic, Typeable)
1247data FilteredQuery =
1248 FilteredQuery
1249 { filteredQuery :: Query
1250 , filteredFilter :: Filter } deriving (Eq, Show, Generic, Typeable)
1252data DisMaxQuery =
1253 DisMaxQuery { disMaxQueries :: [Query]
1254 -- default 0.0
1255 , disMaxTiebreaker :: Tiebreaker
1256 , disMaxBoost :: Maybe Boost
1257 } deriving (Eq, Show, Generic, Typeable)
1259data MatchQuery =
1260 MatchQuery { matchQueryField :: FieldName
1261 , matchQueryQueryString :: QueryString
1262 , matchQueryOperator :: BooleanOperator
1263 , matchQueryZeroTerms :: ZeroTermsQuery
1264 , matchQueryCutoffFrequency :: Maybe CutoffFrequency
1265 , matchQueryMatchType :: Maybe MatchQueryType
1266 , matchQueryAnalyzer :: Maybe Analyzer
1267 , matchQueryMaxExpansions :: Maybe MaxExpansions
1268 , matchQueryLenient :: Maybe Lenient
1269 , matchQueryBoost :: Maybe Boost } deriving (Eq, Show, Generic, Typeable)
1271{-| 'mkMatchQuery' is a convenience function that defaults the less common parameters,
1272 enabling you to provide only the 'FieldName' and 'QueryString' to make a 'MatchQuery'
1274mkMatchQuery :: FieldName -> QueryString -> MatchQuery
1275mkMatchQuery field query = MatchQuery field query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1277data MatchQueryType =
1278 MatchPhrase
1279 | MatchPhrasePrefix deriving (Eq, Show, Generic, Typeable)
1281data MultiMatchQuery =
1282 MultiMatchQuery { multiMatchQueryFields :: [FieldName]
1283 , multiMatchQueryString :: QueryString
1284 , multiMatchQueryOperator :: BooleanOperator
1285 , multiMatchQueryZeroTerms :: ZeroTermsQuery
1286 , multiMatchQueryTiebreaker :: Maybe Tiebreaker
1287 , multiMatchQueryType :: Maybe MultiMatchQueryType
1288 , multiMatchQueryCutoffFrequency :: Maybe CutoffFrequency
1289 , multiMatchQueryAnalyzer :: Maybe Analyzer
1290 , multiMatchQueryMaxExpansions :: Maybe MaxExpansions
1291 , multiMatchQueryLenient :: Maybe Lenient } deriving (Eq, Show, Generic, Typeable)
1293{-| 'mkMultiMatchQuery' is a convenience function that defaults the less common parameters,
1294 enabling you to provide only the list of 'FieldName's and 'QueryString' to
1295 make a 'MultiMatchQuery'.
1298mkMultiMatchQuery :: [FieldName] -> QueryString -> MultiMatchQuery
1299mkMultiMatchQuery matchFields query =
1300 MultiMatchQuery matchFields query
1301 Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1303data MultiMatchQueryType =
1304 MultiMatchBestFields
1305 | MultiMatchMostFields
1306 | MultiMatchCrossFields
1307 | MultiMatchPhrase
1308 | MultiMatchPhrasePrefix deriving (Eq, Show, Generic, Typeable)
1310data BoolQuery =
1311 BoolQuery { boolQueryMustMatch :: [Query]
1312 , boolQueryMustNotMatch :: [Query]
1313 , boolQueryShouldMatch :: [Query]
1314 , boolQueryMinimumShouldMatch :: Maybe MinimumMatch
1315 , boolQueryBoost :: Maybe Boost
1316 , boolQueryDisableCoord :: Maybe DisableCoord
1317 } deriving (Eq, Show, Generic, Typeable)
1319mkBoolQuery :: [Query] -> [Query] -> [Query] -> BoolQuery
1320mkBoolQuery must mustNot should =
1321 BoolQuery must mustNot should Nothing Nothing Nothing
1323data BoostingQuery =
1324 BoostingQuery { positiveQuery :: Query
1325 , negativeQuery :: Query
1326 , negativeBoost :: Boost } deriving (Eq, Show, Generic, Typeable)
1328data CommonTermsQuery =
1329 CommonTermsQuery { commonField :: FieldName
1330 , commonQuery :: QueryString
1331 , commonCutoffFrequency :: CutoffFrequency
1332 , commonLowFreqOperator :: BooleanOperator
1333 , commonHighFreqOperator :: BooleanOperator
1334 , commonMinimumShouldMatch :: Maybe CommonMinimumMatch
1335 , commonBoost :: Maybe Boost
1336 , commonAnalyzer :: Maybe Analyzer
1337 , commonDisableCoord :: Maybe DisableCoord
1338 } deriving (Eq, Show, Generic, Typeable)
1340data CommonMinimumMatch =
1341 CommonMinimumMatchHighLow MinimumMatchHighLow
1342 | CommonMinimumMatch MinimumMatch
1343 deriving (Eq, Show, Generic, Typeable)
1345data MinimumMatchHighLow =
1346 MinimumMatchHighLow { lowFreq :: MinimumMatch
1347 , highFreq :: MinimumMatch } deriving (Eq, Show, Generic, Typeable)
1349data Filter = AndFilter [Filter] Cache
1350 | OrFilter [Filter] Cache
1351 | NotFilter Filter Cache
1352 | IdentityFilter
1353 | BoolFilter BoolMatch
1354 | ExistsFilter FieldName -- always cached
1355 | GeoBoundingBoxFilter GeoBoundingBoxConstraint
1356 | GeoDistanceFilter GeoPoint Distance DistanceType OptimizeBbox Cache
1357 | GeoDistanceRangeFilter GeoPoint DistanceRange
1358 | GeoPolygonFilter FieldName [LatLon]
1359 | IdsFilter MappingName [DocId]
1360 | LimitFilter Int
1361 | MissingFilter FieldName Existence NullValue
1362 | PrefixFilter FieldName PrefixValue Cache
1363 | QueryFilter Query Cache
1364 | RangeFilter FieldName RangeValue RangeExecution Cache
1365 | RegexpFilter FieldName Regexp RegexpFlags CacheName Cache CacheKey
1366 | TermFilter Term Cache
1367 deriving (Eq, Show, Generic, Typeable)
1369data ZeroTermsQuery = ZeroTermsNone
1370 | ZeroTermsAll deriving (Eq, Show, Generic, Typeable)
1372data RangeExecution = RangeExecutionIndex
1373 | RangeExecutionFielddata deriving (Eq, Show, Generic, Typeable)
1375newtype Regexp = Regexp Text deriving (Eq, Show, Generic, Typeable, FromJSON)
1377data RegexpFlags = AllRegexpFlags
1378 | NoRegexpFlags
1379 | SomeRegexpFlags (NonEmpty RegexpFlag) deriving (Eq, Show, Generic, Typeable)
1381data RegexpFlag = AnyString
1382 | Automaton
1383 | Complement
1384 | Empty
1385 | Intersection
1386 | Interval deriving (Eq, Show, Generic, Typeable)
1388newtype LessThan = LessThan Double deriving (Eq, Show, Generic, Typeable)
1389newtype LessThanEq = LessThanEq Double deriving (Eq, Show, Generic, Typeable)
1390newtype GreaterThan = GreaterThan Double deriving (Eq, Show, Generic, Typeable)
1391newtype GreaterThanEq = GreaterThanEq Double deriving (Eq, Show, Generic, Typeable)
1393newtype LessThanD = LessThanD UTCTime deriving (Eq, Show, Generic, Typeable)
1394newtype LessThanEqD = LessThanEqD UTCTime deriving (Eq, Show, Generic, Typeable)
1395newtype GreaterThanD = GreaterThanD UTCTime deriving (Eq, Show, Generic, Typeable)
1396newtype GreaterThanEqD = GreaterThanEqD UTCTime deriving (Eq, Show, Generic, Typeable)
1398data RangeValue = RangeDateLte LessThanEqD
1399 | RangeDateLt LessThanD
1400 | RangeDateGte GreaterThanEqD
1401 | RangeDateGt GreaterThanD
1402 | RangeDateGtLt GreaterThanD LessThanD
1403 | RangeDateGteLte GreaterThanEqD LessThanEqD
1404 | RangeDateGteLt GreaterThanEqD LessThanD
1405 | RangeDateGtLte GreaterThanD LessThanEqD
1406 | RangeDoubleLte LessThanEq
1407 | RangeDoubleLt LessThan
1408 | RangeDoubleGte GreaterThanEq
1409 | RangeDoubleGt GreaterThan
1410 | RangeDoubleGtLt GreaterThan LessThan
1411 | RangeDoubleGteLte GreaterThanEq LessThanEq
1412 | RangeDoubleGteLt GreaterThanEq LessThan
1413 | RangeDoubleGtLte GreaterThan LessThanEq
1414 deriving (Eq, Show, Generic, Typeable)
1416rangeValueToPair :: RangeValue -> [Pair]
1417rangeValueToPair rv = case rv of
1418 RangeDateLte (LessThanEqD t) -> ["lte" .= t]
1419 RangeDateGte (GreaterThanEqD t) -> ["gte" .= t]
1420 RangeDateLt (LessThanD t) -> ["lt" .= t]
1421 RangeDateGt (GreaterThanD t) -> ["gt" .= t]
1422 RangeDateGteLte (GreaterThanEqD l) (LessThanEqD g) -> ["gte" .= l, "lte" .= g]
1423 RangeDateGtLte (GreaterThanD l) (LessThanEqD g) -> ["gt" .= l, "lte" .= g]
1424 RangeDateGteLt (GreaterThanEqD l) (LessThanD g) -> ["gte" .= l, "lt" .= g]
1425 RangeDateGtLt (GreaterThanD l) (LessThanD g) -> ["gt" .= l, "lt" .= g]
1426 RangeDoubleLte (LessThanEq t) -> ["lte" .= t]
1427 RangeDoubleGte (GreaterThanEq t) -> ["gte" .= t]
1428 RangeDoubleLt (LessThan t) -> ["lt" .= t]
1429 RangeDoubleGt (GreaterThan t) -> ["gt" .= t]
1430 RangeDoubleGteLte (GreaterThanEq l) (LessThanEq g) -> ["gte" .= l, "lte" .= g]
1431 RangeDoubleGtLte (GreaterThan l) (LessThanEq g) -> ["gt" .= l, "lte" .= g]
1432 RangeDoubleGteLt (GreaterThanEq l) (LessThan g) -> ["gte" .= l, "lt" .= g]
1433 RangeDoubleGtLt (GreaterThan l) (LessThan g) -> ["gt" .= l, "lt" .= g]
1435data Term = Term { termField :: Text
1436 , termValue :: Text } deriving (Eq, Show, Generic, Typeable)
1438data BoolMatch = MustMatch Term Cache
1439 | MustNotMatch Term Cache
1440 | ShouldMatch [Term] Cache deriving (Eq, Show, Generic, Typeable)
1442-- "memory" or "indexed"
1443data GeoFilterType = GeoFilterMemory
1444 | GeoFilterIndexed deriving (Eq, Show, Generic, Typeable)
1446data LatLon = LatLon { lat :: Double
1447 , lon :: Double } deriving (Eq, Show, Generic, Typeable)
1449data GeoBoundingBox =
1450 GeoBoundingBox { topLeft :: LatLon
1451 , bottomRight :: LatLon } deriving (Eq, Show, Generic, Typeable)
1453data GeoBoundingBoxConstraint =
1454 GeoBoundingBoxConstraint { geoBBField :: FieldName
1455 , constraintBox :: GeoBoundingBox
1456 , bbConstraintcache :: Cache
1457 , geoType :: GeoFilterType
1458 } deriving (Eq, Show, Generic, Typeable)
1460data GeoPoint =
1461 GeoPoint { geoField :: FieldName
1462 , latLon :: LatLon} deriving (Eq, Show, Generic, Typeable)
1464data DistanceUnit = Miles
1465 | Yards
1466 | Feet
1467 | Inches
1468 | Kilometers
1469 | Meters
1470 | Centimeters
1471 | Millimeters
1472 | NauticalMiles deriving (Eq, Show, Generic, Typeable)
1474data DistanceType = Arc
1475 | SloppyArc -- doesn't exist <1.0
1476 | Plane deriving (Eq, Show, Generic, Typeable)
1478data OptimizeBbox = OptimizeGeoFilterType GeoFilterType
1479 | NoOptimizeBbox deriving (Eq, Show, Generic, Typeable)
1481data Distance =
1482 Distance { coefficient :: Double
1483 , unit :: DistanceUnit } deriving (Eq, Show, Generic, Typeable)
1485data DistanceRange =
1486 DistanceRange { distanceFrom :: Distance
1487 , distanceTo :: Distance } deriving (Eq, Show, Generic, Typeable)
1489data SearchResult a =
1490 SearchResult { took :: Int
1491 , timedOut :: Bool
1492 , shards :: ShardResult
1493 , searchHits :: SearchHits a
1494 , aggregations :: Maybe AggregationResults
1495 , scrollId :: Maybe ScrollId } deriving (Eq, Show, Generic, Typeable)
1497newtype ScrollId = ScrollId Text deriving (Eq, Show, Generic, Ord, ToJSON, FromJSON)
1499type Score = Maybe Double
1501data SearchHits a =
1502 SearchHits { hitsTotal :: Int
1503 , maxScore :: Score
1504 , hits :: [Hit a] } deriving (Eq, Show, Generic, Typeable)
1507instance Monoid (SearchHits a) where
1508 mempty = SearchHits 0 Nothing mempty
1509 mappend (SearchHits ta ma ha) (SearchHits tb mb hb) =
1510 SearchHits (ta + tb) (max ma mb) (ha <> hb)
1513data Hit a =
1514 Hit { hitIndex :: IndexName
1515 , hitType :: MappingName
1516 , hitDocId :: DocId
1517 , hitScore :: Score
1518 , hitSource :: Maybe a
1519 , hitHighlight :: Maybe HitHighlight } deriving (Eq, Show, Generic, Typeable)
1521data ShardResult =
1522 ShardResult { shardTotal :: Int
1523 , shardsSuccessful :: Int
1524 , shardsFailed :: Int } deriving (Eq, Show, Generic, Typeable)
1526type HitHighlight = M.Map Text [Text]
1528showText :: Show a => a -> Text
1529showText = T.pack . show
1531readMay :: Read a => String -> Maybe a
1532readMay s = case reads s of
1533 (a, ""):_ -> Just a
1534 _ -> Nothing
1536parseReadText :: Read a => Text -> Parser a
1537parseReadText = maybe mzero return . readMay . T.unpack
1539type Aggregations = M.Map Text Aggregation
1541emptyAggregations :: Aggregations
1542emptyAggregations = M.empty
1544mkAggregations :: Text -> Aggregation -> Aggregations
1545mkAggregations name aggregation = M.insert name aggregation emptyAggregations
1547data TermOrder = TermOrder{ termSortField :: Text
1548 , termSortOrder :: SortOrder } deriving (Eq, Show, Generic, Typeable)
1550data TermInclusion = TermInclusion Text
1551 | TermPattern Text Text deriving (Eq, Show, Generic, Typeable)
1553data CollectionMode = BreadthFirst
1554 | DepthFirst deriving (Eq, Show, Generic, Typeable)
1556data ExecutionHint = Ordinals
1557 | GlobalOrdinals
1558 | GlobalOrdinalsHash
1559 | GlobalOrdinalsLowCardinality
1560 | Map deriving (Eq, Show, Generic, Typeable)
1562data TimeInterval = Weeks
1563 | Days
1564 | Hours
1565 | Minutes
1566 | Seconds deriving (Eq)
1568data Interval = Year
1569 | Quarter
1570 | Month
1571 | Week
1572 | Day
1573 | Hour
1574 | Minute
1575 | Second
1576 | FractionalInterval Float TimeInterval deriving (Eq, Show, Generic, Typeable)
1578data Aggregation = TermsAgg TermsAggregation
1579 | DateHistogramAgg DateHistogramAggregation
1580 | ValueCountAgg ValueCountAggregation
1581 | FilterAgg FilterAggregation
1582 | DateRangeAgg DateRangeAggregation
1583 | MissingAgg MissingAggregation deriving (Eq, Show, Generic, Typeable)
1585data MissingAggregation = MissingAggregation
1586 { maField :: Text
1587 } deriving (Eq, Show, Generic, Typeable)
1589data TermsAggregation = TermsAggregation { term :: Either Text Text
1590 , termInclude :: Maybe TermInclusion
1591 , termExclude :: Maybe TermInclusion
1592 , termOrder :: Maybe TermOrder
1593 , termMinDocCount :: Maybe Int
1594 , termSize :: Maybe Int
1595 , termShardSize :: Maybe Int
1596 , termCollectMode :: Maybe CollectionMode
1597 , termExecutionHint :: Maybe ExecutionHint
1598 , termAggs :: Maybe Aggregations
1599 } deriving (Eq, Show, Generic, Typeable)
1601data DateHistogramAggregation = DateHistogramAggregation { dateField :: FieldName
1602 , dateInterval :: Interval
1603 , dateFormat :: Maybe Text
1604 -- pre and post deprecated in 1.5
1605 , datePreZone :: Maybe Text
1606 , datePostZone :: Maybe Text
1607 , datePreOffset :: Maybe Text
1608 , datePostOffset :: Maybe Text
1609 , dateAggs :: Maybe Aggregations
1610 } deriving (Eq, Show, Generic, Typeable)
1613data DateRangeAggregation = DateRangeAggregation { draField :: FieldName
1614 , draFormat :: Maybe Text
1615 , draRanges :: NonEmpty DateRangeAggRange
1616 } deriving (Eq, Show, Generic, Typeable)
1618data DateRangeAggRange = DateRangeFrom DateMathExpr
1619 | DateRangeTo DateMathExpr
1620 | DateRangeFromAndTo DateMathExpr DateMathExpr deriving (Eq, Show, Generic, Typeable)
1622-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math> for more information.
1623data DateMathExpr = DateMathExpr DateMathAnchor [DateMathModifier] deriving (Eq, Show, Generic, Typeable)
1626-- | Starting point for a date range. This along with the 'DateMathModifiers' gets you the date ES will start from.
1627data DateMathAnchor = DMNow
1628 | DMDate Day deriving (Eq, Show, Generic, Typeable)
1630data DateMathModifier = AddTime Int DateMathUnit
1631 | SubtractTime Int DateMathUnit
1632 | RoundDownTo DateMathUnit deriving (Eq, Show, Generic, Typeable)
1634data DateMathUnit = DMYear
1635 | DMMonth
1636 | DMWeek
1637 | DMDay
1638 | DMHour
1639 | DMMinute
1640 | DMSecond deriving (Eq, Show, Generic, Typeable)
1642-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html> for more information.
1643data ValueCountAggregation = FieldValueCount FieldName
1644 | ScriptValueCount Script deriving (Eq, Show, Generic, Typeable)
1646-- | 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.
1647data FilterAggregation = FilterAggregation { faFilter :: Filter
1648 , faAggs :: Maybe Aggregations} deriving (Eq, Show, Generic, Typeable)
1650mkTermsAggregation :: Text -> TermsAggregation
1651mkTermsAggregation t = TermsAggregation (Left t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1653mkTermsScriptAggregation :: Text -> TermsAggregation
1654mkTermsScriptAggregation t = TermsAggregation (Right t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1656mkDateHistogram :: FieldName -> Interval -> DateHistogramAggregation
1657mkDateHistogram t i = DateHistogramAggregation t i Nothing Nothing Nothing Nothing Nothing Nothing
1659instance ToJSON Version where
1660 toJSON Version {..} = object ["number" .= number
1661 ,"build_hash" .= build_hash
1662 ,"build_timestamp" .= build_timestamp
1663 ,"build_snapshot" .= build_snapshot
1664 ,"lucene_version" .= lucene_version]
1666instance FromJSON Version where
1667 parseJSON = withObject "Version" parse
1668 where parse o = Version
1669 <$> o .: "number"
1670 <*> o .: "build_hash"
1671 <*> o .: "build_timestamp"
1672 <*> o .: "build_snapshot"
1673 <*> o .: "lucene_version"
1675instance ToJSON TermOrder where
1676 toJSON (TermOrder termSortField termSortOrder) = object [termSortField .= termSortOrder]
1678instance ToJSON TermInclusion where
1679 toJSON (TermInclusion x) = toJSON x
1680 toJSON (TermPattern pattern flags) = omitNulls [ "pattern" .= pattern,
1681 "flags" .= flags]
1683instance ToJSON CollectionMode where
1684 toJSON BreadthFirst = "breadth_first"
1685 toJSON DepthFirst = "depth_first"
1687instance ToJSON ExecutionHint where
1688 toJSON Ordinals = "ordinals"
1689 toJSON GlobalOrdinals = "global_ordinals"
1690 toJSON GlobalOrdinalsHash = "global_ordinals_hash"
1691 toJSON GlobalOrdinalsLowCardinality = "global_ordinals_low_cardinality"
1692 toJSON Map = "map"
1694instance ToJSON Interval where
1695 toJSON Year = "year"
1696 toJSON Quarter = "quarter"
1697 toJSON Month = "month"
1698 toJSON Week = "week"
1699 toJSON Day = "day"
1700 toJSON Hour = "hour"
1701 toJSON Minute = "minute"
1702 toJSON Second = "second"
1703 toJSON (FractionalInterval fraction interval) = toJSON $ show fraction ++ show interval
1705instance Show TimeInterval where
1706 show Weeks = "w"
1707 show Days = "d"
1708 show Hours = "h"
1709 show Minutes = "m"
1710 show Seconds = "s"
1712instance ToJSON Aggregation where
1713 toJSON (TermsAgg (TermsAggregation term include exclude order minDocCount size shardSize collectMode executionHint termAggs)) =
1714 omitNulls ["terms" .= omitNulls [ toJSON' term,
1715 "include" .= include,
1716 "exclude" .= exclude,
1717 "order" .= order,
1718 "min_doc_count" .= minDocCount,
1719 "size" .= size,
1720 "shard_size" .= shardSize,
1721 "collect_mode" .= collectMode,
1722 "execution_hint" .= executionHint
1723 ],
1724 "aggs" .= termAggs ]
1725 where
1726 toJSON' x = case x of { Left y -> "field" .= y; Right y -> "script" .= y }
1728 toJSON (DateHistogramAgg (DateHistogramAggregation field interval format preZone postZone preOffset postOffset dateHistoAggs)) =
1729 omitNulls ["date_histogram" .= omitNulls [ "field" .= field,
1730 "interval" .= interval,
1731 "format" .= format,
1732 "pre_zone" .= preZone,
1733 "post_zone" .= postZone,
1734 "pre_offset" .= preOffset,
1735 "post_offset" .= postOffset
1736 ],
1737 "aggs" .= dateHistoAggs ]
1738 toJSON (ValueCountAgg a) = object ["value_count" .= v]
1739 where v = case a of
1740 (FieldValueCount (FieldName n)) -> object ["field" .= n]
1741 (ScriptValueCount (Script s)) -> object ["script" .= s]
1742 toJSON (FilterAgg (FilterAggregation filt ags)) =
1743 omitNulls [ "filter" .= filt
1744 , "aggs" .= ags]
1745 toJSON (DateRangeAgg a) = object [ "date_range" .= a
1747 toJSON (MissingAgg (MissingAggregation{..})) =
1748 object ["missing" .= object ["field" .= maField]]
1750instance ToJSON DateRangeAggregation where
1751 toJSON DateRangeAggregation {..} =
1752 omitNulls [ "field" .= draField
1753 , "format" .= draFormat
1754 , "ranges" .= toList draRanges
1757instance ToJSON DateRangeAggRange where
1758 toJSON (DateRangeFrom e) = object [ "from" .= e ]
1759 toJSON (DateRangeTo e) = object [ "to" .= e ]
1760 toJSON (DateRangeFromAndTo f t) = object [ "from" .= f, "to" .= t ]
1762instance ToJSON DateMathExpr where
1763 toJSON (DateMathExpr a mods) = String (fmtA a <> mconcat (fmtMod <$> mods))
1764 where fmtA DMNow = "now"
1765 fmtA (DMDate date) = case toGregorian date of
1766 (y,m,d) -> showText y <> "-" <>
1767 showText m <> "-" <>
1768 showText d <> "||"
1769 fmtMod (AddTime n u) = "+" <> showText n <> fmtU u
1770 fmtMod (SubtractTime n u) = "-" <> showText n <> fmtU u
1771 fmtMod (RoundDownTo u) = "/" <> fmtU u
1772 fmtU DMYear = "y"
1773 fmtU DMMonth = "M"
1774 fmtU DMWeek = "w"
1775 fmtU DMDay = "d"
1776 fmtU DMHour = "h"
1777 fmtU DMMinute = "m"
1778 fmtU DMSecond = "s"
1781type AggregationResults = M.Map Text Value
1783class BucketAggregation a where
1784 key :: a -> BucketValue
1785 docCount :: a -> Int
1786 aggs :: a -> Maybe AggregationResults
1789data Bucket a = Bucket { buckets :: [a]} deriving (Show, Eq)
1791data BucketValue = TextValue Text
1792 | ScientificValue Scientific
1793 | BoolValue Bool deriving (Show, Eq)
1795data TermsResult = TermsResult { termKey :: BucketValue
1796 , termsDocCount :: Int
1797 , termsAggs :: Maybe AggregationResults } deriving (Show, Eq)
1799data DateHistogramResult = DateHistogramResult { dateKey :: Int
1800 , dateKeyStr :: Maybe Text
1801 , dateDocCount :: Int
1802 , dateHistogramAggs :: Maybe AggregationResults } deriving (Show)
1804data DateRangeResult = DateRangeResult { dateRangeKey :: Text
1805 , dateRangeFrom :: Maybe UTCTime
1806 , dateRangeFromAsString :: Maybe Text
1807 , dateRangeTo :: Maybe UTCTime
1808 , dateRangeToAsString :: Maybe Text
1809 , dateRangeDocCount :: Int
1810 , dateRangeAggs :: Maybe AggregationResults } deriving (Show, Eq, Generic, Typeable)
1812toTerms :: Text -> AggregationResults -> Maybe (Bucket TermsResult)
1813toTerms t a = M.lookup t a >>= deserialize
1814 where deserialize = parseMaybe parseJSON
1816toDateHistogram :: Text -> AggregationResults -> Maybe (Bucket DateHistogramResult)
1817toDateHistogram t a = M.lookup t a >>= deserialize
1818 where deserialize = parseMaybe parseJSON
1820instance BucketAggregation TermsResult where
1821 key = termKey
1822 docCount = termsDocCount
1823 aggs = termsAggs
1825instance BucketAggregation DateHistogramResult where
1826 key = TextValue . showText . dateKey
1827 docCount = dateDocCount
1828 aggs = dateHistogramAggs
1830instance BucketAggregation DateRangeResult where
1831 key = TextValue . dateRangeKey
1832 docCount = dateRangeDocCount
1833 aggs = dateRangeAggs
1835instance (FromJSON a, BucketAggregation a) => FromJSON (Bucket a) where
1836 parseJSON (Object v) = Bucket <$>
1837 v .: "buckets"
1838 parseJSON _ = mempty
1840instance FromJSON BucketValue where
1841 parseJSON (String t) = return $ TextValue t
1842 parseJSON (Number s) = return $ ScientificValue s
1843 parseJSON (Bool b) = return $ BoolValue b
1844 parseJSON _ = mempty
1846instance FromJSON TermsResult where
1847 parseJSON (Object v) = TermsResult <$>
1848 v .: "key" <*>
1849 v .: "doc_count" <*>
1850 v .:? "aggregations"
1851 parseJSON _ = mempty
1853instance FromJSON DateHistogramResult where
1854 parseJSON (Object v) = DateHistogramResult <$>
1855 v .: "key" <*>
1856 v .:? "key_as_string" <*>
1857 v .: "doc_count" <*>
1858 v .:? "aggregations"
1859 parseJSON _ = mempty
1861instance FromJSON DateRangeResult where
1862 parseJSON = withObject "DateRangeResult" parse
1863 where parse v = DateRangeResult <$>
1864 v .: "key" <*>
1865 (fmap posixMS <$> v .:? "from") <*>
1866 v .:? "from_as_string" <*>
1867 (fmap posixMS <$> v .:? "to") <*>
1868 v .:? "to_as_string" <*>
1869 v .: "doc_count" <*>
1870 v .:? "aggregations"
1872instance FromJSON POSIXMS where
1873 parseJSON = withScientific "POSIXMS" (return . parse)
1874 where parse n = let n' = truncate n :: Integer
1875 in POSIXMS (posixSecondsToUTCTime (fromInteger (n' `div` 1000)))
1877instance Monoid Filter where
1878 mempty = IdentityFilter
1879 mappend a b = AndFilter [a, b] defaultCache
1881instance Seminearring Filter where
1882 a <||> b = OrFilter [a, b] defaultCache
1884instance ToJSON Filter where
1885 toJSON (AndFilter filters cache) =
1886 object ["and" .=
1887 object [ "filters" .= fmap toJSON filters
1888 , "_cache" .= cache]]
1890 toJSON (OrFilter filters cache) =
1891 object ["or" .=
1892 object [ "filters" .= fmap toJSON filters
1893 , "_cache" .= cache]]
1895 toJSON (NotFilter notFilter cache) =
1896 object ["not" .=
1897 object ["filter" .= notFilter
1898 , "_cache" .= cache]]
1900 toJSON (IdentityFilter) =
1901 object ["match_all" .= object []]
1903 toJSON (TermFilter (Term termFilterField termFilterValue) cache) =
1904 object ["term" .= object base]
1905 where base = [termFilterField .= termFilterValue,
1906 "_cache" .= cache]
1908 toJSON (ExistsFilter (FieldName fieldName)) =
1909 object ["exists" .= object
1910 ["field" .= fieldName]]
1912 toJSON (BoolFilter boolMatch) =
1913 object ["bool" .= boolMatch]
1915 toJSON (GeoBoundingBoxFilter bbConstraint) =
1916 object ["geo_bounding_box" .= bbConstraint]
1918 toJSON (GeoDistanceFilter (GeoPoint (FieldName distanceGeoField) geoDistLatLon)
1919 distance distanceType optimizeBbox cache) =
1920 object ["geo_distance" .=
1921 object ["distance" .= distance
1922 , "distance_type" .= distanceType
1923 , "optimize_bbox" .= optimizeBbox
1924 , distanceGeoField .= geoDistLatLon
1925 , "_cache" .= cache]]
1927 toJSON (GeoDistanceRangeFilter (GeoPoint (FieldName gddrField) drLatLon)
1928 (DistanceRange geoDistRangeDistFrom drDistanceTo)) =
1929 object ["geo_distance_range" .=
1930 object ["from" .= geoDistRangeDistFrom
1931 , "to" .= drDistanceTo
1932 , gddrField .= drLatLon]]
1934 toJSON (GeoPolygonFilter (FieldName geoPolygonFilterField) latLons) =
1935 object ["geo_polygon" .=
1936 object [geoPolygonFilterField .=
1937 object ["points" .= fmap toJSON latLons]]]
1939 toJSON (IdsFilter (MappingName mappingName) values) =
1940 object ["ids" .=
1941 object ["type" .= mappingName
1942 , "values" .= fmap unpackId values]]
1944 toJSON (LimitFilter limit) =
1945 object ["limit" .= object ["value" .= limit]]
1947 toJSON (MissingFilter (FieldName fieldName) (Existence existence) (NullValue nullValue)) =
1948 object ["missing" .=
1949 object ["field" .= fieldName
1950 , "existence" .= existence
1951 , "null_value" .= nullValue]]
1953 toJSON (PrefixFilter (FieldName fieldName) fieldValue cache) =
1954 object ["prefix" .=
1955 object [fieldName .= fieldValue
1956 , "_cache" .= cache]]
1958 toJSON (QueryFilter query False) =
1959 object ["query" .= toJSON query ]
1960 toJSON (QueryFilter query True) =
1961 object ["fquery" .=
1962 object [ "query" .= toJSON query
1963 , "_cache" .= True ]]
1965 toJSON (RangeFilter (FieldName fieldName) rangeValue rangeExecution cache) =
1966 object ["range" .=
1967 object [ fieldName .= object (rangeValueToPair rangeValue)
1968 , "execution" .= rangeExecution
1969 , "_cache" .= cache]]
1971 toJSON (RegexpFilter (FieldName fieldName)
1972 (Regexp regexText) flags (CacheName cacheName) cache (CacheKey cacheKey)) =
1973 object ["regexp" .=
1974 object [fieldName .=
1975 object ["value" .= regexText
1976 , "flags" .= flags]
1977 , "_name" .= cacheName
1978 , "_cache" .= cache
1979 , "_cache_key" .= cacheKey]]
1981instance FromJSON Filter where
1982 parseJSON = withObject "Filter" parse
1983 where parse o = andFilter `taggedWith` "and"
1984 <|> orFilter `taggedWith` "or"
1985 <|> notFilter `taggedWith` "not"
1986 <|> identityFilter `taggedWith` "match_all"
1987 <|> boolFilter `taggedWith` "bool"
1988 <|> existsFilter `taggedWith` "exists"
1989 <|> geoBoundingBoxFilter `taggedWith` "geo_bounding_box"
1990 <|> geoDistanceFilter `taggedWith` "geo_distance"
1991 <|> geoDistanceRangeFilter `taggedWith` "geo_distance_range"
1992 <|> geoPolygonFilter `taggedWith` "geo_polygon"
1993 <|> idsFilter `taggedWith` "ids"
1994 <|> limitFilter `taggedWith` "limit"
1995 <|> missingFilter `taggedWith` "missing"
1996 <|> prefixFilter `taggedWith` "prefix"
1997 <|> queryFilter `taggedWith` "query"
1998 <|> fqueryFilter `taggedWith` "fquery"
1999 <|> rangeFilter `taggedWith` "range"
2000 <|> regexpFilter `taggedWith` "regexp"
2001 <|> termFilter `taggedWith` "term"
2002 where taggedWith parser k = parser =<< o .: k
2003 andFilter o = AndFilter <$> o .: "filters"
2004 <*> o .:? "_cache" .!= defaultCache
2005 orFilter o = OrFilter <$> o .: "filters"
2006 <*> o .:? "_cache" .!= defaultCache
2007 notFilter o = NotFilter <$> o .: "filter"
2008 <*> o .: "_cache" .!= defaultCache
2009 identityFilter :: Object -> Parser Filter
2010 identityFilter m
2011 | HM.null m = pure IdentityFilter
2012 | otherwise = fail ("Identityfilter expected empty object but got " <> show m)
2013 boolFilter = pure . BoolFilter
2014 existsFilter o = ExistsFilter <$> o .: "field"
2015 geoBoundingBoxFilter = pure . GeoBoundingBoxFilter
2016 geoDistanceFilter o = do
2017 case HM.toList (deleteSeveral ["distance", "distance_type", "optimize_bbox", "_cache"] o) of
2018 [(fn, v)] -> do
2019 gp <- GeoPoint (FieldName fn) <$> parseJSON v
2020 GeoDistanceFilter gp <$> o .: "distance"
2021 <*> o .: "distance_type"
2022 <*> o .: "optimize_bbox"
2023 <*> o .:? "_cache" .!= defaultCache
2024 _ -> fail "Could not find GeoDistanceFilter field name"
2025 geoDistanceRangeFilter o = do
2026 case HM.toList (deleteSeveral ["from", "to"] o) of
2027 [(fn, v)] -> do
2028 gp <- GeoPoint (FieldName fn) <$> parseJSON v
2029 rng <- DistanceRange <$> o .: "from" <*> o .: "to"
2030 return (GeoDistanceRangeFilter gp rng)
2031 _ -> fail "Could not find GeoDistanceRangeFilter field name"
2032 geoPolygonFilter = fieldTagged $ \fn o -> GeoPolygonFilter fn <$> o .: "points"
2033 idsFilter o = IdsFilter <$> o .: "type"
2034 <*> o .: "values"
2035 limitFilter o = LimitFilter <$> o .: "value"
2036 missingFilter o = MissingFilter <$> o .: "field"
2037 <*> o .: "existence"
2038 <*> o .: "null_value"
2039 prefixFilter o = case HM.toList (HM.delete "_cache" o) of
2040 [(fn, String v)] -> PrefixFilter (FieldName fn) v <$> o .:? "_cache" .!= defaultCache
2041 _ -> fail "Could not parse PrefixFilter"
2043 queryFilter q = pure (QueryFilter q False)
2044 fqueryFilter o = QueryFilter <$> o .: "query" <*> pure True
2045 rangeFilter o = case HM.toList (deleteSeveral ["execution", "_cache"] o) of
2046 [(fn, v)] -> RangeFilter (FieldName fn)
2047 <$> parseJSON v
2048 <*> o .: "execution"
2049 <*> o .:? "_cache" .!= defaultCache
2050 _ -> fail "Could not find field name for RangeFilter"
2051 regexpFilter o = case HM.toList (deleteSeveral ["_name", "_cache", "_cache_key"] o) of
2052 [(fn, Object o')] -> RegexpFilter (FieldName fn)
2053 <$> o' .: "value"
2054 <*> o' .: "flags"
2055 <*> o .: "_name"
2056 <*> o .:? "_cache" .!= defaultCache
2057 <*> o .: "_cache_key"
2058 _ -> fail "Could not find field name for RegexpFilter"
2059 termFilter o = case HM.toList (HM.delete "_cache" o) of
2060 [(termField, String termVal)] -> TermFilter (Term termField termVal)
2061 <$> o .:? "_cache" .!= defaultCache
2062 _ -> fail "Could not find term field for TermFilter"
2064fieldTagged :: Monad m => (FieldName -> Object -> m a) -> Object -> m a
2065fieldTagged f o = case HM.toList o of
2066 [(k, Object o')] -> f (FieldName k) o'
2067 _ -> fail "Expected object with 1 field-named key"
2069instance ToJSON GeoPoint where
2070 toJSON (GeoPoint (FieldName geoPointField) geoPointLatLon) =
2071 object [ geoPointField .= geoPointLatLon ]
2074instance ToJSON Query where
2075 toJSON (TermQuery (Term termQueryField termQueryValue) boost) =
2076 object [ "term" .=
2077 object [termQueryField .= object merged]]
2078 where
2079 base = [ "value" .= termQueryValue ]
2080 boosted = maybe [] (return . ("boost" .=)) boost
2081 merged = mappend base boosted
2083 toJSON (TermsQuery fieldName terms) =
2084 object [ "terms" .= object conjoined ]
2085 where conjoined = [fieldName .= terms]
2086 toJSON (IdsQuery idsQueryMappingName docIds) =
2087 object [ "ids" .= object conjoined ]
2088 where conjoined = [ "type" .= idsQueryMappingName
2089 , "values" .= fmap toJSON docIds ]
2091 toJSON (QueryQueryStringQuery qQueryStringQuery) =
2092 object [ "query_string" .= qQueryStringQuery ]
2094 toJSON (QueryMatchQuery matchQuery) =
2095 object [ "match" .= matchQuery ]
2097 toJSON (QueryMultiMatchQuery multiMatchQuery) =
2098 toJSON multiMatchQuery
2100 toJSON (QueryBoolQuery boolQuery) =
2101 object [ "bool" .= boolQuery ]
2103 toJSON (QueryBoostingQuery boostingQuery) =
2104 object [ "boosting" .= boostingQuery ]
2106 toJSON (QueryCommonTermsQuery commonTermsQuery) =
2107 object [ "common" .= commonTermsQuery ]
2109 toJSON (ConstantScoreFilter csFilter boost) =
2110 object ["constant_score" .= object ["filter" .= csFilter
2111 , "boost" .= boost]]
2113 toJSON (ConstantScoreQuery query boost) =
2114 object ["constant_score" .= object ["query" .= query
2115 , "boost" .= boost]]
2117 toJSON (QueryDisMaxQuery disMaxQuery) =
2118 object [ "dis_max" .= disMaxQuery ]
2120 toJSON (QueryFilteredQuery qFilteredQuery) =
2121 object [ "filtered" .= qFilteredQuery ]
2123 toJSON (QueryFuzzyLikeThisQuery fuzzyQuery) =
2124 object [ "fuzzy_like_this" .= fuzzyQuery ]
2126 toJSON (QueryFuzzyLikeFieldQuery fuzzyFieldQuery) =
2127 object [ "fuzzy_like_this_field" .= fuzzyFieldQuery ]
2129 toJSON (QueryFuzzyQuery fuzzyQuery) =
2130 object [ "fuzzy" .= fuzzyQuery ]
2132 toJSON (QueryHasChildQuery childQuery) =
2133 object [ "has_child" .= childQuery ]
2135 toJSON (QueryHasParentQuery parentQuery) =
2136 object [ "has_parent" .= parentQuery ]
2138 toJSON (QueryIndicesQuery qIndicesQuery) =
2139 object [ "indices" .= qIndicesQuery ]
2141 toJSON (MatchAllQuery boost) =
2142 object [ "match_all" .= omitNulls [ "boost" .= boost ] ]
2144 toJSON (QueryMoreLikeThisQuery query) =
2145 object [ "more_like_this" .= query ]
2147 toJSON (QueryMoreLikeThisFieldQuery query) =
2148 object [ "more_like_this_field" .= query ]
2150 toJSON (QueryNestedQuery query) =
2151 object [ "nested" .= query ]
2153 toJSON (QueryPrefixQuery query) =
2154 object [ "prefix" .= query ]
2156 toJSON (QueryRangeQuery query) =
2157 object [ "range" .= query ]
2159 toJSON (QueryRegexpQuery query) =
2160 object [ "regexp" .= query ]
2162 toJSON (QuerySimpleQueryStringQuery query) =
2163 object [ "simple_query_string" .= query ]
2165instance FromJSON Query where
2166 parseJSON v = withObject "Query" parse v
2167 where parse o = termQuery `taggedWith` "term"
2168 <|> termsQuery `taggedWith` "terms"
2169 <|> idsQuery `taggedWith` "ids"
2170 <|> queryQueryStringQuery `taggedWith` "query_string"
2171 <|> queryMatchQuery `taggedWith` "match"
2172 <|> queryMultiMatchQuery
2173 <|> queryBoolQuery `taggedWith` "bool"
2174 <|> queryBoostingQuery `taggedWith` "boosting"
2175 <|> queryCommonTermsQuery `taggedWith` "common"
2176 <|> constantScoreFilter `taggedWith` "constant_score"
2177 <|> constantScoreQuery `taggedWith` "constant_score"
2178 <|> queryDisMaxQuery `taggedWith` "dis_max"
2179 <|> queryFilteredQuery `taggedWith` "filtered"
2180 <|> queryFuzzyLikeThisQuery `taggedWith` "fuzzy_like_this"
2181 <|> queryFuzzyLikeFieldQuery `taggedWith` "fuzzy_like_this_field"
2182 <|> queryFuzzyQuery `taggedWith` "fuzzy"
2183 <|> queryHasChildQuery `taggedWith` "has_child"
2184 <|> queryHasParentQuery `taggedWith` "has_parent"
2185 <|> queryIndicesQuery `taggedWith` "indices"
2186 <|> matchAllQuery `taggedWith` "match_all"
2187 <|> queryMoreLikeThisQuery `taggedWith` "more_like_this"
2188 <|> queryMoreLikeThisFieldQuery `taggedWith` "more_like_this_field"
2189 <|> queryNestedQuery `taggedWith` "nested"
2190 <|> queryPrefixQuery `taggedWith` "prefix"
2191 <|> queryRangeQuery `taggedWith` "range"
2192 <|> queryRegexpQuery `taggedWith` "regexp"
2193 <|> querySimpleQueryStringQuery `taggedWith` "simple_query_string"
2194 where taggedWith parser k = parser =<< o .: k
2195 termQuery = fieldTagged $ \(FieldName fn) o ->
2196 TermQuery <$> (Term fn <$> o .: "value") <*> o .:? "boost"
2197 termsQuery o = case HM.toList o of
2198 [(fn, vs)] -> do vals <- parseJSON vs
2199 case vals of
2200 x:xs -> return (TermsQuery fn (x :| xs))
2201 _ -> fail "Expected non empty list of values"
2202 _ -> fail "Expected object with 1 field-named key"
2203 idsQuery o = IdsQuery <$> o .: "type"
2204 <*> o .: "values"
2205 queryQueryStringQuery = pure . QueryQueryStringQuery
2206 queryMatchQuery = pure . QueryMatchQuery
2207 queryMultiMatchQuery = QueryMultiMatchQuery <$> parseJSON v
2208 queryBoolQuery = pure . QueryBoolQuery
2209 queryBoostingQuery = pure . QueryBoostingQuery
2210 queryCommonTermsQuery = pure . QueryCommonTermsQuery
2211 constantScoreFilter o = case HM.lookup "filter" o of
2212 Just x -> ConstantScoreFilter <$> parseJSON x
2213 <*> o .: "boost"
2214 _ -> fail "Does not appear to be a ConstantScoreFilter"
2215 constantScoreQuery o = case HM.lookup "query" o of
2216 Just x -> ConstantScoreQuery <$> parseJSON x
2217 <*> o .: "boost"
2218 _ -> fail "Does not appear to be a ConstantScoreQuery"
2219 queryDisMaxQuery = pure . QueryDisMaxQuery
2220 queryFilteredQuery = pure . QueryFilteredQuery
2221 queryFuzzyLikeThisQuery = pure . QueryFuzzyLikeThisQuery
2222 queryFuzzyLikeFieldQuery = pure . QueryFuzzyLikeFieldQuery
2223 queryFuzzyQuery = pure . QueryFuzzyQuery
2224 queryHasChildQuery = pure . QueryHasChildQuery
2225 queryHasParentQuery = pure . QueryHasParentQuery
2226 queryIndicesQuery = pure . QueryIndicesQuery
2227 matchAllQuery o = MatchAllQuery <$> o .:? "boost"
2228 queryMoreLikeThisQuery = pure . QueryMoreLikeThisQuery
2229 queryMoreLikeThisFieldQuery = pure . QueryMoreLikeThisFieldQuery
2230 queryNestedQuery = pure . QueryNestedQuery
2231 queryPrefixQuery = pure . QueryPrefixQuery
2232 queryRangeQuery = pure . QueryRangeQuery
2233 queryRegexpQuery = pure . QueryRegexpQuery
2234 querySimpleQueryStringQuery = pure . QuerySimpleQueryStringQuery
2237omitNulls :: [(Text, Value)] -> Value
2238omitNulls = object . filter notNull where
2239 notNull (_, Null) = False
2240 notNull (_, Array a) = (not . V.null) a
2241 notNull _ = True
2244instance ToJSON SimpleQueryStringQuery where
2245 toJSON SimpleQueryStringQuery {..} =
2246 omitNulls (base ++ maybeAdd)
2247 where base = [ "query" .= simpleQueryStringQuery ]
2248 maybeAdd = [ "fields" .= simpleQueryStringField
2249 , "default_operator" .= simpleQueryStringOperator
2250 , "analyzer" .= simpleQueryStringAnalyzer
2251 , "flags" .= simpleQueryStringFlags
2252 , "lowercase_expanded_terms" .= simpleQueryStringLowercaseExpanded
2253 , "locale" .= simpleQueryStringLocale ]
2255instance FromJSON SimpleQueryStringQuery where
2256 parseJSON = withObject "SimpleQueryStringQuery" parse
2257 where parse o = SimpleQueryStringQuery <$> o .: "query"
2258 <*> o .:? "fields"
2259 <*> o .:? "default_operator"
2260 <*> o .:? "analyzer"
2261 <*> (parseFlags <$> o .:? "flags")
2262 <*> o .:? "lowercase_expanded_terms"
2263 <*> o .:? "locale"
2264 parseFlags (Just (x:xs)) = Just (x :| xs)
2265 parseFlags _ = Nothing
2267instance ToJSON FieldOrFields where
2268 toJSON (FofField fieldName) =
2269 toJSON fieldName
2270 toJSON (FofFields fieldNames) =
2271 toJSON fieldNames
2273instance FromJSON FieldOrFields where
2274 parseJSON v = FofField <$> parseJSON v
2275 <|> FofFields <$> (parseNEJSON =<< parseJSON v)
2277instance ToJSON SimpleQueryFlag where
2278 toJSON SimpleQueryAll = "ALL"
2279 toJSON SimpleQueryNone = "NONE"
2280 toJSON SimpleQueryAnd = "AND"
2281 toJSON SimpleQueryOr = "OR"
2282 toJSON SimpleQueryPrefix = "PREFIX"
2283 toJSON SimpleQueryPhrase = "PHRASE"
2284 toJSON SimpleQueryPrecedence = "PRECEDENCE"
2285 toJSON SimpleQueryEscape = "ESCAPE"
2286 toJSON SimpleQueryWhitespace = "WHITESPACE"
2287 toJSON SimpleQueryFuzzy = "FUZZY"
2288 toJSON SimpleQueryNear = "NEAR"
2289 toJSON SimpleQuerySlop = "SLOP"
2291instance FromJSON SimpleQueryFlag where
2292 parseJSON = withText "SimpleQueryFlag" parse
2293 where parse "ALL" = pure SimpleQueryAll
2294 parse "NONE" = pure SimpleQueryNone
2295 parse "AND" = pure SimpleQueryAnd
2296 parse "OR" = pure SimpleQueryOr
2297 parse "PREFIX" = pure SimpleQueryPrefix
2298 parse "PHRASE" = pure SimpleQueryPhrase
2299 parse "PRECEDENCE" = pure SimpleQueryPrecedence
2300 parse "ESCAPE" = pure SimpleQueryEscape
2301 parse "WHITESPACE" = pure SimpleQueryWhitespace
2302 parse "FUZZY" = pure SimpleQueryFuzzy
2303 parse "NEAR" = pure SimpleQueryNear
2304 parse "SLOP" = pure SimpleQuerySlop
2305 parse f = fail ("Unexpected SimpleQueryFlag: " <> show f)
2307instance ToJSON RegexpQuery where
2308 toJSON (RegexpQuery (FieldName rqQueryField)
2309 (Regexp regexpQueryQuery) rqQueryFlags
2310 rqQueryBoost) =
2311 object [ rqQueryField .= omitNulls base ]
2312 where base = [ "value" .= regexpQueryQuery
2313 , "flags" .= rqQueryFlags
2314 , "boost" .= rqQueryBoost ]
2316instance FromJSON RegexpQuery where
2317 parseJSON = withObject "RegexpQuery" parse
2318 where parse = fieldTagged $ \fn o ->
2319 RegexpQuery fn
2320 <$> o .: "value"
2321 <*> o .: "flags"
2322 <*> o .:? "boost"
2324instance ToJSON QueryStringQuery where
2325 toJSON (QueryStringQuery qsQueryString
2326 qsDefaultField qsOperator
2327 qsAnalyzer qsAllowWildcard
2328 qsLowercaseExpanded qsEnablePositionIncrements
2329 qsFuzzyMaxExpansions qsFuzziness
2330 qsFuzzyPrefixLength qsPhraseSlop
2331 qsBoost qsAnalyzeWildcard
2332 qsGeneratePhraseQueries qsMinimumShouldMatch
2333 qsLenient qsLocale) =
2334 omitNulls base
2335 where
2336 base = [ "query" .= qsQueryString
2337 , "default_field" .= qsDefaultField
2338 , "default_operator" .= qsOperator
2339 , "analyzer" .= qsAnalyzer
2340 , "allow_leading_wildcard" .= qsAllowWildcard
2341 , "lowercase_expanded_terms" .= qsLowercaseExpanded
2342 , "enable_position_increments" .= qsEnablePositionIncrements
2343 , "fuzzy_max_expansions" .= qsFuzzyMaxExpansions
2344 , "fuzziness" .= qsFuzziness
2345 , "fuzzy_prefix_length" .= qsFuzzyPrefixLength
2346 , "phrase_slop" .= qsPhraseSlop
2347 , "boost" .= qsBoost
2348 , "analyze_wildcard" .= qsAnalyzeWildcard
2349 , "auto_generate_phrase_queries" .= qsGeneratePhraseQueries
2350 , "minimum_should_match" .= qsMinimumShouldMatch
2351 , "lenient" .= qsLenient
2352 , "locale" .= qsLocale ]
2354instance FromJSON QueryStringQuery where
2355 parseJSON = withObject "QueryStringQuery" parse
2356 where parse o = QueryStringQuery
2357 <$> o .: "query"
2358 <*> o .:? "default_field"
2359 <*> o .:? "default_operator"
2360 <*> o .:? "analyzer"
2361 <*> o .:? "allow_leading_wildcard"
2362 <*> o .:? "lowercase_expanded_terms"
2363 <*> o .:? "enable_position_increments"
2364 <*> o .:? "fuzzy_max_expansions"
2365 <*> o .:? "fuzziness"
2366 <*> o .:? "fuzzy_prefix_length"
2367 <*> o .:? "phrase_slop"
2368 <*> o .:? "boost"
2369 <*> o .:? "analyze_wildcard"
2370 <*> o .:? "auto_generate_phrase_queries"
2371 <*> o .:? "minimum_should_match"
2372 <*> o .:? "lenient"
2373 <*> o .:? "locale"
2375instance ToJSON RangeQuery where
2376 toJSON (RangeQuery (FieldName fieldName) range boost) =
2377 object [ fieldName .= object conjoined ]
2378 where conjoined = [ "boost" .= boost ] ++ (rangeValueToPair range)
2380instance FromJSON RangeQuery where
2381 parseJSON = withObject "RangeQuery" parse
2382 where parse = fieldTagged $ \fn o ->
2383 RangeQuery fn
2384 <$> parseJSON (Object o)
2385 <*> o .: "boost"
2387instance FromJSON RangeValue where
2388 parseJSON = withObject "RangeValue" parse
2389 where parse o = parseDate o
2390 <|> parseDouble o
2391 parseDate o = do lt <- o .:? "lt"
2392 lte <- o .:? "lte"
2393 gt <- o .:? "gt"
2394 gte <- o .:? "gte"
2395 case (lt, lte, gt, gte) of
2396 (Just a, _, Just b, _) -> return (RangeDateGtLt (GreaterThanD b) (LessThanD a))
2397 (Just a, _, _, Just b)-> return (RangeDateGteLt (GreaterThanEqD b) (LessThanD a))
2398 (_, Just a, Just b, _)-> return (RangeDateGtLte (GreaterThanD b) (LessThanEqD a))
2399 (_, Just a, _, Just b)-> return (RangeDateGteLte (GreaterThanEqD b) (LessThanEqD a))
2400 (_, _, Just a, _)-> return (RangeDateGt (GreaterThanD a))
2401 (Just a, _, _, _)-> return (RangeDateLt (LessThanD a))
2402 (_, _, _, Just a)-> return (RangeDateGte (GreaterThanEqD a))
2403 (_, Just a, _, _)-> return (RangeDateLte (LessThanEqD a))
2404 (Nothing, Nothing, Nothing, Nothing) -> mzero
2405 parseDouble o = do lt <- o .:? "lt"
2406 lte <- o .:? "lte"
2407 gt <- o .:? "gt"
2408 gte <- o .:? "gte"
2409 case (lt, lte, gt, gte) of
2410 (Just a, _, Just b, _) -> return (RangeDoubleGtLt (GreaterThan b) (LessThan a))
2411 (Just a, _, _, Just b)-> return (RangeDoubleGteLt (GreaterThanEq b) (LessThan a))
2412 (_, Just a, Just b, _)-> return (RangeDoubleGtLte (GreaterThan b) (LessThanEq a))
2413 (_, Just a, _, Just b)-> return (RangeDoubleGteLte (GreaterThanEq b) (LessThanEq a))
2414 (_, _, Just a, _)-> return (RangeDoubleGt (GreaterThan a))
2415 (Just a, _, _, _)-> return (RangeDoubleLt (LessThan a))
2416 (_, _, _, Just a)-> return (RangeDoubleGte (GreaterThanEq a))
2417 (_, Just a, _, _)-> return (RangeDoubleLte (LessThanEq a))
2418 (Nothing, Nothing, Nothing, Nothing) -> mzero
2420instance ToJSON PrefixQuery where
2421 toJSON (PrefixQuery (FieldName fieldName) queryValue boost) =
2422 object [ fieldName .= omitNulls base ]
2423 where base = [ "value" .= queryValue
2424 , "boost" .= boost ]
2426instance FromJSON PrefixQuery where
2427 parseJSON = withObject "PrefixQuery" parse
2428 where parse = fieldTagged $ \fn o ->
2429 PrefixQuery fn
2430 <$> o .: "value"
2431 <*> o .:? "boost"
2433instance ToJSON NestedQuery where
2434 toJSON (NestedQuery nqPath nqScoreType nqQuery) =
2435 object [ "path" .= nqPath
2436 , "score_mode" .= nqScoreType
2437 , "query" .= nqQuery ]
2439instance FromJSON NestedQuery where
2440 parseJSON = withObject "NestedQuery" parse
2441 where parse o = NestedQuery
2442 <$> o .: "path"
2443 <*> o .: "score_mode"
2444 <*> o .: "query"
2446instance ToJSON MoreLikeThisFieldQuery where
2447 toJSON (MoreLikeThisFieldQuery text (FieldName fieldName)
2448 percent mtf mqt stopwords mindf maxdf
2449 minwl maxwl boostTerms boost analyzer) =
2450 object [ fieldName .= omitNulls base ]
2451 where base = [ "like_text" .= text
2452 , "percent_terms_to_match" .= percent
2453 , "min_term_freq" .= mtf
2454 , "max_query_terms" .= mqt
2455 , "stop_words" .= stopwords
2456 , "min_doc_freq" .= mindf
2457 , "max_doc_freq" .= maxdf
2458 , "min_word_length" .= minwl
2459 , "max_word_length" .= maxwl
2460 , "boost_terms" .= boostTerms
2461 , "boost" .= boost
2462 , "analyzer" .= analyzer ]
2464instance FromJSON MoreLikeThisFieldQuery where
2465 parseJSON = withObject "MoreLikeThisFieldQuery" parse
2466 where parse = fieldTagged $ \fn o ->
2467 MoreLikeThisFieldQuery
2468 <$> o .: "like_text"
2469 <*> pure fn
2470 <*> o .:? "percent_terms_to_match"
2471 <*> o .:? "min_term_freq"
2472 <*> o .:? "max_query_terms"
2473 <*> (optionalNE =<< o .:? "stop_words")
2474 <*> o .:? "min_doc_freq"
2475 <*> o .:? "max_doc_freq"
2476 <*> o .:? "min_word_length"
2477 <*> o .:? "max_word_length"
2478 <*> o .:? "boost_terms"
2479 <*> o .:? "boost"
2480 <*> o .:? "analyzer"
2481 optionalNE = maybe (pure Nothing) (fmap Just . parseNEJSON)
2483instance ToJSON MoreLikeThisQuery where
2484 toJSON (MoreLikeThisQuery text fields percent
2485 mtf mqt stopwords mindf maxdf
2486 minwl maxwl boostTerms boost analyzer) =
2487 omitNulls base
2488 where base = [ "like_text" .= text
2489 , "fields" .= fields
2490 , "percent_terms_to_match" .= percent
2491 , "min_term_freq" .= mtf
2492 , "max_query_terms" .= mqt
2493 , "stop_words" .= stopwords
2494 , "min_doc_freq" .= mindf
2495 , "max_doc_freq" .= maxdf
2496 , "min_word_length" .= minwl
2497 , "max_word_length" .= maxwl
2498 , "boost_terms" .= boostTerms
2499 , "boost" .= boost
2500 , "analyzer" .= analyzer ]
2502instance FromJSON MoreLikeThisQuery where
2503 parseJSON = withObject "MoreLikeThisQuery" parse
2504 where parse o = MoreLikeThisQuery
2505 <$> o .: "like_text"
2506 <*> (optionalNE =<< o .:? "fields")
2507 <*> o .:? "percent_terms_to_match"
2508 <*> o .:? "min_term_freq"
2509 <*> o .:? "max_query_terms"
2510 <*> (optionalNE =<< o .:? "stop_words")
2511 <*> o .:? "min_doc_freq"
2512 <*> o .:? "max_doc_freq"
2513 <*> o .:? "min_word_length"
2514 <*> o .:? "max_word_length"
2515 <*> o .:? "boost_terms"
2516 <*> o .:? "boost"
2517 <*> o .:? "analyzer"
2518 optionalNE = maybe (pure Nothing) (fmap Just . parseNEJSON)
2520instance ToJSON IndicesQuery where
2521 toJSON (IndicesQuery indices query noMatch) =
2522 omitNulls [ "indices" .= indices
2523 , "no_match_query" .= noMatch
2524 , "query" .= query ]
2526instance FromJSON IndicesQuery where
2527 parseJSON = withObject "IndicesQuery" parse
2528 where parse o = IndicesQuery
2529 <$> o .:? "indices" .!= []
2530 <*> o .: "query"
2531 <*> o .:? "no_match_query"
2533instance ToJSON HasParentQuery where
2534 toJSON (HasParentQuery queryType query scoreType) =
2535 omitNulls [ "parent_type" .= queryType
2536 , "score_type" .= scoreType
2537 , "query" .= query ]
2539instance FromJSON HasParentQuery where
2540 parseJSON = withObject "HasParentQuery" parse
2541 where parse o = HasParentQuery
2542 <$> o .: "parent_type"
2543 <*> o .: "query"
2544 <*> o .:? "score_type"
2546instance ToJSON HasChildQuery where
2547 toJSON (HasChildQuery queryType query scoreType) =
2548 omitNulls [ "query" .= query
2549 , "score_type" .= scoreType
2550 , "type" .= queryType ]
2552instance FromJSON HasChildQuery where
2553 parseJSON = withObject "HasChildQuery" parse
2554 where parse o = HasChildQuery
2555 <$> o .: "type"
2556 <*> o .: "query"
2557 <*> o .:? "score_type"
2559instance ToJSON FuzzyQuery where
2560 toJSON (FuzzyQuery (FieldName fieldName) queryText
2561 prefixLength maxEx fuzziness boost) =
2562 object [ fieldName .= omitNulls base ]
2563 where base = [ "value" .= queryText
2564 , "fuzziness" .= fuzziness
2565 , "prefix_length" .= prefixLength
2566 , "boost" .= boost
2567 , "max_expansions" .= maxEx ]
2569instance FromJSON FuzzyQuery where
2570 parseJSON = withObject "FuzzyQuery" parse
2571 where parse = fieldTagged $ \fn o ->
2572 FuzzyQuery fn
2573 <$> o .: "value"
2574 <*> o .: "prefix_length"
2575 <*> o .: "max_expansions"
2576 <*> o .: "fuzziness"
2577 <*> o .:? "boost"
2579instance ToJSON FuzzyLikeFieldQuery where
2580 toJSON (FuzzyLikeFieldQuery (FieldName fieldName)
2581 fieldText maxTerms ignoreFreq fuzziness prefixLength
2582 boost analyzer) =
2583 object [ fieldName .=
2584 omitNulls [ "like_text" .= fieldText
2585 , "max_query_terms" .= maxTerms
2586 , "ignore_tf" .= ignoreFreq
2587 , "fuzziness" .= fuzziness
2588 , "prefix_length" .= prefixLength
2589 , "analyzer" .= analyzer
2590 , "boost" .= boost ]]
2592instance FromJSON FuzzyLikeFieldQuery where
2593 parseJSON = withObject "FuzzyLikeFieldQuery" parse
2594 where parse = fieldTagged $ \fn o ->
2595 FuzzyLikeFieldQuery fn
2596 <$> o .: "like_text"
2597 <*> o .: "max_query_terms"
2598 <*> o .: "ignore_tf"
2599 <*> o .: "fuzziness"
2600 <*> o .: "prefix_length"
2601 <*> o .: "boost"
2602 <*> o .:? "analyzer"
2604instance ToJSON FuzzyLikeThisQuery where
2605 toJSON (FuzzyLikeThisQuery fields text maxTerms
2606 ignoreFreq fuzziness prefixLength boost analyzer) =
2607 omitNulls base
2608 where base = [ "fields" .= fields
2609 , "like_text" .= text
2610 , "max_query_terms" .= maxTerms
2611 , "ignore_tf" .= ignoreFreq
2612 , "fuzziness" .= fuzziness
2613 , "prefix_length" .= prefixLength
2614 , "analyzer" .= analyzer
2615 , "boost" .= boost ]
2617instance FromJSON FuzzyLikeThisQuery where
2618 parseJSON = withObject "FuzzyLikeThisQuery" parse
2619 where parse o = FuzzyLikeThisQuery
2620 <$> o .:? "fields" .!= []
2621 <*> o .: "like_text"
2622 <*> o .: "max_query_terms"
2623 <*> o .: "ignore_tf"
2624 <*> o .: "fuzziness"
2625 <*> o .: "prefix_length"
2626 <*> o .: "boost"
2627 <*> o .:? "analyzer"
2629instance ToJSON FilteredQuery where
2630 toJSON (FilteredQuery query fFilter) =
2631 object [ "query" .= query
2632 , "filter" .= fFilter ]
2634instance FromJSON FilteredQuery where
2635 parseJSON = withObject "FilteredQuery" parse
2636 where parse o = FilteredQuery
2637 <$> o .: "query"
2638 <*> o .: "filter"
2640instance ToJSON DisMaxQuery where
2641 toJSON (DisMaxQuery queries tiebreaker boost) =
2642 omitNulls base
2643 where base = [ "queries" .= queries
2644 , "boost" .= boost
2645 , "tie_breaker" .= tiebreaker ]
2647instance FromJSON DisMaxQuery where
2648 parseJSON = withObject "DisMaxQuery" parse
2649 where parse o = DisMaxQuery
2650 <$> o .:? "queries" .!= []
2651 <*> o .: "tie_breaker"
2652 <*> o .:? "boost"
2654instance ToJSON CommonTermsQuery where
2655 toJSON (CommonTermsQuery (FieldName fieldName)
2656 (QueryString query) cf lfo hfo msm
2657 boost analyzer disableCoord) =
2658 object [fieldName .= omitNulls base ]
2659 where base = [ "query" .= query
2660 , "cutoff_frequency" .= cf
2661 , "low_freq_operator" .= lfo
2662 , "minimum_should_match" .= msm
2663 , "boost" .= boost
2664 , "analyzer" .= analyzer
2665 , "disable_coord" .= disableCoord
2666 , "high_freq_operator" .= hfo ]
2668instance FromJSON CommonTermsQuery where
2669 parseJSON = withObject "CommonTermsQuery" parse
2670 where parse = fieldTagged $ \fn o ->
2671 CommonTermsQuery fn
2672 <$> o .: "query"
2673 <*> o .: "cutoff_frequency"
2674 <*> o .: "low_freq_operator"
2675 <*> o .: "high_freq_operator"
2676 <*> o .:? "minimum_should_match"
2677 <*> o .:? "boost"
2678 <*> o .:? "analyzer"
2679 <*> o .:? "disable_coord"
2681instance ToJSON CommonMinimumMatch where
2682 toJSON (CommonMinimumMatch mm) = toJSON mm
2683 toJSON (CommonMinimumMatchHighLow (MinimumMatchHighLow lowF highF)) =
2684 object [ "low_freq" .= lowF
2685 , "high_freq" .= highF ]
2687instance FromJSON CommonMinimumMatch where
2688 parseJSON v = parseMinimum v
2689 <|> parseMinimumHighLow v
2690 where parseMinimum = fmap CommonMinimumMatch . parseJSON
2691 parseMinimumHighLow = fmap CommonMinimumMatchHighLow . withObject "CommonMinimumMatchHighLow" (\o ->
2692 MinimumMatchHighLow
2693 <$> o .: "low_freq"
2694 <*> o .: "high_freq")
2697instance ToJSON BoostingQuery where
2698 toJSON (BoostingQuery bqPositiveQuery bqNegativeQuery bqNegativeBoost) =
2699 object [ "positive" .= bqPositiveQuery
2700 , "negative" .= bqNegativeQuery
2701 , "negative_boost" .= bqNegativeBoost ]
2703instance FromJSON BoostingQuery where
2704 parseJSON = withObject "BoostingQuery" parse
2705 where parse o = BoostingQuery
2706 <$> o .: "positive"
2707 <*> o .: "negative"
2708 <*> o .: "negative_boost"
2710instance ToJSON BoolQuery where
2711 toJSON (BoolQuery mustM notM shouldM bqMin boost disableCoord) =
2712 omitNulls base
2713 where base = [ "must" .= mustM
2714 , "must_not" .= notM
2715 , "should" .= shouldM
2716 , "minimum_should_match" .= bqMin
2717 , "boost" .= boost
2718 , "disable_coord" .= disableCoord ]
2720instance FromJSON BoolQuery where
2721 parseJSON = withObject "BoolQuery" parse
2722 where parse o = BoolQuery
2723 <$> o .:? "must" .!= []
2724 <*> o .:? "must_not" .!= []
2725 <*> o .:? "should" .!= []
2726 <*> o .:? "minimum_should_match"
2727 <*> o .:? "boost"
2728 <*> o .:? "disable_coord"
2730instance ToJSON MatchQuery where
2731 toJSON (MatchQuery (FieldName fieldName)
2732 (QueryString mqQueryString) booleanOperator
2733 zeroTermsQuery cutoffFrequency matchQueryType
2734 analyzer maxExpansions lenient boost) =
2735 object [ fieldName .= omitNulls base ]
2736 where base = [ "query" .= mqQueryString
2737 , "operator" .= booleanOperator
2738 , "zero_terms_query" .= zeroTermsQuery
2739 , "cutoff_frequency" .= cutoffFrequency
2740 , "type" .= matchQueryType
2741 , "analyzer" .= analyzer
2742 , "max_expansions" .= maxExpansions
2743 , "lenient" .= lenient
2744 , "boost" .= boost ]
2746instance FromJSON MatchQuery where
2747 parseJSON = withObject "MatchQuery" parse
2748 where parse = fieldTagged $ \fn o ->
2749 MatchQuery fn
2750 <$> o .: "query"
2751 <*> o .: "operator"
2752 <*> o .: "zero_terms_query"
2753 <*> o .:? "cutoff_frequency"
2754 <*> o .:? "type"
2755 <*> o .:? "analyzer"
2756 <*> o .:? "max_expansions"
2757 <*> o .:? "lenient"
2758 <*> o .:? "boost"
2760instance ToJSON MultiMatchQuery where
2761 toJSON (MultiMatchQuery fields (QueryString query) boolOp
2762 ztQ tb mmqt cf analyzer maxEx lenient) =
2763 object ["multi_match" .= omitNulls base]
2764 where base = [ "fields" .= fmap toJSON fields
2765 , "query" .= query
2766 , "operator" .= boolOp
2767 , "zero_terms_query" .= ztQ
2768 , "tiebreaker" .= tb
2769 , "type" .= mmqt
2770 , "cutoff_frequency" .= cf
2771 , "analyzer" .= analyzer
2772 , "max_expansions" .= maxEx
2773 , "lenient" .= lenient ]
2775instance FromJSON MultiMatchQuery where
2776 parseJSON = withObject "MultiMatchQuery" parse
2777 where parse raw = do o <- raw .: "multi_match"
2778 MultiMatchQuery
2779 <$> o .:? "fields" .!= []
2780 <*> o .: "query"
2781 <*> o .: "operator"
2782 <*> o .: "zero_terms_query"
2783 <*> o .:? "tiebreaker"
2784 <*> o .:? "type"
2785 <*> o .:? "cutoff_frequency"
2786 <*> o .:? "analyzer"
2787 <*> o .:? "max_expansions"
2788 <*> o .:? "lenient"
2790instance ToJSON MultiMatchQueryType where
2791 toJSON MultiMatchBestFields = "best_fields"
2792 toJSON MultiMatchMostFields = "most_fields"
2793 toJSON MultiMatchCrossFields = "cross_fields"
2794 toJSON MultiMatchPhrase = "phrase"
2795 toJSON MultiMatchPhrasePrefix = "phrase_prefix"
2797instance FromJSON MultiMatchQueryType where
2798 parseJSON = withText "MultiMatchPhrasePrefix" parse
2799 where parse "best_fields" = pure MultiMatchBestFields
2800 parse "most_fields" = pure MultiMatchMostFields
2801 parse "cross_fields" = pure MultiMatchCrossFields
2802 parse "phrase" = pure MultiMatchPhrase
2803 parse "phrase_prefix" = pure MultiMatchPhrasePrefix
2804 parse t = fail ("Unexpected MultiMatchPhrasePrefix: " <> show t)
2806instance ToJSON BooleanOperator where
2807 toJSON And = String "and"
2808 toJSON Or = String "or"
2810instance FromJSON BooleanOperator where
2811 parseJSON = withText "BooleanOperator" parse
2812 where parse "and" = pure And
2813 parse "or" = pure Or
2814 parse o = fail ("Unexpected BooleanOperator: " <> show o)
2816instance ToJSON ZeroTermsQuery where
2817 toJSON ZeroTermsNone = String "none"
2818 toJSON ZeroTermsAll = String "all"
2820instance FromJSON ZeroTermsQuery where
2821 parseJSON = withText "ZeroTermsQuery" parse
2822 where parse "none" = pure ZeroTermsNone
2823 parse "all" = pure ZeroTermsAll
2824 parse q = fail ("Unexpected ZeroTermsQuery: " <> show q)
2826instance ToJSON MatchQueryType where
2827 toJSON MatchPhrase = "phrase"
2828 toJSON MatchPhrasePrefix = "phrase_prefix"
2830instance FromJSON MatchQueryType where
2831 parseJSON = withText "MatchQueryType" parse
2832 where parse "phrase" = pure MatchPhrase
2833 parse "phrase_prefix" = pure MatchPhrasePrefix
2834 parse t = fail ("Unexpected MatchQueryType: " <> show t)
2836instance FromJSON Status where
2837 parseJSON (Object v) = Status <$>
2838 v .:? "ok" <*>
2839 v .: "status" <*>
2840 v .: "name" <*>
2841 v .: "version" <*>
2842 v .: "tagline"
2843 parseJSON _ = empty
2846instance ToJSON IndexSettings where
2847 toJSON (IndexSettings s r) = object ["settings" .=
2848 object ["index" .=
2849 object ["number_of_shards" .= s, "number_of_replicas" .= r]
2853instance FromJSON IndexSettings where
2854 parseJSON = withObject "IndexSettings" parse
2855 where parse o = do s <- o .: "settings"
2856 i <- s .: "index"
2857 IndexSettings <$> i .: "number_of_shards"
2858 <*> i .: "number_of_replicas"
2860instance ToJSON UpdatableIndexSetting where
2861 toJSON (NumberOfReplicas x) = oPath ("index" :| ["number_of_replicas"]) x
2862 toJSON (AutoExpandReplicas x) = oPath ("index" :| ["auto_expand_replicas"]) x
2863 toJSON (RefreshInterval x) = oPath ("index" :| ["refresh_interval"]) (NominalDiffTimeJSON x)
2864 toJSON (IndexConcurrency x) = oPath ("index" :| ["concurrency"]) x
2865 toJSON (FailOnMergeFailure x) = oPath ("index" :| ["fail_on_merge_failure"]) x
2866 toJSON (TranslogFlushThresholdOps x) = oPath ("index" :| ["translog", "flush_threshold_ops"]) x
2867 toJSON (TranslogFlushThresholdSize x) = oPath ("index" :| ["translog", "flush_threshold_size"]) x
2868 toJSON (TranslogFlushThresholdPeriod x) = oPath ("index" :| ["translog", "flush_threshold_period"]) (NominalDiffTimeJSON x)
2869 toJSON (TranslogDisableFlush x) = oPath ("index" :| ["translog", "disable_flush"]) x
2870 toJSON (CacheFilterMaxSize x) = oPath ("index" :| ["cache", "filter", "max_size"]) x
2871 toJSON (CacheFilterExpire x) = oPath ("index" :| ["cache", "filter", "expire"]) (NominalDiffTimeJSON <$> x)
2872 toJSON (GatewaySnapshotInterval x) = oPath ("index" :| ["gateway", "snapshot_interval"]) (NominalDiffTimeJSON x)
2873 toJSON (RoutingAllocationInclude fs) = oPath ("index" :| ["routing", "allocation", "include"]) (attrFilterJSON fs)
2874 toJSON (RoutingAllocationExclude fs) = oPath ("index" :| ["routing", "allocation", "exclude"]) (attrFilterJSON fs)
2875 toJSON (RoutingAllocationRequire fs) = oPath ("index" :| ["routing", "allocation", "require"]) (attrFilterJSON fs)
2876 toJSON (RoutingAllocationEnable x) = oPath ("index" :| ["routing", "allocation", "enable"]) x
2877 toJSON (RoutingAllocationShardsPerNode x) = oPath ("index" :| ["routing", "allocation", "total_shards_per_node"]) x
2878 toJSON (RecoveryInitialShards x) = oPath ("index" :| ["recovery", "initial_shards"]) x
2879 toJSON (GCDeletes x) = oPath ("index" :| ["gc_deletes"]) (NominalDiffTimeJSON x)
2880 toJSON (TTLDisablePurge x) = oPath ("index" :| ["ttl", "disable_purge"]) x
2881 toJSON (TranslogFSType x) = oPath ("index" :| ["translog", "fs", "type"]) x
2882 toJSON (IndexCompoundFormat x) = oPath ("index" :| ["compound_format"]) x
2883 toJSON (IndexCompoundOnFlush x) = oPath ("index" :| ["compound_on_flush"]) x
2884 toJSON (WarmerEnabled x) = oPath ("index" :| ["warmer", "enabled"]) x
2885 toJSON (BlocksReadOnly x) = oPath ("blocks" :| ["read_only"]) x
2886 toJSON (BlocksRead x) = oPath ("blocks" :| ["read"]) x
2887 toJSON (BlocksWrite x) = oPath ("blocks" :| ["write"]) x
2888 toJSON (BlocksMetaData x) = oPath ("blocks" :| ["metadata"]) x
2890instance FromJSON UpdatableIndexSetting where
2891 parseJSON = withObject "UpdatableIndexSetting" parse
2892 where parse o = numberOfReplicas `taggedAt` ["index", "number_of_replicas"]
2893 <|> autoExpandReplicas `taggedAt` ["index", "auto_expand_replicas"]
2894 <|> refreshInterval `taggedAt` ["index", "refresh_interval"]
2895 <|> indexConcurrency `taggedAt` ["index", "concurrency"]
2896 <|> failOnMergeFailure `taggedAt` ["index", "fail_on_merge_failure"]
2897 <|> translogFlushThresholdOps `taggedAt` ["index", "translog", "flush_threshold_ops"]
2898 <|> translogFlushThresholdSize `taggedAt` ["index", "translog", "flush_threshold_size"]
2899 <|> translogFlushThresholdPeriod `taggedAt` ["index", "translog", "flush_threshold_period"]
2900 <|> translogDisableFlush `taggedAt` ["index", "translog", "disable_flush"]
2901 <|> cacheFilterMaxSize `taggedAt` ["index", "cache", "filter", "max_size"]
2902 <|> cacheFilterExpire `taggedAt` ["index", "cache", "filter", "expire"]
2903 <|> gatewaySnapshotInterval `taggedAt` ["index", "gateway", "snapshot_interval"]
2904 <|> routingAllocationInclude `taggedAt` ["index", "routing", "allocation", "include"]
2905 <|> routingAllocationExclude `taggedAt` ["index", "routing", "allocation", "exclude"]
2906 <|> routingAllocationRequire `taggedAt` ["index", "routing", "allocation", "require"]
2907 <|> routingAllocationEnable `taggedAt` ["index", "routing", "allocation", "enable"]
2908 <|> routingAllocationShardsPerNode `taggedAt` ["index", "routing", "allocation", "total_shards_per_node"]
2909 <|> recoveryInitialShards `taggedAt` ["index", "recovery", "initial_shards"]
2910 <|> gcDeletes `taggedAt` ["index", "gc_deletes"]
2911 <|> ttlDisablePurge `taggedAt` ["index", "ttl", "disable_purge"]
2912 <|> translogFSType `taggedAt` ["index", "translog", "fs", "type"]
2913 <|> compoundFormat `taggedAt` ["index", "compound_format"]
2914 <|> compoundOnFlush `taggedAt` ["index", "compound_on_flush"]
2915 <|> warmerEnabled `taggedAt` ["index", "warmer", "enabled"]
2916 <|> blocksReadOnly `taggedAt` ["blocks", "read_only"]
2917 <|> blocksRead `taggedAt` ["blocks", "read"]
2918 <|> blocksWrite `taggedAt` ["blocks", "write"]
2919 <|> blocksMetaData `taggedAt` ["blocks", "metadata"]
2920 where taggedAt f ks = taggedAt' f (Object o) ks
2921 taggedAt' f v [] = f =<< (parseJSON v <|> (parseJSON =<< unStringlyTypeJSON v))
2922 taggedAt' f v (k:ks) = withObject "Object" (\o -> do v' <- o .: k
2923 taggedAt' f v' ks) v
2924 numberOfReplicas = pure . NumberOfReplicas
2925 autoExpandReplicas = pure . AutoExpandReplicas
2926 refreshInterval = pure . RefreshInterval . ndtJSON
2927 indexConcurrency = pure . IndexConcurrency
2928 failOnMergeFailure = pure . FailOnMergeFailure
2929 translogFlushThresholdOps = pure . TranslogFlushThresholdOps
2930 translogFlushThresholdSize = pure . TranslogFlushThresholdSize
2931 translogFlushThresholdPeriod = pure . TranslogFlushThresholdPeriod . ndtJSON
2932 translogDisableFlush = pure . TranslogDisableFlush
2933 cacheFilterMaxSize = pure . CacheFilterMaxSize
2934 cacheFilterExpire = pure . CacheFilterExpire . fmap ndtJSON
2935 gatewaySnapshotInterval = pure . GatewaySnapshotInterval . ndtJSON
2936 routingAllocationInclude = fmap RoutingAllocationInclude . parseAttrFilter
2937 routingAllocationExclude = fmap RoutingAllocationExclude . parseAttrFilter
2938 routingAllocationRequire = fmap RoutingAllocationRequire . parseAttrFilter
2939 routingAllocationEnable = pure . RoutingAllocationEnable
2940 routingAllocationShardsPerNode = pure . RoutingAllocationShardsPerNode
2941 recoveryInitialShards = pure . RecoveryInitialShards
2942 gcDeletes = pure . GCDeletes . ndtJSON
2943 ttlDisablePurge = pure . TTLDisablePurge
2944 translogFSType = pure . TranslogFSType
2945 compoundFormat = pure . IndexCompoundFormat
2946 compoundOnFlush = pure . IndexCompoundOnFlush
2947 warmerEnabled = pure . WarmerEnabled
2948 blocksReadOnly = pure . BlocksReadOnly
2949 blocksRead = pure . BlocksRead
2950 blocksWrite = pure . BlocksWrite
2951 blocksMetaData = pure . BlocksMetaData
2953instance FromJSON IndexSettingsSummary where
2954 parseJSON = withObject "IndexSettingsSummary" parse
2955 where parse o = case HM.toList o of
2956 [(ixn, v@(Object o'))] -> IndexSettingsSummary (IndexName ixn)
2957 <$> parseJSON v
2958 <*> (fmap (filter (not . redundant)) . parseSettings =<< o' .: "settings")
2959 _ -> fail "Expected single-key object with index name"
2960 redundant (NumberOfReplicas _) = True
2961 redundant _ = False
2963-- | For some reason in the settings API, all leaf values get returned
2964-- as strings. This function attepmts to recover from this for all
2965-- non-recursive JSON types. If nothing can be done or the same value
2966-- would be return, it returns 'mzero'
2967unStringlyTypeJSON :: MonadPlus m => Value -> m Value
2968unStringlyTypeJSON (String "true") = return (Bool True)
2969unStringlyTypeJSON (String "false") = return (Bool False)
2970unStringlyTypeJSON (String "null") = return Null
2971unStringlyTypeJSON (String t) = case readMay (T.unpack t) of
2972 Just n -> return (Number n)
2973 Nothing -> mzero
2974unStringlyTypeJSON _ = mzero
2977parseSettings :: Object -> Parser [UpdatableIndexSetting]
2978parseSettings o = do
2979 o' <- o .: "index"
2980 -- slice the index object into singleton hashmaps and try to parse each
2981 parses <- forM (HM.toList o') $ \(k, v) -> do
2982 -- blocks are now nested into the "index" key, which is not how they're serialized
2983 let atRoot = Object (HM.singleton k v)
2984 let atIndex = Object (HM.singleton "index" atRoot)
2985 optional (parseJSON atRoot <|> parseJSON atIndex)
2986 return (catMaybes parses)
2988oPath :: ToJSON a => NonEmpty Text -> a -> Value
2989oPath (k :| []) v = object [k .= v]
2990oPath (k:| (h:t)) v = object [k .= oPath (h :| t) v]
2992attrFilterJSON :: NonEmpty NodeAttrFilter -> Value
2993attrFilterJSON fs = object [ n .= T.intercalate "," (toList vs)
2994 | NodeAttrFilter (NodeAttrName n) vs <- toList fs]
2996parseAttrFilter :: Value -> Parser (NonEmpty NodeAttrFilter)
2997parseAttrFilter = withObject "NonEmpty NodeAttrFilter" parse
2998 where parse o = case HM.toList o of
2999 [] -> fail "Expected non-empty list of NodeAttrFilters"
3000 x:xs -> DT.mapM (uncurry parse') (x :| xs)
3001 parse' n = withText "Text" $ \t ->
3002 case T.splitOn "," t of
3003 fv:fvs -> return (NodeAttrFilter (NodeAttrName n) (fv :| fvs))
3004 [] -> fail "Expected non-empty list of filter values"
3006instance ToJSON ReplicaBounds where
3007 toJSON (ReplicasBounded a b) = String (showText a <> "-" <> showText b)
3008 toJSON (ReplicasLowerBounded a) = String (showText a <> "-all")
3009 toJSON ReplicasUnbounded = Bool False
3011instance FromJSON ReplicaBounds where
3012 parseJSON v = withText "ReplicaBounds" parseText v
3013 <|> withBool "ReplicaBounds" parseBool v
3014 where parseText t = case T.splitOn "-" t of
3015 [a, "all"] -> ReplicasLowerBounded <$> parseReadText a
3016 [a, b] -> ReplicasBounded <$> parseReadText a
3017 <*> parseReadText b
3018 _ -> fail ("Could not parse ReplicaBounds: " <> show t)
3019 parseBool False = pure ReplicasUnbounded
3020 parseBool _ = fail "ReplicasUnbounded cannot be represented with True"
3022instance ToJSON AllocationPolicy where
3023 toJSON AllocAll = String "all"
3024 toJSON AllocPrimaries = String "primaries"
3025 toJSON AllocNewPrimaries = String "new_primaries"
3026 toJSON AllocNone = String "none"
3028instance FromJSON AllocationPolicy where
3029 parseJSON = withText "AllocationPolicy" parse
3030 where parse "all" = pure AllocAll
3031 parse "primaries" = pure AllocPrimaries
3032 parse "new_primaries" = pure AllocNewPrimaries
3033 parse "none" = pure AllocNone
3034 parse t = fail ("Invlaid AllocationPolicy: " <> show t)
3036instance ToJSON InitialShardCount where
3037 toJSON QuorumShards = String "quorum"
3038 toJSON QuorumMinus1Shards = String "quorum-1"
3039 toJSON FullShards = String "full"
3040 toJSON FullMinus1Shards = String "full-1"
3041 toJSON (ExplicitShards x) = toJSON x
3043instance FromJSON InitialShardCount where
3044 parseJSON v = withText "InitialShardCount" parseText v
3045 <|> ExplicitShards <$> parseJSON v
3046 where parseText "quorum" = pure QuorumShards
3047 parseText "quorum-1" = pure QuorumMinus1Shards
3048 parseText "full" = pure FullShards
3049 parseText "full-1" = pure FullMinus1Shards
3050 parseText _ = mzero
3052instance ToJSON FSType where
3053 toJSON FSSimple = "simple"
3054 toJSON FSBuffered = "buffered"
3056instance FromJSON FSType where
3057 parseJSON = withText "FSType" parse
3058 where parse "simple" = pure FSSimple
3059 parse "buffered" = pure FSBuffered
3060 parse t = fail ("Invalid FSType: " <> show t)
3062instance ToJSON CompoundFormat where
3063 toJSON (CompoundFileFormat x) = Bool x
3064 toJSON (MergeSegmentVsTotalIndex x) = toJSON x
3066instance FromJSON CompoundFormat where
3067 parseJSON v = CompoundFileFormat <$> parseJSON v
3068 <|> MergeSegmentVsTotalIndex <$> parseJSON v
3070instance ToJSON NominalDiffTimeJSON where
3071 toJSON (NominalDiffTimeJSON t) = String (showText (round t :: Integer) <> "s")
3073instance FromJSON NominalDiffTimeJSON where
3074 parseJSON = withText "NominalDiffTime" parse
3075 where parse t = case T.takeEnd 1 t of
3076 "s" -> NominalDiffTimeJSON . fromInteger <$> parseReadText (T.dropEnd 1 t)
3077 _ -> fail "Invalid or missing NominalDiffTime unit (expected s)"
3079instance ToJSON IndexTemplate where
3080 toJSON (IndexTemplate p s m) = merge
3081 (object [ "template" .= p
3082 , "mappings" .= foldl' merge (object []) m
3083 ])
3084 (toJSON s)
3085 where
3086 merge (Object o1) (Object o2) = toJSON $ HM.union o1 o2
3087 merge o Null = o
3088 merge _ _ = undefined
3090instance (FromJSON a) => FromJSON (EsResult a) where
3091 parseJSON jsonVal@(Object v) = do
3092 found <- v .:? "found" .!= False
3093 fr <- if found
3094 then parseJSON jsonVal
3095 else return Nothing
3096 EsResult <$> v .: "_index" <*>
3097 v .: "_type" <*>
3098 v .: "_id" <*>
3099 pure fr
3100 parseJSON _ = empty
3102instance (FromJSON a) => FromJSON (EsResultFound a) where
3103 parseJSON (Object v) = EsResultFound <$>
3104 v .: "_version" <*>
3105 v .: "_source"
3106 parseJSON _ = empty
3108instance FromJSON EsError where
3109 parseJSON (Object v) = EsError <$>
3110 v .: "status" <*>
3111 v .: "error"
3112 parseJSON _ = empty
3114instance FromJSON IndexAliasesSummary where
3115 parseJSON = withObject "IndexAliasesSummary" parse
3116 where parse o = IndexAliasesSummary . mconcat <$> mapM (uncurry go) (HM.toList o)
3117 go ixn = withObject "index aliases" $ \ia -> do
3118 aliases <- ia .:? "aliases" .!= mempty
3119 forM (HM.toList aliases) $ \(aName, v) -> do
3120 let indexAlias = IndexAlias (IndexName ixn) (IndexAliasName (IndexName aName))
3121 IndexAliasSummary indexAlias <$> parseJSON v
3124instance ToJSON IndexAliasAction where
3125 toJSON (AddAlias ia opts) = object ["add" .= (iaObj <> optsObj)]
3126 where Object iaObj = toJSON ia
3127 Object optsObj = toJSON opts
3128 toJSON (RemoveAlias ia) = object ["remove" .= iaObj]
3129 where Object iaObj = toJSON ia
3131instance ToJSON IndexAlias where
3132 toJSON IndexAlias {..} = object ["index" .= srcIndex
3133 , "alias" .= indexAlias
3136instance ToJSON IndexAliasCreate where
3137 toJSON IndexAliasCreate {..} = Object (filterObj <> routingObj)
3138 where filterObj = maybe mempty (HM.singleton "filter" . toJSON) aliasCreateFilter
3139 Object routingObj = maybe (Object mempty) toJSON aliasCreateRouting
3141instance ToJSON AliasRouting where
3142 toJSON (AllAliasRouting v) = object ["routing" .= v]
3143 toJSON (GranularAliasRouting srch idx) = object (catMaybes prs)
3144 where prs = [("search_routing" .=) <$> srch
3145 ,("index_routing" .=) <$> idx]
3147instance FromJSON AliasRouting where
3148 parseJSON = withObject "AliasRouting" parse
3149 where parse o = parseAll o <|> parseGranular o
3150 parseAll o = AllAliasRouting <$> o .: "routing"
3151 parseGranular o = do
3152 sr <- o .:? "search_routing"
3153 ir <- o .:? "index_routing"
3154 if isNothing sr && isNothing ir
3155 then fail "Both search_routing and index_routing can't be blank"
3156 else return (GranularAliasRouting sr ir)
3158instance FromJSON IndexAliasCreate where
3159 parseJSON v = withObject "IndexAliasCreate" parse v
3160 where parse o = IndexAliasCreate <$> optional (parseJSON v)
3161 <*> o .:? "filter"
3163instance ToJSON SearchAliasRouting where
3164 toJSON (SearchAliasRouting rvs) = toJSON (T.intercalate "," (routingValue <$> toList rvs))
3166instance FromJSON SearchAliasRouting where
3167 parseJSON = withText "SearchAliasRouting" parse
3168 where parse t = SearchAliasRouting <$> parseNEJSON (String <$> T.splitOn "," t)
3170instance ToJSON Search where
3171 toJSON (Search query sFilter sort searchAggs highlight sTrackSortScores sFrom sSize _ sFields sSource) =
3172 omitNulls [ "query" .= query
3173 , "filter" .= sFilter
3174 , "sort" .= sort
3175 , "aggregations" .= searchAggs
3176 , "highlight" .= highlight
3177 , "from" .= sFrom
3178 , "size" .= sSize
3179 , "track_scores" .= sTrackSortScores
3180 , "fields" .= sFields
3181 , "_source" .= sSource]
3184instance ToJSON Source where
3185 toJSON NoSource = toJSON False
3186 toJSON (SourcePatterns patterns) = toJSON patterns
3187 toJSON (SourceIncludeExclude incl excl) = object [ "include" .= incl, "exclude" .= excl ]
3189instance ToJSON PatternOrPatterns where
3190 toJSON (PopPattern pattern) = toJSON pattern
3191 toJSON (PopPatterns patterns) = toJSON patterns
3193instance ToJSON Include where
3194 toJSON (Include patterns) = toJSON patterns
3196instance ToJSON Exclude where
3197 toJSON (Exclude patterns) = toJSON patterns
3199instance ToJSON Pattern where
3200 toJSON (Pattern pattern) = toJSON pattern
3203instance ToJSON FieldHighlight where
3204 toJSON (FieldHighlight (FieldName fName) (Just fSettings)) =
3205 object [ fName .= fSettings ]
3206 toJSON (FieldHighlight (FieldName fName) Nothing) =
3207 object [ fName .= emptyObject ]
3209instance ToJSON Highlights where
3210 toJSON (Highlights global fields) =
3211 omitNulls (("fields" .= fields)
3212 : highlightSettingsPairs global)
3214instance ToJSON HighlightSettings where
3215 toJSON hs = omitNulls (highlightSettingsPairs (Just hs))
3217highlightSettingsPairs :: Maybe HighlightSettings -> [Pair]
3218highlightSettingsPairs Nothing = []
3219highlightSettingsPairs (Just (Plain plh)) = plainHighPairs (Just plh)
3220highlightSettingsPairs (Just (Postings ph)) = postHighPairs (Just ph)
3221highlightSettingsPairs (Just (FastVector fvh)) = fastVectorHighPairs (Just fvh)
3224plainHighPairs :: Maybe PlainHighlight -> [Pair]
3225plainHighPairs Nothing = []
3226plainHighPairs (Just (PlainHighlight plCom plNonPost)) =
3227 [ "type" .= String "plain"]
3228 ++ commonHighlightPairs plCom
3229 ++ nonPostingsToPairs plNonPost
3231postHighPairs :: Maybe PostingsHighlight -> [Pair]
3232postHighPairs Nothing = []
3233postHighPairs (Just (PostingsHighlight pCom)) =
3234 ("type" .= String "postings")
3235 : commonHighlightPairs pCom
3237fastVectorHighPairs :: Maybe FastVectorHighlight -> [Pair]
3238fastVectorHighPairs Nothing = []
3239fastVectorHighPairs (Just
3240 (FastVectorHighlight fvCom fvNonPostSettings fvBoundChars
3241 fvBoundMaxScan fvFragOff fvMatchedFields
3242 fvPhraseLim)) =
3243 [ "type" .= String "fvh"
3244 , "boundary_chars" .= fvBoundChars
3245 , "boundary_max_scan" .= fvBoundMaxScan
3246 , "fragment_offset" .= fvFragOff
3247 , "matched_fields" .= fvMatchedFields
3248 , "phraseLimit" .= fvPhraseLim]
3249 ++ commonHighlightPairs fvCom
3250 ++ nonPostingsToPairs fvNonPostSettings
3252deleteSeveral :: (Eq k, Hashable k) => [k] -> HM.HashMap k v -> HM.HashMap k v
3253deleteSeveral ks hm = foldr HM.delete hm ks
3255commonHighlightPairs :: Maybe CommonHighlight -> [Pair]
3256commonHighlightPairs Nothing = []
3257commonHighlightPairs (Just (CommonHighlight chScore chForceSource chTag chEncoder
3258 chNoMatchSize chHighlightQuery
3259 chRequireFieldMatch)) =
3260 [ "order" .= chScore
3261 , "force_source" .= chForceSource
3262 , "encoder" .= chEncoder
3263 , "no_match_size" .= chNoMatchSize
3264 , "highlight_query" .= chHighlightQuery
3265 , "require_fieldMatch" .= chRequireFieldMatch]
3266 ++ highlightTagToPairs chTag
3269nonPostingsToPairs :: Maybe NonPostings -> [Pair]
3270nonPostingsToPairs Nothing = []
3271nonPostingsToPairs (Just (NonPostings npFragSize npNumOfFrags)) =
3272 [ "fragment_size" .= npFragSize
3273 , "number_of_fragments" .= npNumOfFrags]
3275parseNEJSON :: (FromJSON a) => [Value] -> Parser (NonEmpty a)
3276parseNEJSON [] = fail "Expected non-empty list"
3277parseNEJSON (x:xs) = DT.mapM parseJSON (x :| xs)
3280instance ToJSON HighlightEncoder where
3281 toJSON DefaultEncoder = String "default"
3282 toJSON HTMLEncoder = String "html"
3284highlightTagToPairs :: Maybe HighlightTag -> [Pair]
3285highlightTagToPairs (Just (TagSchema _)) = [ "scheme" .= String "default"]
3286highlightTagToPairs (Just (CustomTags (pre, post))) = [ "pre_tags" .= pre
3287 , "post_tags" .= post]
3288highlightTagToPairs Nothing = []
3290instance ToJSON SortSpec where
3291 toJSON (DefaultSortSpec
3292 (DefaultSort (FieldName dsSortFieldName) dsSortOrder dsIgnoreUnmapped
3293 dsSortMode dsMissingSort dsNestedFilter)) =
3294 object [dsSortFieldName .= omitNulls base] where
3295 base = [ "order" .= dsSortOrder
3296 , "ignore_unmapped" .= dsIgnoreUnmapped
3297 , "mode" .= dsSortMode
3298 , "missing" .= dsMissingSort
3299 , "nested_filter" .= dsNestedFilter ]
3301 toJSON (GeoDistanceSortSpec gdsSortOrder (GeoPoint (FieldName field) gdsLatLon) units) =
3302 object [ "unit" .= units
3303 , field .= gdsLatLon
3304 , "order" .= gdsSortOrder ]
3307instance ToJSON SortOrder where
3308 toJSON Ascending = String "asc"
3309 toJSON Descending = String "desc"
3312instance ToJSON SortMode where
3313 toJSON SortMin = String "min"
3314 toJSON SortMax = String "max"
3315 toJSON SortSum = String "sum"
3316 toJSON SortAvg = String "avg"
3319instance ToJSON Missing where
3320 toJSON LastMissing = String "_last"
3321 toJSON FirstMissing = String "_first"
3322 toJSON (CustomMissing txt) = String txt
3325instance ToJSON ScoreType where
3326 toJSON ScoreTypeMax = "max"
3327 toJSON ScoreTypeAvg = "avg"
3328 toJSON ScoreTypeSum = "sum"
3329 toJSON ScoreTypeNone = "none"
3331instance FromJSON ScoreType where
3332 parseJSON = withText "ScoreType" parse
3333 where parse "max" = pure ScoreTypeMax
3334 parse "avg" = pure ScoreTypeAvg
3335 parse "sum" = pure ScoreTypeSum
3336 parse "none" = pure ScoreTypeNone
3337 parse t = fail ("Unexpected ScoreType: " <> show t)
3339instance ToJSON Distance where
3340 toJSON (Distance dCoefficient dUnit) =
3341 String boltedTogether where
3342 coefText = showText dCoefficient
3343 (String unitText) = toJSON dUnit
3344 boltedTogether = mappend coefText unitText
3346instance FromJSON Distance where
3347 parseJSON = withText "Distance" parse
3348 where parse t = Distance <$> parseCoeff nT
3349 <*> parseJSON (String unitT)
3350 where (nT, unitT) = T.span validForNumber t
3351 -- may be a better way to do this
3352 validForNumber '-' = True
3353 validForNumber '.' = True
3354 validForNumber 'e' = True
3355 validForNumber c = isNumber c
3356 parseCoeff "" = fail "Empty string cannot be parsed as number"
3357 parseCoeff s = return (read (T.unpack s))
3359instance ToJSON DistanceUnit where
3360 toJSON Miles = String "mi"
3361 toJSON Yards = String "yd"
3362 toJSON Feet = String "ft"
3363 toJSON Inches = String "in"
3364 toJSON Kilometers = String "km"
3365 toJSON Meters = String "m"
3366 toJSON Centimeters = String "cm"
3367 toJSON Millimeters = String "mm"
3368 toJSON NauticalMiles = String "nmi"
3371instance FromJSON DistanceUnit where
3372 parseJSON = withText "DistanceUnit" parse
3373 where parse "mi" = pure Miles
3374 parse "yd" = pure Yards
3375 parse "ft" = pure Feet
3376 parse "in" = pure Inches
3377 parse "km" = pure Kilometers
3378 parse "m" = pure Meters
3379 parse "cm" = pure Centimeters
3380 parse "mm" = pure Millimeters
3381 parse "nmi" = pure NauticalMiles
3382 parse u = fail ("Unrecognized DistanceUnit: " <> show u)
3384instance ToJSON DistanceType where
3385 toJSON Arc = String "arc"
3386 toJSON SloppyArc = String "sloppy_arc"
3387 toJSON Plane = String "plane"
3389instance FromJSON DistanceType where
3390 parseJSON = withText "DistanceType" parse
3391 where parse "arc" = pure Arc
3392 parse "sloppy_arc" = pure SloppyArc
3393 parse "plane" = pure Plane
3394 parse t = fail ("Unrecognized DistanceType: " <> show t)
3397instance ToJSON OptimizeBbox where
3398 toJSON NoOptimizeBbox = String "none"
3399 toJSON (OptimizeGeoFilterType gft) = toJSON gft
3401instance FromJSON OptimizeBbox where
3402 parseJSON v = withText "NoOptimizeBbox" parseNoOptimize v
3403 <|> parseOptimize v
3404 where parseNoOptimize "none" = pure NoOptimizeBbox
3405 parseNoOptimize _ = mzero
3406 parseOptimize = fmap OptimizeGeoFilterType . parseJSON
3408instance ToJSON GeoBoundingBoxConstraint where
3409 toJSON (GeoBoundingBoxConstraint
3410 (FieldName gbbcGeoBBField) gbbcConstraintBox cache type') =
3411 object [gbbcGeoBBField .= gbbcConstraintBox
3412 , "_cache" .= cache
3413 , "type" .= type']
3415instance FromJSON GeoBoundingBoxConstraint where
3416 parseJSON = withObject "GeoBoundingBoxConstraint" parse
3417 where parse o = case HM.toList (deleteSeveral ["type", "_cache"] o) of
3418 [(fn, v)] -> GeoBoundingBoxConstraint (FieldName fn)
3419 <$> parseJSON v
3420 <*> o .:? "_cache" .!= defaultCache
3421 <*> o .: "type"
3422 _ -> fail "Could not find field name for GeoBoundingBoxConstraint"
3424instance ToJSON GeoFilterType where
3425 toJSON GeoFilterMemory = String "memory"
3426 toJSON GeoFilterIndexed = String "indexed"
3428instance FromJSON GeoFilterType where
3429 parseJSON = withText "GeoFilterType" parse
3430 where parse "memory" = pure GeoFilterMemory
3431 parse "indexed" = pure GeoFilterIndexed
3432 parse t = fail ("Unrecognized GeoFilterType: " <> show t)
3434instance ToJSON GeoBoundingBox where
3435 toJSON (GeoBoundingBox gbbTopLeft gbbBottomRight) =
3436 object ["top_left" .= gbbTopLeft
3437 , "bottom_right" .= gbbBottomRight]
3439instance FromJSON GeoBoundingBox where
3440 parseJSON = withObject "GeoBoundingBox" parse
3441 where parse o = GeoBoundingBox
3442 <$> o .: "top_left"
3443 <*> o .: "bottom_right"
3445instance ToJSON LatLon where
3446 toJSON (LatLon lLat lLon) =
3447 object ["lat" .= lLat
3448 , "lon" .= lLon]
3450instance FromJSON LatLon where
3451 parseJSON = withObject "LatLon" parse
3452 where parse o = LatLon <$> o .: "lat"
3453 <*> o .: "lon"
3455-- index for smaller ranges, fielddata for longer ranges
3456instance ToJSON RangeExecution where
3457 toJSON RangeExecutionIndex = "index"
3458 toJSON RangeExecutionFielddata = "fielddata"
3461instance FromJSON RangeExecution where
3462 parseJSON = withText "RangeExecution" parse
3463 where parse "index" = pure RangeExecutionIndex
3464 parse "fielddata" = pure RangeExecutionFielddata
3465 parse t = error ("Unrecognized RangeExecution " <> show t)
3467instance ToJSON RegexpFlags where
3468 toJSON AllRegexpFlags = String "ALL"
3469 toJSON NoRegexpFlags = String "NONE"
3470 toJSON (SomeRegexpFlags (h :| fs)) = String $ T.intercalate "|" flagStrs
3471 where flagStrs = map flagStr . nub $ h:fs
3472 flagStr AnyString = "ANYSTRING"
3473 flagStr Automaton = "AUTOMATON"
3474 flagStr Complement = "COMPLEMENT"
3475 flagStr Empty = "EMPTY"
3476 flagStr Intersection = "INTERSECTION"
3477 flagStr Interval = "INTERVAL"
3479instance FromJSON RegexpFlags where
3480 parseJSON = withText "RegexpFlags" parse
3481 where parse "ALL" = pure AllRegexpFlags
3482 parse "NONE" = pure NoRegexpFlags
3483 parse t = SomeRegexpFlags <$> parseNEJSON (String <$> T.splitOn "|" t)
3485instance FromJSON RegexpFlag where
3486 parseJSON = withText "RegexpFlag" parse
3487 where parse "ANYSTRING" = pure AnyString
3488 parse "AUTOMATON" = pure Automaton
3489 parse "COMPLEMENT" = pure Complement
3490 parse "EMPTY" = pure Empty
3491 parse "INTERSECTION" = pure Intersection
3492 parse "INTERVAL" = pure Interval
3493 parse f = fail ("Unknown RegexpFlag: " <> show f)
3495instance ToJSON Term where
3496 toJSON (Term field value) = object ["term" .= object
3497 [field .= value]]
3499instance FromJSON Term where
3500 parseJSON = withObject "Term" parse
3501 where parse o = do termObj <- o .: "term"
3502 case HM.toList termObj of
3503 [(fn, v)] -> Term fn <$> parseJSON v
3504 _ -> fail "Expected object with 1 field-named key"
3506instance ToJSON BoolMatch where
3507 toJSON (MustMatch term cache) = object ["must" .= term,
3508 "_cache" .= cache]
3509 toJSON (MustNotMatch term cache) = object ["must_not" .= term,
3510 "_cache" .= cache]
3511 toJSON (ShouldMatch terms cache) = object ["should" .= fmap toJSON terms,
3512 "_cache" .= cache]
3514instance FromJSON BoolMatch where
3515 parseJSON = withObject "BoolMatch" parse
3516 where parse o = mustMatch `taggedWith` "must"
3517 <|> mustNotMatch `taggedWith` "must_not"
3518 <|> shouldMatch `taggedWith` "should"
3519 where taggedWith parser k = parser =<< o .: k
3520 mustMatch t = MustMatch t <$> o .:? "_cache" .!= defaultCache
3521 mustNotMatch t = MustNotMatch t <$> o .:? "_cache" .!= defaultCache
3522 shouldMatch t = ShouldMatch t <$> o .:? "_cache" .!= defaultCache
3524instance (FromJSON a) => FromJSON (SearchResult a) where
3525 parseJSON (Object v) = SearchResult <$>
3526 v .: "took" <*>
3527 v .: "timed_out" <*>
3528 v .: "_shards" <*>
3529 v .: "hits" <*>
3530 v .:? "aggregations" <*>
3531 v .:? "_scroll_id"
3532 parseJSON _ = empty
3534instance (FromJSON a) => FromJSON (SearchHits a) where
3535 parseJSON (Object v) = SearchHits <$>
3536 v .: "total" <*>
3537 v .: "max_score" <*>
3538 v .: "hits"
3539 parseJSON _ = empty
3541instance (FromJSON a) => FromJSON (Hit a) where
3542 parseJSON (Object v) = Hit <$>
3543 v .: "_index" <*>
3544 v .: "_type" <*>
3545 v .: "_id" <*>
3546 v .: "_score" <*>
3547 v .:? "_source" <*>
3548 v .:? "highlight"
3549 parseJSON _ = empty
3551instance FromJSON ShardResult where
3552 parseJSON (Object v) = ShardResult <$>
3553 v .: "total" <*>
3554 v .: "successful" <*>
3555 v .: "failed"
3556 parseJSON _ = empty
3559instance FromJSON DocVersion where
3560 parseJSON v = do
3561 i <- parseJSON v
3562 maybe (fail "DocVersion out of range") return $ mkDocVersion i
3564-- This insanity is because ES *sometimes* returns Replica/Shard counts as strings
3565instance FromJSON ReplicaCount where
3566 parseJSON v = parseAsInt v
3567 <|> parseAsString v
3568 where parseAsInt = fmap ReplicaCount . parseJSON
3569 parseAsString = withText "ReplicaCount" (fmap ReplicaCount . parseReadText)
3571instance FromJSON ShardCount where
3572 parseJSON v = parseAsInt v
3573 <|> parseAsString v
3574 where parseAsInt = fmap ShardCount . parseJSON
3575 parseAsString = withText "ShardCount" (fmap ShardCount . parseReadText)
3577instance Bounded DocVersion where
3578 minBound = DocVersion 1
3579 maxBound = DocVersion 9200000000000000000 -- 9.2e+18
3581instance Enum DocVersion where
3582 succ x
3583 | x /= maxBound = DocVersion (succ $ docVersionNumber x)
3584 | otherwise = succError "DocVersion"
3585 pred x
3586 | x /= minBound = DocVersion (pred $ docVersionNumber x)
3587 | otherwise = predError "DocVersion"
3588 toEnum i =
3589 fromMaybe (error $ show i ++ " out of DocVersion range") $ mkDocVersion i
3590 fromEnum = docVersionNumber
3591 enumFrom = boundedEnumFrom
3592 enumFromThen = boundedEnumFromThen
3594-- | Username type used for HTTP Basic authentication. See 'basicAuthHook'.
3595newtype EsUsername = EsUsername { esUsername :: Text } deriving (Show, Eq)
3597-- | Password type used for HTTP Basic authentication. See 'basicAuthHook'.
3598newtype EsPassword = EsPassword { esPassword :: Text } deriving (Show, Eq)