git.iko.soy/typeable/bloodhound
on v0.8.0.0 help sign in
2435 lines 91 kB history raw
1{-# LANGUAGE DeriveGeneric #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5{-# LANGUAGE MultiParamTypeClasses #-}
6{-# LANGUAGE OverloadedStrings #-}
7{-# LANGUAGE RecordWildCards #-}
8{-# LANGUAGE UndecidableInstances #-}
10-------------------------------------------------------------------------------
11-- |
12-- Module : Database.Bloodhound.Types
13-- Copyright : (C) 2014 Chris Allen
14-- License : BSD-style (see the file LICENSE)
15-- Maintainer : Chris Allen <cma@bitemyapp.com
16-- Stability : provisional
17-- Portability : DeriveGeneric, RecordWildCards
18--
19-- Data types for describing actions and data structures performed to interact
20-- with Elasticsearch. The two main buckets your queries against Elasticsearch
21-- will fall into are 'Query's and 'Filter's. 'Filter's are more like
22-- traditional database constraints and often have preferable performance
23-- properties. 'Query's support human-written textual queries, such as fuzzy
24-- queries.
25-------------------------------------------------------------------------------
29module Database.Bloodhound.Types
30 ( defaultCache
31 , defaultIndexSettings
32 , defaultIndexDocumentSettings
33 , mkSort
34 , showText
35 , unpackId
36 , mkMatchQuery
37 , mkMultiMatchQuery
38 , mkBoolQuery
39 , mkRangeQuery
40 , mkQueryStringQuery
41 , mkAggregations
42 , mkTermsAggregation
43 , mkTermsScriptAggregation
44 , mkDateHistogram
45 , mkDocVersion
46 , docVersionNumber
47 , toTerms
48 , toDateHistogram
49 , omitNulls
50 , BH(..)
51 , runBH
52 , BHEnv(..)
53 , MonadBH(..)
54 , Version(..)
55 , Status(..)
56 , Existence(..)
57 , NullValue(..)
58 , IndexSettings(..)
59 , IndexTemplate(..)
60 , Server(..)
61 , Reply
62 , EsResult(..)
63 , EsResultFound(..)
64 , DocVersion
65 , ExternalDocVersion(..)
66 , VersionControl(..)
67 , DocumentParent(..)
68 , IndexDocumentSettings(..)
69 , Query(..)
70 , Search(..)
71 , SearchType(..)
72 , SearchResult(..)
73 , ScrollId
74 , SearchHits(..)
75 , TrackSortScores
76 , From(..)
77 , Size(..)
78 , Source(..)
79 , PatternOrPatterns(..)
80 , Include(..)
81 , Exclude(..)
82 , Pattern(..)
83 , ShardResult(..)
84 , Hit(..)
85 , Filter(..)
86 , Seminearring(..)
87 , BoolMatch(..)
88 , Term(..)
89 , GeoPoint(..)
90 , GeoBoundingBoxConstraint(..)
91 , GeoBoundingBox(..)
92 , GeoFilterType(..)
93 , Distance(..)
94 , DistanceUnit(..)
95 , DistanceType(..)
96 , DistanceRange(..)
97 , OptimizeBbox(..)
98 , LatLon(..)
99 , RangeValue(..)
100 , RangeExecution(..)
101 , LessThan(..)
102 , LessThanEq(..)
103 , GreaterThan(..)
104 , GreaterThanEq(..)
105 , LessThanD(..)
106 , LessThanEqD(..)
107 , GreaterThanD(..)
108 , GreaterThanEqD(..)
109 , Regexp(..)
110 , RegexpFlags(..)
111 , RegexpFlag(..)
112 , FieldName(..)
113 , Script(..)
114 , IndexName(..)
115 , TemplateName(..)
116 , TemplatePattern(..)
117 , MappingName(..)
118 , DocId(..)
119 , CacheName(..)
120 , CacheKey(..)
121 , BulkOperation(..)
122 , ReplicaCount(..)
123 , ShardCount(..)
124 , Sort
125 , SortMode(..)
126 , SortOrder(..)
127 , SortSpec(..)
128 , DefaultSort(..)
129 , Missing(..)
130 , OpenCloseIndex(..)
131 , Method
132 , Boost(..)
133 , MatchQuery(..)
134 , MultiMatchQuery(..)
135 , BoolQuery(..)
136 , BoostingQuery(..)
137 , CommonTermsQuery(..)
138 , DisMaxQuery(..)
139 , FilteredQuery(..)
140 , FuzzyLikeThisQuery(..)
141 , FuzzyLikeFieldQuery(..)
142 , FuzzyQuery(..)
143 , HasChildQuery(..)
144 , HasParentQuery(..)
145 , IndicesQuery(..)
146 , MoreLikeThisQuery(..)
147 , MoreLikeThisFieldQuery(..)
148 , NestedQuery(..)
149 , PrefixQuery(..)
150 , QueryStringQuery(..)
151 , SimpleQueryStringQuery(..)
152 , RangeQuery(..)
153 , RegexpQuery(..)
154 , QueryString(..)
155 , BooleanOperator(..)
156 , ZeroTermsQuery(..)
157 , CutoffFrequency(..)
158 , Analyzer(..)
159 , MaxExpansions(..)
160 , Lenient(..)
161 , MatchQueryType(..)
162 , MultiMatchQueryType(..)
163 , Tiebreaker(..)
164 , MinimumMatch(..)
165 , DisableCoord(..)
166 , CommonMinimumMatch(..)
167 , MinimumMatchHighLow(..)
168 , PrefixLength(..)
169 , Fuzziness(..)
170 , IgnoreTermFrequency(..)
171 , MaxQueryTerms(..)
172 , ScoreType(..)
173 , Score
174 , Cache
175 , TypeName(..)
176 , BoostTerms(..)
177 , MaxWordLength(..)
178 , MinWordLength(..)
179 , MaxDocFrequency(..)
180 , MinDocFrequency(..)
181 , PhraseSlop(..)
182 , StopWord(..)
183 , QueryPath(..)
184 , MinimumTermFrequency(..)
185 , PercentMatch(..)
186 , FieldDefinition(..)
187 , MappingField(..)
188 , Mapping(..)
189 , AllowLeadingWildcard(..)
190 , LowercaseExpanded(..)
191 , GeneratePhraseQueries(..)
192 , Locale(..)
193 , AnalyzeWildcard(..)
194 , EnablePositionIncrements(..)
195 , SimpleQueryFlag(..)
196 , FieldOrFields(..)
197 , Monoid(..)
198 , ToJSON(..)
199 , Interval(..)
200 , TimeInterval(..)
201 , ExecutionHint(..)
202 , CollectionMode(..)
203 , TermOrder(..)
204 , TermInclusion(..)
206 , Aggregation(..)
207 , Aggregations
208 , AggregationResults
209 , Bucket(..)
210 , BucketAggregation(..)
211 , TermsAggregation(..)
212 , ValueCountAggregation(..)
213 , FilterAggregation(..)
214 , DateHistogramAggregation(..)
216 , Highlights(..)
217 , FieldHighlight(..)
218 , HighlightSettings(..)
219 , PlainHighlight(..)
220 , PostingsHighlight(..)
221 , FastVectorHighlight(..)
222 , CommonHighlight(..)
223 , NonPostings(..)
224 , HighlightEncoder(..)
225 , HighlightTag(..)
226 , HitHighlight
228 , TermsResult(..)
229 , DateHistogramResult(..)
230 ) where
232import Control.Applicative
233import Control.Monad.Catch
234import Control.Monad.Except
235import Control.Monad.Reader
236import Control.Monad.State
237import Control.Monad.Writer
238import Data.Aeson
239import Data.Aeson.Types (Pair, emptyObject, parseMaybe)
240import qualified Data.ByteString.Lazy.Char8 as L
241import qualified Data.HashMap.Strict as HM (union)
242import Data.List (foldl', nub)
243import Data.List.NonEmpty (NonEmpty (..), toList)
244import qualified Data.Map.Strict as M
245import Data.Maybe
246import Data.Text (Text)
247import qualified Data.Text as T
248import Data.Time.Clock (UTCTime)
249import qualified Data.Vector as V
250import GHC.Enum
251import GHC.Generics (Generic)
252import Network.HTTP.Client
253import qualified Network.HTTP.Types.Method as NHTM
255import Database.Bloodhound.Types.Class
257-- $setup
258-- >>> :set -XOverloadedStrings
259-- >>> import Database.Bloodhound
260-- >>> let testServer = (Server "http://localhost:9200")
261-- >>> let testIndex = IndexName "twitter"
262-- >>> let testMapping = MappingName "tweet"
263-- >>> let defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
265-- defaultIndexSettings is exported by Database.Bloodhound as well
266-- no trailing slashes in servers, library handles building the path.
268{-| Common environment for Elasticsearch calls. Connections will be
269 pipelined according to the provided HTTP connection manager.
270-}
271data BHEnv = BHEnv { bhServer :: Server
272 , bhManager :: Manager
273 }
275{-| All API calls to Elasticsearch operate within
276 MonadBH. The idea is that it can be easily embedded in your
277 own monad transformer stack. A default instance for a ReaderT and
278 alias 'BH' is provided for the simple case.
279-}
280class (Functor m, Applicative m, MonadIO m) => MonadBH m where
281 getBHEnv :: m BHEnv
283newtype BH m a = BH {
284 unBH :: ReaderT BHEnv m a
285 } deriving ( Functor
286 , Applicative
287 , Monad
288 , MonadIO
289 , MonadState s
290 , MonadWriter w
291 , MonadError e
292 , Alternative
293 , MonadPlus
294 , MonadFix
295 , MonadThrow
296 , MonadCatch
297 , MonadMask)
299instance MonadTrans BH where
300 lift = BH . lift
302instance (MonadReader r m) => MonadReader r (BH m) where
303 ask = lift ask
304 local f (BH (ReaderT m)) = BH $ ReaderT $ \r ->
305 local f (m r)
307instance (Functor m, Applicative m, MonadIO m) => MonadBH (BH m) where
308 getBHEnv = BH getBHEnv
311instance (Functor m, Applicative m, MonadIO m) => MonadBH (ReaderT BHEnv m) where
312 getBHEnv = ask
314runBH :: BHEnv -> BH m a -> m a
315runBH e f = runReaderT (unBH f) e
317{-| 'Version' is embedded in 'Status' -}
318data Version = Version { number :: Text
319 , build_hash :: Text
320 , build_timestamp :: UTCTime
321 , build_snapshot :: Bool
322 , lucene_version :: Text } deriving (Eq, Show, Generic)
324{-| 'Status' is a data type for describing the JSON body returned by
325 Elasticsearch when you query its status. This was deprecated in 1.2.0.
327 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-status.html#indices-status>
328-}
330data Status = Status { ok :: Maybe Bool
331 , status :: Int
332 , name :: Text
333 , version :: Version
334 , tagline :: Text } deriving (Eq, Show)
336{-| 'IndexSettings' is used to configure the shards and replicas when you create
337 an Elasticsearch Index.
339 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html>
340-}
342data IndexSettings =
343 IndexSettings { indexShards :: ShardCount
344 , indexReplicas :: ReplicaCount } deriving (Eq, Show)
346{-| 'defaultIndexSettings' is an 'IndexSettings' with 3 shards and 2 replicas. -}
347defaultIndexSettings :: IndexSettings
348defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
350{-| 'Reply' and 'Method' are type synonyms from 'Network.HTTP.Types.Method.Method' -}
351type Reply = Network.HTTP.Client.Response L.ByteString
352type Method = NHTM.Method
354{-| 'OpenCloseIndex' is a sum type for opening and closing indices.
356 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-open-close.html>
357-}
358data OpenCloseIndex = OpenIndex | CloseIndex deriving (Eq, Show)
360data FieldType = GeoPointType
361 | GeoShapeType
362 | FloatType
363 | IntegerType
364 | LongType
365 | ShortType
366 | ByteType deriving (Eq, Show)
368data FieldDefinition =
369 FieldDefinition { fieldType :: FieldType } deriving (Eq, Show)
371{-| An 'IndexTemplate' defines a template that will automatically be
372 applied to new indices created. The templates include both
373 'IndexSettings' and mappings, and a simple 'TemplatePattern' that
374 controls if the template will be applied to the index created.
375 Specify mappings as follows: @[toJSON TweetMapping, ...]@
377 https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-templates.html
378-}
379data IndexTemplate =
380 IndexTemplate { templatePattern :: TemplatePattern
381 , templateSettings :: Maybe IndexSettings
382 , templateMappings :: [Value]
383 }
385data MappingField =
386 MappingField { mappingFieldName :: FieldName
387 , fieldDefinition :: FieldDefinition } deriving (Eq, Show)
389{-| Support for type reification of 'Mapping's is currently incomplete, for
390 now the mapping API verbiage expects a 'ToJSON'able blob.
392 Indexes have mappings, mappings are schemas for the documents contained in the
393 index. I'd recommend having only one mapping per index, always having a mapping,
394 and keeping different kinds of documents separated if possible.
395-}
396data Mapping = Mapping { typeName :: TypeName
397 , mappingFields :: [MappingField] } deriving (Eq, Show)
399{-| 'BulkOperation' is a sum type for expressing the four kinds of bulk
400 operation index, create, delete, and update. 'BulkIndex' behaves like an
401 "upsert", 'BulkCreate' will fail if a document already exists at the DocId.
403 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-bulk.html#docs-bulk>
404-}
405data BulkOperation =
406 BulkIndex IndexName MappingName DocId Value
407 | BulkCreate IndexName MappingName DocId Value
408 | BulkDelete IndexName MappingName DocId
409 | BulkUpdate IndexName MappingName DocId Value deriving (Eq, Show)
411{-| 'EsResult' describes the standard wrapper JSON document that you see in
412 successful Elasticsearch lookups or lookups that couldn't find the document.
413-}
414data EsResult a = EsResult { _index :: Text
415 , _type :: Text
416 , _id :: Text
417 , foundResult :: Maybe (EsResultFound a)} deriving (Eq, Show)
420{-| 'EsResultFound' contains the document and its metadata inside of an
421 'EsResult' when the document was successfully found.
422-}
423data EsResultFound a = EsResultFound { _version :: DocVersion
424 , _source :: a } deriving (Eq, Show)
428{-| 'DocVersion' is an integer version number for a document between 1
429and 9.2e+18 used for <<https://www.elastic.co/guide/en/elasticsearch/guide/current/optimistic-concurrency-control.html optimistic concurrency control>>.
430-}
431newtype DocVersion = DocVersion {
432 docVersionNumber :: Int
433 } deriving (Eq, Show, Ord, ToJSON)
435-- | Smart constructor for in-range doc version
436mkDocVersion :: Int -> Maybe DocVersion
437mkDocVersion i
438 | i >= (docVersionNumber minBound) && i <= (docVersionNumber maxBound) =
439 Just $ DocVersion i
440 | otherwise = Nothing
443{-| 'ExternalDocVersion' is a convenience wrapper if your code uses its
444own version numbers instead of ones from ES.
445-}
446newtype ExternalDocVersion = ExternalDocVersion DocVersion
447 deriving (Eq, Show, Ord, Bounded, Enum, ToJSON)
449{-| 'VersionControl' is specified when indexing documents as a
450optimistic concurrency control.
451-}
452data VersionControl = NoVersionControl
453 -- ^ Don't send a version. This is a pure overwrite.
454 | InternalVersion DocVersion
455 -- ^ Use the default ES versioning scheme. Only
456 -- index the document if the version is the same
457 -- as the one specified. Only applicable to
458 -- updates, as you should be getting Version from
459 -- a search result.
460 | ExternalGT ExternalDocVersion
461 -- ^ Use your own version numbering. Only index
462 -- the document if the version is strictly higher
463 -- OR the document doesn't exist. The given
464 -- version will be used as the new version number
465 -- for the stored document. N.B. All updates must
466 -- increment this number, meaning there is some
467 -- global, external ordering of updates.
468 | ExternalGTE ExternalDocVersion
469 -- ^ Use your own version numbering. Only index
470 -- the document if the version is equal or higher
471 -- than the stored version. Will succeed if there
472 -- is no existing document. The given version will
473 -- be used as the new version number for the
474 -- stored document. Use with care, as this could
475 -- result in data loss.
476 | ForceVersion ExternalDocVersion
477 -- ^ The document will always be indexed and the
478 -- given version will be the new version. This is
479 -- typically used for correcting errors. Use with
480 -- care, as this could result in data loss.
481 deriving (Show, Eq, Ord)
483{-| 'DocumentParent' is used to specify a parent document.
484-}
485newtype DocumentParent = DocumentParent DocId
486 deriving (Eq, Show)
488{-| 'IndexDocumentSettings' are special settings supplied when indexing
489a document. For the best backwards compatiblity when new fields are
490added, you should probably prefer to start with 'defaultIndexDocumentSettings'
491-}
492data IndexDocumentSettings =
493 IndexDocumentSettings { idsVersionControl :: VersionControl
494 , idsParent :: Maybe DocumentParent
495 } deriving (Eq, Show)
497{-| Reasonable default settings. Chooses no version control and no parent.
498-}
499defaultIndexDocumentSettings :: IndexDocumentSettings
500defaultIndexDocumentSettings = IndexDocumentSettings NoVersionControl Nothing
502{-| 'Sort' is a synonym for a list of 'SortSpec's. Sort behavior is order
503 dependent with later sorts acting as tie-breakers for earlier sorts.
504-}
505type Sort = [SortSpec]
507{-| The two main kinds of 'SortSpec' are 'DefaultSortSpec' and
508 'GeoDistanceSortSpec'. The latter takes a 'SortOrder', 'GeoPoint', and
509 'DistanceUnit' to express "nearness" to a single geographical point as a
510 sort specification.
512<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
513-}
514data SortSpec = DefaultSortSpec DefaultSort
515 | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit deriving (Eq, Show)
517{-| 'DefaultSort' is usually the kind of 'SortSpec' you'll want. There's a
518 'mkSort' convenience function for when you want to specify only the most
519 common parameters.
521<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
522-}
523data DefaultSort =
524 DefaultSort { sortFieldName :: FieldName
525 , sortOrder :: SortOrder
526 -- default False
527 , ignoreUnmapped :: Bool
528 , sortMode :: Maybe SortMode
529 , missingSort :: Maybe Missing
530 , nestedFilter :: Maybe Filter } deriving (Eq, Show)
532{-| 'SortOrder' is 'Ascending' or 'Descending', as you might expect. These get
533 encoded into "asc" or "desc" when turned into JSON.
535<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
536-}
537data SortOrder = Ascending
538 | Descending deriving (Eq, Show)
540{-| 'Missing' prescribes how to handle missing fields. A missing field can be
541 sorted last, first, or using a custom value as a substitute.
543<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_missing_values>
544-}
545data Missing = LastMissing
546 | FirstMissing
547 | CustomMissing Text deriving (Eq, Show)
549{-| 'SortMode' prescribes how to handle sorting array/multi-valued fields.
551http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_sort_mode_option
552-}
553data SortMode = SortMin
554 | SortMax
555 | SortSum
556 | SortAvg deriving (Eq, Show)
558{-| 'mkSort' defaults everything but the 'FieldName' and the 'SortOrder' so
559 that you can concisely describe the usual kind of 'SortSpec's you want.
560-}
561mkSort :: FieldName -> SortOrder -> DefaultSort
562mkSort fieldName sOrder = DefaultSort fieldName sOrder False Nothing Nothing Nothing
564{-| 'Cache' is for telling ES whether it should cache a 'Filter' not.
565 'Query's cannot be cached.
566-}
567type Cache = Bool -- caching on/off
568defaultCache :: Cache
569defaultCache = False
571{-| 'PrefixValue' is used in 'PrefixQuery' as the main query component.
572-}
573type PrefixValue = Text
575{-| 'BooleanOperator' is the usual And/Or operators with an ES compatible
576 JSON encoding baked in. Used all over the place.
577-}
578data BooleanOperator = And | Or deriving (Eq, Show)
580{-| 'ShardCount' is part of 'IndexSettings'
581-}
582newtype ShardCount = ShardCount Int deriving (Eq, Show, Generic)
584{-| 'ReplicaCount' is part of 'IndexSettings'
585-}
586newtype ReplicaCount = ReplicaCount Int deriving (Eq, Show, Generic)
588{-| 'Server' is used with the client functions to point at the ES instance
589-}
590newtype Server = Server Text deriving (Eq, Show)
592{-| 'IndexName' is used to describe which index to query/create/delete
593-}
594newtype IndexName = IndexName Text deriving (Eq, Generic, Show)
596{-| 'TemplateName' is used to describe which template to query/create/delete
597-}
598newtype TemplateName = TemplateName Text deriving (Eq, Show, Generic)
600{-| 'TemplatePattern' represents a pattern which is matched against index names
601-}
602newtype TemplatePattern = TemplatePattern Text deriving (Eq, Show, Generic)
604{-| 'MappingName' is part of mappings which are how ES describes and schematizes
605 the data in the indices.
606-}
607newtype MappingName = MappingName Text deriving (Eq, Generic, Show)
609{-| 'DocId' is a generic wrapper value for expressing unique Document IDs.
610 Can be set by the user or created by ES itself. Often used in client
611 functions for poking at specific documents.
612-}
613newtype DocId = DocId Text deriving (Eq, Generic, Show)
615{-| 'QueryString' is used to wrap query text bodies, be they human written or not.
616-}
617newtype QueryString = QueryString Text deriving (Eq, Generic, Show)
619{-| 'FieldName' is used all over the place wherever a specific field within
620 a document needs to be specified, usually in 'Query's or 'Filter's.
621-}
622newtype FieldName = FieldName Text deriving (Eq, Show)
625{-| 'Script' is often used in place of 'FieldName' to specify more
626complex ways of extracting a value from a document.
627-}
628newtype Script = Script { scriptText :: Text } deriving (Eq, Show)
630{-| 'CacheName' is used in 'RegexpFilter' for describing the
631 'CacheKey' keyed caching behavior.
632-}
633newtype CacheName = CacheName Text deriving (Eq, Show)
635{-| 'CacheKey' is used in 'RegexpFilter' to key regex caching.
636-}
637newtype CacheKey =
638 CacheKey Text deriving (Eq, Show)
639newtype Existence =
640 Existence Bool deriving (Eq, Show)
641newtype NullValue =
642 NullValue Bool deriving (Eq, Show)
643newtype CutoffFrequency =
644 CutoffFrequency Double deriving (Eq, Show, Generic)
645newtype Analyzer =
646 Analyzer Text deriving (Eq, Show, Generic)
647newtype MaxExpansions =
648 MaxExpansions Int deriving (Eq, Show, Generic)
650{-| 'Lenient', if set to true, will cause format based failures to be
651 ignored. I don't know what the bloody default is, Elasticsearch
652 documentation didn't say what it was. Let me know if you figure it out.
653-}
654newtype Lenient =
655 Lenient Bool deriving (Eq, Show, Generic)
656newtype Tiebreaker =
657 Tiebreaker Double deriving (Eq, Show, Generic)
658newtype Boost =
659 Boost Double deriving (Eq, Show, Generic)
660newtype BoostTerms =
661 BoostTerms Double deriving (Eq, Show, Generic)
663{-| 'MinimumMatch' controls how many should clauses in the bool query should
664 match. Can be an absolute value (2) or a percentage (30%) or a
665 combination of both.
666-}
667newtype MinimumMatch =
668 MinimumMatch Int deriving (Eq, Show, Generic)
669newtype MinimumMatchText =
670 MinimumMatchText Text deriving (Eq, Show)
671newtype DisableCoord =
672 DisableCoord Bool deriving (Eq, Show, Generic)
673newtype IgnoreTermFrequency =
674 IgnoreTermFrequency Bool deriving (Eq, Show, Generic)
675newtype MinimumTermFrequency =
676 MinimumTermFrequency Int deriving (Eq, Show, Generic)
677newtype MaxQueryTerms =
678 MaxQueryTerms Int deriving (Eq, Show, Generic)
679newtype Fuzziness =
680 Fuzziness Double deriving (Eq, Show, Generic)
682{-| 'PrefixLength' is the prefix length used in queries, defaults to 0. -}
683newtype PrefixLength =
684 PrefixLength Int deriving (Eq, Show, Generic)
685newtype TypeName =
686 TypeName Text deriving (Eq, Show, Generic)
687newtype PercentMatch =
688 PercentMatch Double deriving (Eq, Show, Generic)
689newtype StopWord =
690 StopWord Text deriving (Eq, Show, Generic)
691newtype QueryPath =
692 QueryPath Text deriving (Eq, Show, Generic)
694{-| Allowing a wildcard at the beginning of a word (eg "*ing") is particularly
695 heavy, because all terms in the index need to be examined, just in case
696 they match. Leading wildcards can be disabled by setting
697 'AllowLeadingWildcard' to false. -}
698newtype AllowLeadingWildcard =
699 AllowLeadingWildcard Bool deriving (Eq, Show, Generic)
700newtype LowercaseExpanded =
701 LowercaseExpanded Bool deriving (Eq, Show, Generic)
702newtype EnablePositionIncrements =
703 EnablePositionIncrements Bool deriving (Eq, Show, Generic)
705{-| By default, wildcard terms in a query are not analyzed.
706 Setting 'AnalyzeWildcard' to true enables best-effort analysis.
707-}
708newtype AnalyzeWildcard = AnalyzeWildcard Bool deriving (Eq, Show, Generic)
710{-| 'GeneratePhraseQueries' defaults to false.
711-}
712newtype GeneratePhraseQueries =
713 GeneratePhraseQueries Bool deriving (Eq, Show, Generic)
715{-| 'Locale' is used for string conversions - defaults to ROOT.
716-}
717newtype Locale = Locale Text deriving (Eq, Show, Generic)
718newtype MaxWordLength = MaxWordLength Int deriving (Eq, Show, Generic)
719newtype MinWordLength = MinWordLength Int deriving (Eq, Show, Generic)
721{-| 'PhraseSlop' sets the default slop for phrases, 0 means exact
722 phrase matches. Default is 0.
723-}
724newtype PhraseSlop = PhraseSlop Int deriving (Eq, Show, Generic)
725newtype MinDocFrequency = MinDocFrequency Int deriving (Eq, Show, Generic)
726newtype MaxDocFrequency = MaxDocFrequency Int deriving (Eq, Show, Generic)
728{-| 'unpackId' is a silly convenience function that gets used once.
729-}
730unpackId :: DocId -> Text
731unpackId (DocId docId) = docId
733type TrackSortScores = Bool
734newtype From = From Int deriving (Eq, Show, ToJSON)
735newtype Size = Size Int deriving (Eq, Show, ToJSON)
737data Search = Search { queryBody :: Maybe Query
738 , filterBody :: Maybe Filter
739 , sortBody :: Maybe Sort
740 , aggBody :: Maybe Aggregations
741 , highlight :: Maybe Highlights
742 -- default False
743 , trackSortScores :: TrackSortScores
744 , from :: From
745 , size :: Size
746 , searchType :: SearchType
747 , fields :: Maybe [FieldName]
748 , source :: Maybe Source } deriving (Eq, Show)
750data SearchType = SearchTypeQueryThenFetch
751 | SearchTypeDfsQueryThenFetch
752 | SearchTypeCount
753 | SearchTypeScan
754 | SearchTypeQueryAndFetch
755 | SearchTypeDfsQueryAndFetch
756 deriving (Eq, Show)
758data Source =
759 NoSource
760 | SourcePatterns PatternOrPatterns
761 | SourceIncludeExclude Include Exclude
762 deriving (Show, Eq)
764data PatternOrPatterns = PopPattern Pattern
765 | PopPatterns [Pattern] deriving (Eq, Show)
767data Include = Include [Pattern] deriving (Eq, Show)
768data Exclude = Exclude [Pattern] deriving (Eq, Show)
770newtype Pattern = Pattern Text deriving (Eq, Show)
772data Highlights = Highlights { globalsettings :: Maybe HighlightSettings
773 , highlightFields :: [FieldHighlight]
774 } deriving (Show, Eq)
776data FieldHighlight = FieldHighlight FieldName (Maybe HighlightSettings)
777 deriving (Show, Eq)
780data HighlightSettings = Plain PlainHighlight
781 | Postings PostingsHighlight
782 | FastVector FastVectorHighlight
783 deriving (Show, Eq)
784data PlainHighlight =
785 PlainHighlight { plainCommon :: Maybe CommonHighlight
786 , plainNonPost :: Maybe NonPostings } deriving (Show, Eq)
788 -- This requires that index_options are set to 'offset' in the mapping.
789data PostingsHighlight = PostingsHighlight (Maybe CommonHighlight) deriving (Show, Eq)
791-- This requires that term_vector is set to 'with_positions_offsets' in the mapping.
792data FastVectorHighlight =
793 FastVectorHighlight { fvCommon :: Maybe CommonHighlight
794 , fvNonPostSettings :: Maybe NonPostings
795 , boundaryChars :: Maybe Text
796 , boundaryMaxScan :: Maybe Int
797 , fragmentOffset :: Maybe Int
798 , matchedFields :: [Text]
799 , phraseLimit :: Maybe Int
800 } deriving (Show, Eq)
802data CommonHighlight =
803 CommonHighlight { order :: Maybe Text
804 , forceSource :: Maybe Bool
805 , tag :: Maybe HighlightTag
806 , encoder :: Maybe HighlightEncoder
807 , noMatchSize :: Maybe Int
808 , highlightQuery :: Maybe Query
809 , requireFieldMatch :: Maybe Bool
810 } deriving (Show, Eq)
812-- Settings that are only applicable to FastVector and Plain highlighters.
813data NonPostings =
814 NonPostings { fragmentSize :: Maybe Int
815 , numberOfFragments :: Maybe Int} deriving (Show, Eq)
817data HighlightEncoder = DefaultEncoder
818 | HTMLEncoder
819 deriving (Show, Eq)
821-- NOTE: Should the tags use some kind of HTML type, rather than Text?
822data HighlightTag = TagSchema Text
823 | CustomTags ([Text], [Text]) -- Only uses more than the first value in the lists if fvh
824 deriving (Show, Eq)
827data Query =
828 TermQuery Term (Maybe Boost)
829 | TermsQuery (NonEmpty Term)
830 | QueryMatchQuery MatchQuery
831 | QueryMultiMatchQuery MultiMatchQuery
832 | QueryBoolQuery BoolQuery
833 | QueryBoostingQuery BoostingQuery
834 | QueryCommonTermsQuery CommonTermsQuery
835 | ConstantScoreFilter Filter Boost
836 | ConstantScoreQuery Query Boost
837 | QueryDisMaxQuery DisMaxQuery
838 | QueryFilteredQuery FilteredQuery
839 | QueryFuzzyLikeThisQuery FuzzyLikeThisQuery
840 | QueryFuzzyLikeFieldQuery FuzzyLikeFieldQuery
841 | QueryFuzzyQuery FuzzyQuery
842 | QueryHasChildQuery HasChildQuery
843 | QueryHasParentQuery HasParentQuery
844 | IdsQuery MappingName [DocId]
845 | QueryIndicesQuery IndicesQuery
846 | MatchAllQuery (Maybe Boost)
847 | QueryMoreLikeThisQuery MoreLikeThisQuery
848 | QueryMoreLikeThisFieldQuery MoreLikeThisFieldQuery
849 | QueryNestedQuery NestedQuery
850 | QueryPrefixQuery PrefixQuery
851 | QueryQueryStringQuery QueryStringQuery
852 | QuerySimpleQueryStringQuery SimpleQueryStringQuery
853 | QueryRangeQuery RangeQuery
854 | QueryRegexpQuery RegexpQuery
855 deriving (Eq, Show)
857data RegexpQuery =
858 RegexpQuery { regexpQueryField :: FieldName
859 , regexpQuery :: Regexp
860 , regexpQueryFlags :: RegexpFlags
861 , regexpQueryBoost :: Maybe Boost
862 } deriving (Eq, Show)
864data RangeQuery =
865 RangeQuery { rangeQueryField :: FieldName
866 , rangeQueryRange :: RangeValue
867 , rangeQueryBoost :: Boost } deriving (Eq, Show)
869mkRangeQuery :: FieldName -> RangeValue -> RangeQuery
870mkRangeQuery f r = RangeQuery f r (Boost 1.0)
872data SimpleQueryStringQuery =
873 SimpleQueryStringQuery
874 { simpleQueryStringQuery :: QueryString
875 , simpleQueryStringField :: Maybe FieldOrFields
876 , simpleQueryStringOperator :: Maybe BooleanOperator
877 , simpleQueryStringAnalyzer :: Maybe Analyzer
878 , simpleQueryStringFlags :: Maybe [SimpleQueryFlag]
879 , simpleQueryStringLowercaseExpanded :: Maybe LowercaseExpanded
880 , simpleQueryStringLocale :: Maybe Locale
881 } deriving (Eq, Show)
883data SimpleQueryFlag =
884 SimpleQueryAll
885 | SimpleQueryNone
886 | SimpleQueryAnd
887 | SimpleQueryOr
888 | SimpleQueryPrefix
889 | SimpleQueryPhrase
890 | SimpleQueryPrecedence
891 | SimpleQueryEscape
892 | SimpleQueryWhitespace
893 | SimpleQueryFuzzy
894 | SimpleQueryNear
895 | SimpleQuerySlop deriving (Eq, Show)
897-- use_dis_max and tie_breaker when fields are plural?
898data QueryStringQuery =
899 QueryStringQuery
900 { queryStringQuery :: QueryString
901 , queryStringDefaultField :: Maybe FieldName
902 , queryStringOperator :: Maybe BooleanOperator
903 , queryStringAnalyzer :: Maybe Analyzer
904 , queryStringAllowLeadingWildcard :: Maybe AllowLeadingWildcard
905 , queryStringLowercaseExpanded :: Maybe LowercaseExpanded
906 , queryStringEnablePositionIncrements :: Maybe EnablePositionIncrements
907 , queryStringFuzzyMaxExpansions :: Maybe MaxExpansions
908 , queryStringFuzziness :: Maybe Fuzziness
909 , queryStringFuzzyPrefixLength :: Maybe PrefixLength
910 , queryStringPhraseSlop :: Maybe PhraseSlop
911 , queryStringBoost :: Maybe Boost
912 , queryStringAnalyzeWildcard :: Maybe AnalyzeWildcard
913 , queryStringGeneratePhraseQueries :: Maybe GeneratePhraseQueries
914 , queryStringMinimumShouldMatch :: Maybe MinimumMatch
915 , queryStringLenient :: Maybe Lenient
916 , queryStringLocale :: Maybe Locale
917 } deriving (Eq, Show)
919mkQueryStringQuery :: QueryString -> QueryStringQuery
920mkQueryStringQuery qs =
921 QueryStringQuery qs Nothing Nothing
922 Nothing Nothing Nothing Nothing
923 Nothing Nothing Nothing Nothing
924 Nothing Nothing Nothing Nothing
925 Nothing Nothing
927data FieldOrFields = FofField FieldName
928 | FofFields [FieldName] deriving (Eq, Show)
930data PrefixQuery =
931 PrefixQuery
932 { prefixQueryField :: FieldName
933 , prefixQueryPrefixValue :: Text
934 , prefixQueryBoost :: Maybe Boost } deriving (Eq, Show)
936data NestedQuery =
937 NestedQuery
938 { nestedQueryPath :: QueryPath
939 , nestedQueryScoreType :: ScoreType
940 , nestedQuery :: Query } deriving (Eq, Show)
942data MoreLikeThisFieldQuery =
943 MoreLikeThisFieldQuery
944 { moreLikeThisFieldText :: Text
945 , moreLikeThisFieldFields :: FieldName
946 -- default 0.3 (30%)
947 , moreLikeThisFieldPercentMatch :: Maybe PercentMatch
948 , moreLikeThisFieldMinimumTermFreq :: Maybe MinimumTermFrequency
949 , moreLikeThisFieldMaxQueryTerms :: Maybe MaxQueryTerms
950 , moreLikeThisFieldStopWords :: Maybe [StopWord]
951 , moreLikeThisFieldMinDocFrequency :: Maybe MinDocFrequency
952 , moreLikeThisFieldMaxDocFrequency :: Maybe MaxDocFrequency
953 , moreLikeThisFieldMinWordLength :: Maybe MinWordLength
954 , moreLikeThisFieldMaxWordLength :: Maybe MaxWordLength
955 , moreLikeThisFieldBoostTerms :: Maybe BoostTerms
956 , moreLikeThisFieldBoost :: Maybe Boost
957 , moreLikeThisFieldAnalyzer :: Maybe Analyzer
958 } deriving (Eq, Show)
960data MoreLikeThisQuery =
961 MoreLikeThisQuery
962 { moreLikeThisText :: Text
963 , moreLikeThisFields :: Maybe [FieldName]
964 -- default 0.3 (30%)
965 , moreLikeThisPercentMatch :: Maybe PercentMatch
966 , moreLikeThisMinimumTermFreq :: Maybe MinimumTermFrequency
967 , moreLikeThisMaxQueryTerms :: Maybe MaxQueryTerms
968 , moreLikeThisStopWords :: Maybe [StopWord]
969 , moreLikeThisMinDocFrequency :: Maybe MinDocFrequency
970 , moreLikeThisMaxDocFrequency :: Maybe MaxDocFrequency
971 , moreLikeThisMinWordLength :: Maybe MinWordLength
972 , moreLikeThisMaxWordLength :: Maybe MaxWordLength
973 , moreLikeThisBoostTerms :: Maybe BoostTerms
974 , moreLikeThisBoost :: Maybe Boost
975 , moreLikeThisAnalyzer :: Maybe Analyzer
976 } deriving (Eq, Show)
978data IndicesQuery =
979 IndicesQuery
980 { indicesQueryIndices :: [IndexName]
981 , indicesQuery :: Query
982 -- default "all"
983 , indicesQueryNoMatch :: Maybe Query } deriving (Eq, Show)
985data HasParentQuery =
986 HasParentQuery
987 { hasParentQueryType :: TypeName
988 , hasParentQuery :: Query
989 , hasParentQueryScoreType :: Maybe ScoreType } deriving (Eq, Show)
991data HasChildQuery =
992 HasChildQuery
993 { hasChildQueryType :: TypeName
994 , hasChildQuery :: Query
995 , hasChildQueryScoreType :: Maybe ScoreType } deriving (Eq, Show)
997data ScoreType =
998 ScoreTypeMax
999 | ScoreTypeSum
1000 | ScoreTypeAvg
1001 | ScoreTypeNone deriving (Eq, Show)
1003data FuzzyQuery =
1004 FuzzyQuery { fuzzyQueryField :: FieldName
1005 , fuzzyQueryValue :: Text
1006 , fuzzyQueryPrefixLength :: PrefixLength
1007 , fuzzyQueryMaxExpansions :: MaxExpansions
1008 , fuzzyQueryFuzziness :: Fuzziness
1009 , fuzzyQueryBoost :: Maybe Boost
1010 } deriving (Eq, Show)
1012data FuzzyLikeFieldQuery =
1013 FuzzyLikeFieldQuery
1014 { fuzzyLikeField :: FieldName
1015 -- anaphora is good for the soul.
1016 , fuzzyLikeFieldText :: Text
1017 , fuzzyLikeFieldMaxQueryTerms :: MaxQueryTerms
1018 , fuzzyLikeFieldIgnoreTermFrequency :: IgnoreTermFrequency
1019 , fuzzyLikeFieldFuzziness :: Fuzziness
1020 , fuzzyLikeFieldPrefixLength :: PrefixLength
1021 , fuzzyLikeFieldBoost :: Boost
1022 , fuzzyLikeFieldAnalyzer :: Maybe Analyzer
1023 } deriving (Eq, Show)
1025data FuzzyLikeThisQuery =
1026 FuzzyLikeThisQuery
1027 { fuzzyLikeFields :: [FieldName]
1028 , fuzzyLikeText :: Text
1029 , fuzzyLikeMaxQueryTerms :: MaxQueryTerms
1030 , fuzzyLikeIgnoreTermFrequency :: IgnoreTermFrequency
1031 , fuzzyLikeFuzziness :: Fuzziness
1032 , fuzzyLikePrefixLength :: PrefixLength
1033 , fuzzyLikeBoost :: Boost
1034 , fuzzyLikeAnalyzer :: Maybe Analyzer
1035 } deriving (Eq, Show)
1037data FilteredQuery =
1038 FilteredQuery
1039 { filteredQuery :: Query
1040 , filteredFilter :: Filter } deriving (Eq, Show)
1042data DisMaxQuery =
1043 DisMaxQuery { disMaxQueries :: [Query]
1044 -- default 0.0
1045 , disMaxTiebreaker :: Tiebreaker
1046 , disMaxBoost :: Maybe Boost
1047 } deriving (Eq, Show)
1049data MatchQuery =
1050 MatchQuery { matchQueryField :: FieldName
1051 , matchQueryQueryString :: QueryString
1052 , matchQueryOperator :: BooleanOperator
1053 , matchQueryZeroTerms :: ZeroTermsQuery
1054 , matchQueryCutoffFrequency :: Maybe CutoffFrequency
1055 , matchQueryMatchType :: Maybe MatchQueryType
1056 , matchQueryAnalyzer :: Maybe Analyzer
1057 , matchQueryMaxExpansions :: Maybe MaxExpansions
1058 , matchQueryLenient :: Maybe Lenient
1059 , matchQueryBoost :: Maybe Boost } deriving (Eq, Show)
1061{-| 'mkMatchQuery' is a convenience function that defaults the less common parameters,
1062 enabling you to provide only the 'FieldName' and 'QueryString' to make a 'MatchQuery'
1064mkMatchQuery :: FieldName -> QueryString -> MatchQuery
1065mkMatchQuery field query = MatchQuery field query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1067data MatchQueryType =
1068 MatchPhrase
1069 | MatchPhrasePrefix deriving (Eq, Show)
1071data MultiMatchQuery =
1072 MultiMatchQuery { multiMatchQueryFields :: [FieldName]
1073 , multiMatchQueryString :: QueryString
1074 , multiMatchQueryOperator :: BooleanOperator
1075 , multiMatchQueryZeroTerms :: ZeroTermsQuery
1076 , multiMatchQueryTiebreaker :: Maybe Tiebreaker
1077 , multiMatchQueryType :: Maybe MultiMatchQueryType
1078 , multiMatchQueryCutoffFrequency :: Maybe CutoffFrequency
1079 , multiMatchQueryAnalyzer :: Maybe Analyzer
1080 , multiMatchQueryMaxExpansions :: Maybe MaxExpansions
1081 , multiMatchQueryLenient :: Maybe Lenient } deriving (Eq, Show)
1083{-| 'mkMultiMatchQuery' is a convenience function that defaults the less common parameters,
1084 enabling you to provide only the list of 'FieldName's and 'QueryString' to
1085 make a 'MultiMatchQuery'.
1088mkMultiMatchQuery :: [FieldName] -> QueryString -> MultiMatchQuery
1089mkMultiMatchQuery matchFields query =
1090 MultiMatchQuery matchFields query
1091 Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1093data MultiMatchQueryType =
1094 MultiMatchBestFields
1095 | MultiMatchMostFields
1096 | MultiMatchCrossFields
1097 | MultiMatchPhrase
1098 | MultiMatchPhrasePrefix deriving (Eq, Show)
1100data BoolQuery =
1101 BoolQuery { boolQueryMustMatch :: [Query]
1102 , boolQueryMustNotMatch :: [Query]
1103 , boolQueryShouldMatch :: [Query]
1104 , boolQueryMinimumShouldMatch :: Maybe MinimumMatch
1105 , boolQueryBoost :: Maybe Boost
1106 , boolQueryDisableCoord :: Maybe DisableCoord
1107 } deriving (Eq, Show)
1109mkBoolQuery :: [Query] -> [Query] -> [Query] -> BoolQuery
1110mkBoolQuery must mustNot should =
1111 BoolQuery must mustNot should Nothing Nothing Nothing
1113data BoostingQuery =
1114 BoostingQuery { positiveQuery :: Query
1115 , negativeQuery :: Query
1116 , negativeBoost :: Boost } deriving (Eq, Show)
1118data CommonTermsQuery =
1119 CommonTermsQuery { commonField :: FieldName
1120 , commonQuery :: QueryString
1121 , commonCutoffFrequency :: CutoffFrequency
1122 , commonLowFreqOperator :: BooleanOperator
1123 , commonHighFreqOperator :: BooleanOperator
1124 , commonMinimumShouldMatch :: Maybe CommonMinimumMatch
1125 , commonBoost :: Maybe Boost
1126 , commonAnalyzer :: Maybe Analyzer
1127 , commonDisableCoord :: Maybe DisableCoord
1128 } deriving (Eq, Show)
1130data CommonMinimumMatch =
1131 CommonMinimumMatchHighLow MinimumMatchHighLow
1132 | CommonMinimumMatch MinimumMatch
1133 deriving (Eq, Show)
1135data MinimumMatchHighLow =
1136 MinimumMatchHighLow { lowFreq :: MinimumMatch
1137 , highFreq :: MinimumMatch } deriving (Eq, Show)
1139data Filter = AndFilter [Filter] Cache
1140 | OrFilter [Filter] Cache
1141 | NotFilter Filter Cache
1142 | IdentityFilter
1143 | BoolFilter BoolMatch
1144 | ExistsFilter FieldName -- always cached
1145 | GeoBoundingBoxFilter GeoBoundingBoxConstraint
1146 | GeoDistanceFilter GeoPoint Distance DistanceType OptimizeBbox Cache
1147 | GeoDistanceRangeFilter GeoPoint DistanceRange
1148 | GeoPolygonFilter FieldName [LatLon]
1149 | IdsFilter MappingName [DocId]
1150 | LimitFilter Int
1151 | MissingFilter FieldName Existence NullValue
1152 | PrefixFilter FieldName PrefixValue Cache
1153 | QueryFilter Query Cache
1154 | RangeFilter FieldName RangeValue RangeExecution Cache
1155 | RegexpFilter FieldName Regexp RegexpFlags CacheName Cache CacheKey
1156 | TermFilter Term Cache
1157 deriving (Eq, Show)
1159data ZeroTermsQuery = ZeroTermsNone
1160 | ZeroTermsAll deriving (Eq, Show)
1162data RangeExecution = RangeExecutionIndex
1163 | RangeExecutionFielddata deriving (Eq, Show)
1165newtype Regexp = Regexp Text deriving (Eq, Show)
1167data RegexpFlags = AllRegexpFlags
1168 | NoRegexpFlags
1169 | SomeRegexpFlags (NonEmpty RegexpFlag) deriving (Eq, Show)
1171data RegexpFlag = AnyString
1172 | Automaton
1173 | Complement
1174 | Empty
1175 | Intersection
1176 | Interval deriving (Eq, Show)
1178newtype LessThan = LessThan Double deriving (Eq, Show)
1179newtype LessThanEq = LessThanEq Double deriving (Eq, Show)
1180newtype GreaterThan = GreaterThan Double deriving (Eq, Show)
1181newtype GreaterThanEq = GreaterThanEq Double deriving (Eq, Show)
1183newtype LessThanD = LessThanD UTCTime deriving (Eq, Show)
1184newtype LessThanEqD = LessThanEqD UTCTime deriving (Eq, Show)
1185newtype GreaterThanD = GreaterThanD UTCTime deriving (Eq, Show)
1186newtype GreaterThanEqD = GreaterThanEqD UTCTime deriving (Eq, Show)
1188data RangeValue = RangeDateLte LessThanEqD
1189 | RangeDateLt LessThanD
1190 | RangeDateGte GreaterThanEqD
1191 | RangeDateGt GreaterThanD
1192 | RangeDateGtLt GreaterThanD LessThanD
1193 | RangeDateGteLte GreaterThanEqD LessThanEqD
1194 | RangeDateGteLt GreaterThanEqD LessThanD
1195 | RangeDateGtLte GreaterThanD LessThanEqD
1196 | RangeDoubleLte LessThanEq
1197 | RangeDoubleLt LessThan
1198 | RangeDoubleGte GreaterThanEq
1199 | RangeDoubleGt GreaterThan
1200 | RangeDoubleGtLt GreaterThan LessThan
1201 | RangeDoubleGteLte GreaterThanEq LessThanEq
1202 | RangeDoubleGteLt GreaterThanEq LessThan
1203 | RangeDoubleGtLte GreaterThan LessThanEq
1204 deriving (Eq, Show)
1206rangeValueToPair :: RangeValue -> [Pair]
1207rangeValueToPair rv = case rv of
1208 RangeDateLte (LessThanEqD t) -> ["lte" .= t]
1209 RangeDateGte (GreaterThanEqD t) -> ["gte" .= t]
1210 RangeDateLt (LessThanD t) -> ["lt" .= t]
1211 RangeDateGt (GreaterThanD t) -> ["gt" .= t]
1212 RangeDateGteLte (GreaterThanEqD l) (LessThanEqD g) -> ["gte" .= l, "lte" .= g]
1213 RangeDateGtLte (GreaterThanD l) (LessThanEqD g) -> ["gt" .= l, "lte" .= g]
1214 RangeDateGteLt (GreaterThanEqD l) (LessThanD g) -> ["gte" .= l, "lt" .= g]
1215 RangeDateGtLt (GreaterThanD l) (LessThanD g) -> ["gt" .= l, "lt" .= g]
1216 RangeDoubleLte (LessThanEq t) -> ["lte" .= t]
1217 RangeDoubleGte (GreaterThanEq t) -> ["gte" .= t]
1218 RangeDoubleLt (LessThan t) -> ["lt" .= t]
1219 RangeDoubleGt (GreaterThan t) -> ["gt" .= t]
1220 RangeDoubleGteLte (GreaterThanEq l) (LessThanEq g) -> ["gte" .= l, "lte" .= g]
1221 RangeDoubleGtLte (GreaterThan l) (LessThanEq g) -> ["gt" .= l, "lte" .= g]
1222 RangeDoubleGteLt (GreaterThanEq l) (LessThan g) -> ["gte" .= l, "lt" .= g]
1223 RangeDoubleGtLt (GreaterThan l) (LessThan g) -> ["gt" .= l, "lt" .= g]
1225data Term = Term { termField :: Text
1226 , termValue :: Text } deriving (Eq, Show)
1228data BoolMatch = MustMatch Term Cache
1229 | MustNotMatch Term Cache
1230 | ShouldMatch [Term] Cache deriving (Eq, Show)
1232-- "memory" or "indexed"
1233data GeoFilterType = GeoFilterMemory
1234 | GeoFilterIndexed deriving (Eq, Show)
1236data LatLon = LatLon { lat :: Double
1237 , lon :: Double } deriving (Eq, Show)
1239data GeoBoundingBox =
1240 GeoBoundingBox { topLeft :: LatLon
1241 , bottomRight :: LatLon } deriving (Eq, Show)
1243data GeoBoundingBoxConstraint =
1244 GeoBoundingBoxConstraint { geoBBField :: FieldName
1245 , constraintBox :: GeoBoundingBox
1246 , bbConstraintcache :: Cache
1247 , geoType :: GeoFilterType
1248 } deriving (Eq, Show)
1250data GeoPoint =
1251 GeoPoint { geoField :: FieldName
1252 , latLon :: LatLon} deriving (Eq, Show)
1254data DistanceUnit = Miles
1255 | Yards
1256 | Feet
1257 | Inches
1258 | Kilometers
1259 | Meters
1260 | Centimeters
1261 | Millimeters
1262 | NauticalMiles deriving (Eq, Show)
1264data DistanceType = Arc
1265 | SloppyArc -- doesn't exist <1.0
1266 | Plane deriving (Eq, Show)
1268data OptimizeBbox = OptimizeGeoFilterType GeoFilterType
1269 | NoOptimizeBbox deriving (Eq, Show)
1271data Distance =
1272 Distance { coefficient :: Double
1273 , unit :: DistanceUnit } deriving (Eq, Show)
1275data DistanceRange =
1276 DistanceRange { distanceFrom :: Distance
1277 , distanceTo :: Distance } deriving (Eq, Show)
1279data SearchResult a =
1280 SearchResult { took :: Int
1281 , timedOut :: Bool
1282 , shards :: ShardResult
1283 , searchHits :: SearchHits a
1284 , aggregations :: Maybe AggregationResults
1285 , scrollId :: Maybe ScrollId } deriving (Eq, Show)
1287type ScrollId = Text -- Fixme: Newtype
1289type Score = Maybe Double
1291data SearchHits a =
1292 SearchHits { hitsTotal :: Int
1293 , maxScore :: Score
1294 , hits :: [Hit a] } deriving (Eq, Show)
1297instance Monoid (SearchHits a) where
1298 mempty = SearchHits 0 Nothing mempty
1299 mappend (SearchHits ta ma ha) (SearchHits tb mb hb) =
1300 SearchHits (ta + tb) (max ma mb) (ha <> hb)
1303data Hit a =
1304 Hit { hitIndex :: IndexName
1305 , hitType :: MappingName
1306 , hitDocId :: DocId
1307 , hitScore :: Score
1308 , hitSource :: a
1309 , hitHighlight :: Maybe HitHighlight } deriving (Eq, Show)
1311data ShardResult =
1312 ShardResult { shardTotal :: Int
1313 , shardsSuccessful :: Int
1314 , shardsFailed :: Int } deriving (Eq, Show, Generic)
1316type HitHighlight = M.Map Text [Text]
1318showText :: Show a => a -> Text
1319showText = T.pack . show
1321type Aggregations = M.Map Text Aggregation
1323emptyAggregations :: Aggregations
1324emptyAggregations = M.empty
1326mkAggregations :: Text -> Aggregation -> Aggregations
1327mkAggregations name aggregation = M.insert name aggregation emptyAggregations
1329data TermOrder = TermOrder{ termSortField :: Text
1330 , termSortOrder :: SortOrder } deriving (Eq, Show)
1332data TermInclusion = TermInclusion Text
1333 | TermPattern Text Text deriving (Eq, Show)
1335data CollectionMode = BreadthFirst
1336 | DepthFirst deriving (Eq, Show)
1338data ExecutionHint = Ordinals
1339 | GlobalOrdinals
1340 | GlobalOrdinalsHash
1341 | GlobalOrdinalsLowCardinality
1342 | Map deriving (Eq, Show)
1344data TimeInterval = Weeks
1345 | Days
1346 | Hours
1347 | Minutes
1348 | Seconds deriving (Eq)
1350data Interval = Year
1351 | Quarter
1352 | Month
1353 | Week
1354 | Day
1355 | Hour
1356 | Minute
1357 | Second
1358 | FractionalInterval Float TimeInterval deriving (Eq, Show)
1360data Aggregation = TermsAgg TermsAggregation
1361 | DateHistogramAgg DateHistogramAggregation
1362 | ValueCountAgg ValueCountAggregation
1363 | FilterAgg FilterAggregation deriving (Eq, Show)
1366data TermsAggregation = TermsAggregation { term :: Either Text Text
1367 , termInclude :: Maybe TermInclusion
1368 , termExclude :: Maybe TermInclusion
1369 , termOrder :: Maybe TermOrder
1370 , termMinDocCount :: Maybe Int
1371 , termSize :: Maybe Int
1372 , termShardSize :: Maybe Int
1373 , termCollectMode :: Maybe CollectionMode
1374 , termExecutionHint :: Maybe ExecutionHint
1375 , termAggs :: Maybe Aggregations
1376 } deriving (Eq, Show)
1378data DateHistogramAggregation = DateHistogramAggregation { dateField :: FieldName
1379 , dateInterval :: Interval
1380 , dateFormat :: Maybe Text
1381 -- pre and post deprecated in 1.5
1382 , datePreZone :: Maybe Text
1383 , datePostZone :: Maybe Text
1384 , datePreOffset :: Maybe Text
1385 , datePostOffset :: Maybe Text
1386 , dateAggs :: Maybe Aggregations
1387 } deriving (Eq, Show)
1389-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html> for more information.
1390data ValueCountAggregation = FieldValueCount FieldName
1391 | ScriptValueCount Script deriving (Eq, Show)
1393-- | 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.
1394data FilterAggregation = FilterAggregation { faFilter :: Filter
1395 , faAggs :: Maybe Aggregations} deriving (Eq, Show)
1397mkTermsAggregation :: Text -> TermsAggregation
1398mkTermsAggregation t = TermsAggregation (Left t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1400mkTermsScriptAggregation :: Text -> TermsAggregation
1401mkTermsScriptAggregation t = TermsAggregation (Right t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1403mkDateHistogram :: FieldName -> Interval -> DateHistogramAggregation
1404mkDateHistogram t i = DateHistogramAggregation t i Nothing Nothing Nothing Nothing Nothing Nothing
1406instance ToJSON TermOrder where
1407 toJSON (TermOrder termSortField termSortOrder) = object [termSortField .= termSortOrder]
1409instance ToJSON TermInclusion where
1410 toJSON (TermInclusion x) = toJSON x
1411 toJSON (TermPattern pattern flags) = omitNulls [ "pattern" .= pattern,
1412 "flags" .= flags]
1414instance ToJSON CollectionMode where
1415 toJSON BreadthFirst = "breadth_first"
1416 toJSON DepthFirst = "depth_first"
1418instance ToJSON ExecutionHint where
1419 toJSON Ordinals = "ordinals"
1420 toJSON GlobalOrdinals = "global_ordinals"
1421 toJSON GlobalOrdinalsHash = "global_ordinals_hash"
1422 toJSON GlobalOrdinalsLowCardinality = "global_ordinals_low_cardinality"
1423 toJSON Map = "map"
1425instance ToJSON Interval where
1426 toJSON Year = "year"
1427 toJSON Quarter = "quarter"
1428 toJSON Month = "month"
1429 toJSON Week = "week"
1430 toJSON Day = "day"
1431 toJSON Hour = "hour"
1432 toJSON Minute = "minute"
1433 toJSON Second = "second"
1434 toJSON (FractionalInterval fraction interval) = toJSON $ show fraction ++ show interval
1436instance Show TimeInterval where
1437 show Weeks = "w"
1438 show Days = "d"
1439 show Hours = "h"
1440 show Minutes = "m"
1441 show Seconds = "s"
1443instance ToJSON Aggregation where
1444 toJSON (TermsAgg (TermsAggregation term include exclude order minDocCount size shardSize collectMode executionHint termAggs)) =
1445 omitNulls ["terms" .= omitNulls [ toJSON' term,
1446 "include" .= include,
1447 "exclude" .= exclude,
1448 "order" .= order,
1449 "min_doc_count" .= minDocCount,
1450 "size" .= size,
1451 "shard_size" .= shardSize,
1452 "collect_mode" .= collectMode,
1453 "execution_hint" .= executionHint
1454 ],
1455 "aggs" .= termAggs ]
1456 where
1457 toJSON' x = case x of { Left y -> "field" .= y; Right y -> "script" .= y }
1459 toJSON (DateHistogramAgg (DateHistogramAggregation field interval format preZone postZone preOffset postOffset dateHistoAggs)) =
1460 omitNulls ["date_histogram" .= omitNulls [ "field" .= field,
1461 "interval" .= interval,
1462 "format" .= format,
1463 "pre_zone" .= preZone,
1464 "post_zone" .= postZone,
1465 "pre_offset" .= preOffset,
1466 "post_offset" .= postOffset
1467 ],
1468 "aggs" .= dateHistoAggs ]
1469 toJSON (ValueCountAgg a) = object ["value_count" .= v]
1470 where v = case a of
1471 (FieldValueCount (FieldName n)) -> object ["field" .= n]
1472 (ScriptValueCount (Script s)) -> object ["script" .= s]
1473 toJSON (FilterAgg (FilterAggregation filt ags)) =
1474 omitNulls [ "filter" .= filt
1475 , "aggs" .= ags]
1477type AggregationResults = M.Map Text Value
1479class BucketAggregation a where
1480 key :: a -> Text
1481 docCount :: a -> Int
1482 aggs :: a -> Maybe AggregationResults
1485data Bucket a = Bucket { buckets :: [a]} deriving (Show)
1487data TermsResult = TermsResult { termKey :: Text
1488 , termsDocCount :: Int
1489 , termsAggs :: Maybe AggregationResults } deriving (Show)
1491data DateHistogramResult = DateHistogramResult { dateKey :: Int
1492 , dateKeyStr :: Maybe Text
1493 , dateDocCount :: Int
1494 , dateHistogramAggs :: Maybe AggregationResults } deriving (Show)
1496toTerms :: Text -> AggregationResults -> Maybe (Bucket TermsResult)
1497toTerms t a = M.lookup t a >>= deserialize
1498 where deserialize = parseMaybe parseJSON
1500toDateHistogram :: Text -> AggregationResults -> Maybe (Bucket DateHistogramResult)
1501toDateHistogram t a = M.lookup t a >>= deserialize
1502 where deserialize = parseMaybe parseJSON
1504instance BucketAggregation TermsResult where
1505 key = termKey
1506 docCount = termsDocCount
1507 aggs = termsAggs
1509instance BucketAggregation DateHistogramResult where
1510 key = showText . dateKey
1511 docCount = dateDocCount
1512 aggs = dateHistogramAggs
1514instance (FromJSON a, BucketAggregation a) => FromJSON (Bucket a) where
1515 parseJSON (Object v) = Bucket <$>
1516 v .: "buckets"
1517 parseJSON _ = mempty
1519instance FromJSON TermsResult where
1520 parseJSON (Object v) = TermsResult <$>
1521 v .: "key" <*>
1522 v .: "doc_count" <*>
1523 v .:? "aggregations"
1524 parseJSON _ = mempty
1526instance FromJSON DateHistogramResult where
1527 parseJSON (Object v) = DateHistogramResult <$>
1528 v .: "key" <*>
1529 v .:? "key_as_string" <*>
1530 v .: "doc_count" <*>
1531 v .:? "aggregations"
1532 parseJSON _ = mempty
1534instance Monoid Filter where
1535 mempty = IdentityFilter
1536 mappend a b = AndFilter [a, b] defaultCache
1538instance Seminearring Filter where
1539 a <||> b = OrFilter [a, b] defaultCache
1541instance ToJSON Filter where
1542 toJSON (AndFilter filters cache) =
1543 object ["and" .=
1544 object [ "filters" .= fmap toJSON filters
1545 , "_cache" .= cache]]
1547 toJSON (OrFilter filters cache) =
1548 object ["or" .=
1549 object [ "filters" .= fmap toJSON filters
1550 , "_cache" .= cache]]
1552 toJSON (NotFilter notFilter cache) =
1553 object ["not" .=
1554 object ["filter" .= notFilter
1555 , "_cache" .= cache]]
1557 toJSON (IdentityFilter) =
1558 object ["match_all" .= object []]
1560 toJSON (TermFilter (Term termFilterField termFilterValue) cache) =
1561 object ["term" .= object base]
1562 where base = [termFilterField .= termFilterValue,
1563 "_cache" .= cache]
1565 toJSON (ExistsFilter (FieldName fieldName)) =
1566 object ["exists" .= object
1567 ["field" .= fieldName]]
1569 toJSON (BoolFilter boolMatch) =
1570 object ["bool" .= boolMatch]
1572 toJSON (GeoBoundingBoxFilter bbConstraint) =
1573 object ["geo_bounding_box" .= bbConstraint]
1575 toJSON (GeoDistanceFilter (GeoPoint (FieldName distanceGeoField) geoDistLatLon)
1576 distance distanceType optimizeBbox cache) =
1577 object ["geo_distance" .=
1578 object ["distance" .= distance
1579 , "distance_type" .= distanceType
1580 , "optimize_bbox" .= optimizeBbox
1581 , distanceGeoField .= geoDistLatLon
1582 , "_cache" .= cache]]
1584 toJSON (GeoDistanceRangeFilter (GeoPoint (FieldName gddrField) drLatLon)
1585 (DistanceRange geoDistRangeDistFrom drDistanceTo)) =
1586 object ["geo_distance_range" .=
1587 object ["from" .= geoDistRangeDistFrom
1588 , "to" .= drDistanceTo
1589 , gddrField .= drLatLon]]
1591 toJSON (GeoPolygonFilter (FieldName geoPolygonFilterField) latLons) =
1592 object ["geo_polygon" .=
1593 object [geoPolygonFilterField .=
1594 object ["points" .= fmap toJSON latLons]]]
1596 toJSON (IdsFilter (MappingName mappingName) values) =
1597 object ["ids" .=
1598 object ["type" .= mappingName
1599 , "values" .= fmap unpackId values]]
1601 toJSON (LimitFilter limit) =
1602 object ["limit" .= object ["value" .= limit]]
1604 toJSON (MissingFilter (FieldName fieldName) (Existence existence) (NullValue nullValue)) =
1605 object ["missing" .=
1606 object ["field" .= fieldName
1607 , "existence" .= existence
1608 , "null_value" .= nullValue]]
1610 toJSON (PrefixFilter (FieldName fieldName) fieldValue cache) =
1611 object ["prefix" .=
1612 object [fieldName .= fieldValue
1613 , "_cache" .= cache]]
1615 toJSON (QueryFilter query False) =
1616 object ["query" .= toJSON query ]
1617 toJSON (QueryFilter query True) =
1618 object ["fquery" .=
1619 object [ "query" .= toJSON query
1620 , "_cache" .= True ]]
1622 toJSON (RangeFilter (FieldName fieldName) rangeValue rangeExecution cache) =
1623 object ["range" .=
1624 object [ fieldName .= object (rangeValueToPair rangeValue)
1625 , "execution" .= rangeExecution
1626 , "_cache" .= cache]]
1628 toJSON (RegexpFilter (FieldName fieldName)
1629 (Regexp regexText) flags (CacheName cacheName) cache (CacheKey cacheKey)) =
1630 object ["regexp" .=
1631 object [fieldName .=
1632 object ["value" .= regexText
1633 , "flags" .= flags]
1634 , "_name" .= cacheName
1635 , "_cache" .= cache
1636 , "_cache_key" .= cacheKey]]
1638instance ToJSON GeoPoint where
1639 toJSON (GeoPoint (FieldName geoPointField) geoPointLatLon) =
1640 object [ geoPointField .= geoPointLatLon ]
1643instance ToJSON Query where
1644 toJSON (TermQuery (Term termQueryField termQueryValue) boost) =
1645 object [ "term" .=
1646 object [termQueryField .= object merged]]
1647 where
1648 base = [ "value" .= termQueryValue ]
1649 boosted = maybe [] (return . ("boost" .=)) boost
1650 merged = mappend base boosted
1652 toJSON (TermsQuery terms) =
1653 object [ "terms" .= object conjoined ]
1654 where conjoined = [ getTermsField terms .=
1655 fmap (toJSON . getTermValue) (toList terms)]
1656 getTermsField ((Term f _ ) :| _) = f
1657 getTermValue (Term _ v) = v
1658 toJSON (IdsQuery idsQueryMappingName docIds) =
1659 object [ "ids" .= object conjoined ]
1660 where conjoined = [ "type" .= idsQueryMappingName
1661 , "values" .= fmap toJSON docIds ]
1663 toJSON (QueryQueryStringQuery qQueryStringQuery) =
1664 object [ "query_string" .= qQueryStringQuery ]
1666 toJSON (QueryMatchQuery matchQuery) =
1667 object [ "match" .= matchQuery ]
1669 toJSON (QueryMultiMatchQuery multiMatchQuery) =
1670 toJSON multiMatchQuery
1672 toJSON (QueryBoolQuery boolQuery) =
1673 object [ "bool" .= boolQuery ]
1675 toJSON (QueryBoostingQuery boostingQuery) =
1676 object [ "boosting" .= boostingQuery ]
1678 toJSON (QueryCommonTermsQuery commonTermsQuery) =
1679 object [ "common" .= commonTermsQuery ]
1681 toJSON (ConstantScoreFilter csFilter boost) =
1682 object [ "constant_score" .= csFilter
1683 , "boost" .= boost]
1685 toJSON (ConstantScoreQuery query boost) =
1686 object [ "constant_score" .= query
1687 , "boost" .= boost]
1689 toJSON (QueryDisMaxQuery disMaxQuery) =
1690 object [ "dis_max" .= disMaxQuery ]
1692 toJSON (QueryFilteredQuery qFilteredQuery) =
1693 object [ "filtered" .= qFilteredQuery ]
1695 toJSON (QueryFuzzyLikeThisQuery fuzzyQuery) =
1696 object [ "fuzzy_like_this" .= fuzzyQuery ]
1698 toJSON (QueryFuzzyLikeFieldQuery fuzzyFieldQuery) =
1699 object [ "fuzzy_like_this_field" .= fuzzyFieldQuery ]
1701 toJSON (QueryFuzzyQuery fuzzyQuery) =
1702 object [ "fuzzy" .= fuzzyQuery ]
1704 toJSON (QueryHasChildQuery childQuery) =
1705 object [ "has_child" .= childQuery ]
1707 toJSON (QueryHasParentQuery parentQuery) =
1708 object [ "has_parent" .= parentQuery ]
1710 toJSON (QueryIndicesQuery qIndicesQuery) =
1711 object [ "indices" .= qIndicesQuery ]
1713 toJSON (MatchAllQuery boost) =
1714 object [ "match_all" .= omitNulls [ "boost" .= boost ] ]
1716 toJSON (QueryMoreLikeThisQuery query) =
1717 object [ "more_like_this" .= query ]
1719 toJSON (QueryMoreLikeThisFieldQuery query) =
1720 object [ "more_like_this_field" .= query ]
1722 toJSON (QueryNestedQuery query) =
1723 object [ "nested" .= query ]
1725 toJSON (QueryPrefixQuery query) =
1726 object [ "prefix" .= query ]
1728 toJSON (QueryRangeQuery query) =
1729 object [ "range" .= query ]
1731 toJSON (QueryRegexpQuery query) =
1732 object [ "regexp" .= query ]
1734 toJSON (QuerySimpleQueryStringQuery query) =
1735 object [ "simple_query_string" .= query ]
1738omitNulls :: [(Text, Value)] -> Value
1739omitNulls = object . filter notNull where
1740 notNull (_, Null) = False
1741 notNull (_, Array a) = (not . V.null) a
1742 notNull _ = True
1745instance ToJSON SimpleQueryStringQuery where
1746 toJSON SimpleQueryStringQuery {..} =
1747 omitNulls (base ++ maybeAdd)
1748 where base = [ "query" .= simpleQueryStringQuery ]
1749 maybeAdd = [ "fields" .= simpleQueryStringField
1750 , "default_operator" .= simpleQueryStringOperator
1751 , "analyzer" .= simpleQueryStringAnalyzer
1752 , "flags" .= simpleQueryStringFlags
1753 , "lowercase_expanded_terms" .= simpleQueryStringLowercaseExpanded
1754 , "locale" .= simpleQueryStringLocale ]
1757instance ToJSON FieldOrFields where
1758 toJSON (FofField fieldName) =
1759 toJSON fieldName
1760 toJSON (FofFields fieldNames) =
1761 toJSON fieldNames
1763instance ToJSON SimpleQueryFlag where
1764 toJSON SimpleQueryAll = "ALL"
1765 toJSON SimpleQueryNone = "NONE"
1766 toJSON SimpleQueryAnd = "AND"
1767 toJSON SimpleQueryOr = "OR"
1768 toJSON SimpleQueryPrefix = "PREFIX"
1769 toJSON SimpleQueryPhrase = "PHRASE"
1770 toJSON SimpleQueryPrecedence = "PRECEDENCE"
1771 toJSON SimpleQueryEscape = "ESCAPE"
1772 toJSON SimpleQueryWhitespace = "WHITESPACE"
1773 toJSON SimpleQueryFuzzy = "FUZZY"
1774 toJSON SimpleQueryNear = "NEAR"
1775 toJSON SimpleQuerySlop = "SLOP"
1778instance ToJSON RegexpQuery where
1779 toJSON (RegexpQuery (FieldName rqQueryField)
1780 (Regexp regexpQueryQuery) rqQueryFlags
1781 rqQueryBoost) =
1782 object [ rqQueryField .= omitNulls base ]
1783 where base = [ "value" .= regexpQueryQuery
1784 , "flags" .= rqQueryFlags
1785 , "boost" .= rqQueryBoost ]
1788instance ToJSON QueryStringQuery where
1789 toJSON (QueryStringQuery qsQueryString
1790 qsDefaultField qsOperator
1791 qsAnalyzer qsAllowWildcard
1792 qsLowercaseExpanded qsEnablePositionIncrements
1793 qsFuzzyMaxExpansions qsFuzziness
1794 qsFuzzyPrefixLength qsPhraseSlop
1795 qsBoost qsAnalyzeWildcard
1796 qsGeneratePhraseQueries qsMinimumShouldMatch
1797 qsLenient qsLocale) =
1798 omitNulls base
1799 where
1800 base = [ "query" .= qsQueryString
1801 , "default_field" .= qsDefaultField
1802 , "default_operator" .= qsOperator
1803 , "analyzer" .= qsAnalyzer
1804 , "allow_leading_wildcard" .= qsAllowWildcard
1805 , "lowercase_expanded_terms" .= qsLowercaseExpanded
1806 , "enable_position_increments" .= qsEnablePositionIncrements
1807 , "fuzzy_max_expansions" .= qsFuzzyMaxExpansions
1808 , "fuzziness" .= qsFuzziness
1809 , "fuzzy_prefix_length" .= qsFuzzyPrefixLength
1810 , "phrase_slop" .= qsPhraseSlop
1811 , "boost" .= qsBoost
1812 , "analyze_wildcard" .= qsAnalyzeWildcard
1813 , "auto_generate_phrase_queries" .= qsGeneratePhraseQueries
1814 , "minimum_should_match" .= qsMinimumShouldMatch
1815 , "lenient" .= qsLenient
1816 , "locale" .= qsLocale ]
1819instance ToJSON RangeQuery where
1820 toJSON (RangeQuery (FieldName fieldName) range boost) =
1821 object [ fieldName .= conjoined ]
1822 where conjoined = [ "boost" .= boost ] ++ (rangeValueToPair range)
1825instance ToJSON PrefixQuery where
1826 toJSON (PrefixQuery (FieldName fieldName) queryValue boost) =
1827 object [ fieldName .= omitNulls base ]
1828 where base = [ "value" .= queryValue
1829 , "boost" .= boost ]
1832instance ToJSON NestedQuery where
1833 toJSON (NestedQuery nqPath nqScoreType nqQuery) =
1834 object [ "path" .= nqPath
1835 , "score_mode" .= nqScoreType
1836 , "query" .= nqQuery ]
1839instance ToJSON MoreLikeThisFieldQuery where
1840 toJSON (MoreLikeThisFieldQuery text (FieldName fieldName)
1841 percent mtf mqt stopwords mindf maxdf
1842 minwl maxwl boostTerms boost analyzer) =
1843 object [ fieldName .= omitNulls base ]
1844 where base = [ "like_text" .= text
1845 , "percent_terms_to_match" .= percent
1846 , "min_term_freq" .= mtf
1847 , "max_query_terms" .= mqt
1848 , "stop_words" .= stopwords
1849 , "min_doc_freq" .= mindf
1850 , "max_doc_freq" .= maxdf
1851 , "min_word_length" .= minwl
1852 , "max_word_length" .= maxwl
1853 , "boost_terms" .= boostTerms
1854 , "boost" .= boost
1855 , "analyzer" .= analyzer ]
1858instance ToJSON MoreLikeThisQuery where
1859 toJSON (MoreLikeThisQuery text fields percent
1860 mtf mqt stopwords mindf maxdf
1861 minwl maxwl boostTerms boost analyzer) =
1862 omitNulls base
1863 where base = [ "like_text" .= text
1864 , "fields" .= fields
1865 , "percent_terms_to_match" .= percent
1866 , "min_term_freq" .= mtf
1867 , "max_query_terms" .= mqt
1868 , "stop_words" .= stopwords
1869 , "min_doc_freq" .= mindf
1870 , "max_doc_freq" .= maxdf
1871 , "min_word_length" .= minwl
1872 , "max_word_length" .= maxwl
1873 , "boost_terms" .= boostTerms
1874 , "boost" .= boost
1875 , "analyzer" .= analyzer ]
1878instance ToJSON IndicesQuery where
1879 toJSON (IndicesQuery indices query noMatch) =
1880 omitNulls [ "indices" .= indices
1881 , "no_match_query" .= noMatch
1882 , "query" .= query ]
1885instance ToJSON HasParentQuery where
1886 toJSON (HasParentQuery queryType query scoreType) =
1887 omitNulls [ "parent_type" .= queryType
1888 , "score_type" .= scoreType
1889 , "query" .= query ]
1892instance ToJSON HasChildQuery where
1893 toJSON (HasChildQuery queryType query scoreType) =
1894 omitNulls [ "query" .= query
1895 , "score_type" .= scoreType
1896 , "type" .= queryType ]
1899instance ToJSON FuzzyQuery where
1900 toJSON (FuzzyQuery (FieldName fieldName) queryText
1901 prefixLength maxEx fuzziness boost) =
1902 object [ fieldName .= omitNulls base ]
1903 where base = [ "value" .= queryText
1904 , "fuzziness" .= fuzziness
1905 , "prefix_length" .= prefixLength
1906 , "boost" .= boost
1907 , "max_expansions" .= maxEx ]
1910instance ToJSON FuzzyLikeFieldQuery where
1911 toJSON (FuzzyLikeFieldQuery (FieldName fieldName)
1912 fieldText maxTerms ignoreFreq fuzziness prefixLength
1913 boost analyzer) =
1914 object [ fieldName .=
1915 omitNulls [ "like_text" .= fieldText
1916 , "max_query_terms" .= maxTerms
1917 , "ignore_tf" .= ignoreFreq
1918 , "fuzziness" .= fuzziness
1919 , "prefix_length" .= prefixLength
1920 , "analyzer" .= analyzer
1921 , "boost" .= boost ]]
1924instance ToJSON FuzzyLikeThisQuery where
1925 toJSON (FuzzyLikeThisQuery fields text maxTerms
1926 ignoreFreq fuzziness prefixLength boost analyzer) =
1927 omitNulls base
1928 where base = [ "fields" .= fields
1929 , "like_text" .= text
1930 , "max_query_terms" .= maxTerms
1931 , "ignore_tf" .= ignoreFreq
1932 , "fuzziness" .= fuzziness
1933 , "prefix_length" .= prefixLength
1934 , "analyzer" .= analyzer
1935 , "boost" .= boost ]
1938instance ToJSON FilteredQuery where
1939 toJSON (FilteredQuery query fFilter) =
1940 object [ "query" .= query
1941 , "filter" .= fFilter ]
1944instance ToJSON DisMaxQuery where
1945 toJSON (DisMaxQuery queries tiebreaker boost) =
1946 omitNulls base
1947 where base = [ "queries" .= queries
1948 , "boost" .= boost
1949 , "tie_breaker" .= tiebreaker ]
1952instance ToJSON CommonTermsQuery where
1953 toJSON (CommonTermsQuery (FieldName fieldName)
1954 (QueryString query) cf lfo hfo msm
1955 boost analyzer disableCoord) =
1956 object [fieldName .= omitNulls base ]
1957 where base = [ "query" .= query
1958 , "cutoff_frequency" .= cf
1959 , "low_freq_operator" .= lfo
1960 , "minimum_should_match" .= msm
1961 , "boost" .= boost
1962 , "analyzer" .= analyzer
1963 , "disable_coord" .= disableCoord
1964 , "high_freq_operator" .= hfo ]
1967instance ToJSON CommonMinimumMatch where
1968 toJSON (CommonMinimumMatch mm) = toJSON mm
1969 toJSON (CommonMinimumMatchHighLow (MinimumMatchHighLow lowF highF)) =
1970 object [ "low_freq" .= lowF
1971 , "high_freq" .= highF ]
1973instance ToJSON BoostingQuery where
1974 toJSON (BoostingQuery bqPositiveQuery bqNegativeQuery bqNegativeBoost) =
1975 object [ "positive" .= bqPositiveQuery
1976 , "negative" .= bqNegativeQuery
1977 , "negative_boost" .= bqNegativeBoost ]
1980instance ToJSON BoolQuery where
1981 toJSON (BoolQuery mustM notM shouldM bqMin boost disableCoord) =
1982 omitNulls base
1983 where base = [ "must" .= mustM
1984 , "must_not" .= notM
1985 , "should" .= shouldM
1986 , "minimum_should_match" .= bqMin
1987 , "boost" .= boost
1988 , "disable_coord" .= disableCoord ]
1991instance ToJSON MatchQuery where
1992 toJSON (MatchQuery (FieldName fieldName)
1993 (QueryString mqQueryString) booleanOperator
1994 zeroTermsQuery cutoffFrequency matchQueryType
1995 analyzer maxExpansions lenient boost) =
1996 object [ fieldName .= omitNulls base ]
1997 where base = [ "query" .= mqQueryString
1998 , "operator" .= booleanOperator
1999 , "zero_terms_query" .= zeroTermsQuery
2000 , "cutoff_frequency" .= cutoffFrequency
2001 , "type" .= matchQueryType
2002 , "analyzer" .= analyzer
2003 , "max_expansions" .= maxExpansions
2004 , "lenient" .= lenient
2005 , "boost" .= boost ]
2008instance ToJSON MultiMatchQuery where
2009 toJSON (MultiMatchQuery fields (QueryString query) boolOp
2010 ztQ tb mmqt cf analyzer maxEx lenient) =
2011 object ["multi_match" .= omitNulls base]
2012 where base = [ "fields" .= fmap toJSON fields
2013 , "query" .= query
2014 , "operator" .= boolOp
2015 , "zero_terms_query" .= ztQ
2016 , "tiebreaker" .= tb
2017 , "type" .= mmqt
2018 , "cutoff_frequency" .= cf
2019 , "analyzer" .= analyzer
2020 , "max_expansions" .= maxEx
2021 , "lenient" .= lenient ]
2024instance ToJSON MultiMatchQueryType where
2025 toJSON MultiMatchBestFields = "best_fields"
2026 toJSON MultiMatchMostFields = "most_fields"
2027 toJSON MultiMatchCrossFields = "cross_fields"
2028 toJSON MultiMatchPhrase = "phrase"
2029 toJSON MultiMatchPhrasePrefix = "phrase_prefix"
2031instance ToJSON BooleanOperator where
2032 toJSON And = String "and"
2033 toJSON Or = String "or"
2035instance ToJSON ZeroTermsQuery where
2036 toJSON ZeroTermsNone = String "none"
2037 toJSON ZeroTermsAll = String "all"
2039instance ToJSON MatchQueryType where
2040 toJSON MatchPhrase = "phrase"
2041 toJSON MatchPhrasePrefix = "phrase_prefix"
2043instance ToJSON FieldName where
2044 toJSON (FieldName fieldName) = String fieldName
2046instance ToJSON ReplicaCount
2047instance ToJSON ShardCount
2048instance ToJSON CutoffFrequency
2049instance ToJSON Analyzer
2050instance ToJSON MaxExpansions
2051instance ToJSON Lenient
2052instance ToJSON Boost
2053instance ToJSON Version
2054instance ToJSON Tiebreaker
2055instance ToJSON MinimumMatch
2056instance ToJSON DisableCoord
2057instance ToJSON PrefixLength
2058instance ToJSON Fuzziness
2059instance ToJSON IgnoreTermFrequency
2060instance ToJSON MaxQueryTerms
2061instance ToJSON TypeName
2062instance ToJSON IndexName
2063instance ToJSON TemplateName
2064instance ToJSON TemplatePattern
2065instance ToJSON BoostTerms
2066instance ToJSON MaxWordLength
2067instance ToJSON MinWordLength
2068instance ToJSON MaxDocFrequency
2069instance ToJSON MinDocFrequency
2070instance ToJSON PhraseSlop
2071instance ToJSON StopWord
2072instance ToJSON QueryPath
2073instance ToJSON MinimumTermFrequency
2074instance ToJSON PercentMatch
2075instance ToJSON MappingName
2076instance ToJSON DocId
2077instance ToJSON QueryString
2078instance ToJSON AllowLeadingWildcard
2079instance ToJSON LowercaseExpanded
2080instance ToJSON AnalyzeWildcard
2081instance ToJSON GeneratePhraseQueries
2082instance ToJSON Locale
2083instance ToJSON EnablePositionIncrements
2084instance FromJSON Version
2085instance FromJSON IndexName
2086instance FromJSON MappingName
2087instance FromJSON DocId
2090instance FromJSON Status where
2091 parseJSON (Object v) = Status <$>
2092 v .:? "ok" <*>
2093 v .: "status" <*>
2094 v .: "name" <*>
2095 v .: "version" <*>
2096 v .: "tagline"
2097 parseJSON _ = empty
2100instance ToJSON IndexSettings where
2101 toJSON (IndexSettings s r) = object ["settings" .=
2102 object ["index" .=
2103 object ["number_of_shards" .= s, "number_of_replicas" .= r]
2107instance ToJSON IndexTemplate where
2108 toJSON (IndexTemplate p s m) = merge
2109 (object [ "template" .= p
2110 , "mappings" .= foldl' merge (object []) m
2111 ])
2112 (toJSON s)
2113 where
2114 merge (Object o1) (Object o2) = toJSON $ HM.union o1 o2
2115 merge o Null = o
2116 merge _ _ = undefined
2118instance (FromJSON a) => FromJSON (EsResult a) where
2119 parseJSON jsonVal@(Object v) = do
2120 found <- v .:? "found" .!= False
2121 fr <- if found
2122 then parseJSON jsonVal
2123 else return Nothing
2124 EsResult <$> v .: "_index" <*>
2125 v .: "_type" <*>
2126 v .: "_id" <*>
2127 pure fr
2128 parseJSON _ = empty
2130instance (FromJSON a) => FromJSON (EsResultFound a) where
2131 parseJSON (Object v) = EsResultFound <$>
2132 v .: "_version" <*>
2133 v .: "_source"
2134 parseJSON _ = empty
2136instance ToJSON Search where
2137 toJSON (Search query sFilter sort searchAggs highlight sTrackSortScores sFrom sSize _ sFields sSource) =
2138 omitNulls [ "query" .= query
2139 , "filter" .= sFilter
2140 , "sort" .= sort
2141 , "aggregations" .= searchAggs
2142 , "highlight" .= highlight
2143 , "from" .= sFrom
2144 , "size" .= sSize
2145 , "track_scores" .= sTrackSortScores
2146 , "fields" .= sFields
2147 , "_source" .= sSource]
2150instance ToJSON Source where
2151 toJSON NoSource = toJSON False
2152 toJSON (SourcePatterns patterns) = toJSON patterns
2153 toJSON (SourceIncludeExclude incl excl) = object [ "include" .= incl, "exclude" .= excl ]
2155instance ToJSON PatternOrPatterns where
2156 toJSON (PopPattern pattern) = toJSON pattern
2157 toJSON (PopPatterns patterns) = toJSON patterns
2159instance ToJSON Include where
2160 toJSON (Include patterns) = toJSON patterns
2162instance ToJSON Exclude where
2163 toJSON (Exclude patterns) = toJSON patterns
2165instance ToJSON Pattern where
2166 toJSON (Pattern pattern) = toJSON pattern
2169instance ToJSON FieldHighlight where
2170 toJSON (FieldHighlight (FieldName fName) (Just fSettings)) =
2171 object [ fName .= fSettings ]
2172 toJSON (FieldHighlight (FieldName fName) Nothing) =
2173 object [ fName .= emptyObject ]
2175instance ToJSON Highlights where
2176 toJSON (Highlights global fields) =
2177 omitNulls (("fields" .= fields)
2178 : highlightSettingsPairs global)
2180instance ToJSON HighlightSettings where
2181 toJSON hs = omitNulls (highlightSettingsPairs (Just hs))
2183highlightSettingsPairs :: Maybe HighlightSettings -> [Pair]
2184highlightSettingsPairs Nothing = []
2185highlightSettingsPairs (Just (Plain plh)) = plainHighPairs (Just plh)
2186highlightSettingsPairs (Just (Postings ph)) = postHighPairs (Just ph)
2187highlightSettingsPairs (Just (FastVector fvh)) = fastVectorHighPairs (Just fvh)
2190plainHighPairs :: Maybe PlainHighlight -> [Pair]
2191plainHighPairs Nothing = []
2192plainHighPairs (Just (PlainHighlight plCom plNonPost)) =
2193 [ "type" .= String "plain"]
2194 ++ commonHighlightPairs plCom
2195 ++ nonPostingsToPairs plNonPost
2197postHighPairs :: Maybe PostingsHighlight -> [Pair]
2198postHighPairs Nothing = []
2199postHighPairs (Just (PostingsHighlight pCom)) =
2200 ("type" .= String "postings")
2201 : commonHighlightPairs pCom
2203fastVectorHighPairs :: Maybe FastVectorHighlight -> [Pair]
2204fastVectorHighPairs Nothing = []
2205fastVectorHighPairs (Just
2206 (FastVectorHighlight fvCom fvNonPostSettings fvBoundChars
2207 fvBoundMaxScan fvFragOff fvMatchedFields
2208 fvPhraseLim)) =
2209 [ "type" .= String "fvh"
2210 , "boundary_chars" .= fvBoundChars
2211 , "boundary_max_scan" .= fvBoundMaxScan
2212 , "fragment_offset" .= fvFragOff
2213 , "matched_fields" .= fvMatchedFields
2214 , "phraseLimit" .= fvPhraseLim]
2215 ++ commonHighlightPairs fvCom
2216 ++ nonPostingsToPairs fvNonPostSettings
2218commonHighlightPairs :: Maybe CommonHighlight -> [Pair]
2219commonHighlightPairs Nothing = []
2220commonHighlightPairs (Just (CommonHighlight chScore chForceSource chTag chEncoder
2221 chNoMatchSize chHighlightQuery
2222 chRequireFieldMatch)) =
2223 [ "order" .= chScore
2224 , "force_source" .= chForceSource
2225 , "encoder" .= chEncoder
2226 , "no_match_size" .= chNoMatchSize
2227 , "highlight_query" .= chHighlightQuery
2228 , "require_fieldMatch" .= chRequireFieldMatch]
2229 ++ highlightTagToPairs chTag
2232nonPostingsToPairs :: Maybe NonPostings -> [Pair]
2233nonPostingsToPairs Nothing = []
2234nonPostingsToPairs (Just (NonPostings npFragSize npNumOfFrags)) =
2235 [ "fragment_size" .= npFragSize
2236 , "number_of_fragments" .= npNumOfFrags]
2240instance ToJSON HighlightEncoder where
2241 toJSON DefaultEncoder = String "default"
2242 toJSON HTMLEncoder = String "html"
2244highlightTagToPairs :: Maybe HighlightTag -> [Pair]
2245highlightTagToPairs (Just (TagSchema _)) = [ "scheme" .= String "default"]
2246highlightTagToPairs (Just (CustomTags (pre, post))) = [ "pre_tags" .= pre
2247 , "post_tags" .= post]
2248highlightTagToPairs Nothing = []
2250instance ToJSON SortSpec where
2251 toJSON (DefaultSortSpec
2252 (DefaultSort (FieldName dsSortFieldName) dsSortOrder dsIgnoreUnmapped
2253 dsSortMode dsMissingSort dsNestedFilter)) =
2254 object [dsSortFieldName .= omitNulls base] where
2255 base = [ "order" .= dsSortOrder
2256 , "ignore_unmapped" .= dsIgnoreUnmapped
2257 , "mode" .= dsSortMode
2258 , "missing" .= dsMissingSort
2259 , "nested_filter" .= dsNestedFilter ]
2261 toJSON (GeoDistanceSortSpec gdsSortOrder (GeoPoint (FieldName field) gdsLatLon) units) =
2262 object [ "unit" .= units
2263 , field .= gdsLatLon
2264 , "order" .= gdsSortOrder ]
2267instance ToJSON SortOrder where
2268 toJSON Ascending = String "asc"
2269 toJSON Descending = String "desc"
2272instance ToJSON SortMode where
2273 toJSON SortMin = String "min"
2274 toJSON SortMax = String "max"
2275 toJSON SortSum = String "sum"
2276 toJSON SortAvg = String "avg"
2279instance ToJSON Missing where
2280 toJSON LastMissing = String "_last"
2281 toJSON FirstMissing = String "_first"
2282 toJSON (CustomMissing txt) = String txt
2285instance ToJSON ScoreType where
2286 toJSON ScoreTypeMax = "max"
2287 toJSON ScoreTypeAvg = "avg"
2288 toJSON ScoreTypeSum = "sum"
2289 toJSON ScoreTypeNone = "none"
2292instance ToJSON Distance where
2293 toJSON (Distance dCoefficient dUnit) =
2294 String boltedTogether where
2295 coefText = showText dCoefficient
2296 (String unitText) = toJSON dUnit
2297 boltedTogether = mappend coefText unitText
2300instance ToJSON DistanceUnit where
2301 toJSON Miles = String "mi"
2302 toJSON Yards = String "yd"
2303 toJSON Feet = String "ft"
2304 toJSON Inches = String "in"
2305 toJSON Kilometers = String "km"
2306 toJSON Meters = String "m"
2307 toJSON Centimeters = String "cm"
2308 toJSON Millimeters = String "mm"
2309 toJSON NauticalMiles = String "nmi"
2312instance ToJSON DistanceType where
2313 toJSON Arc = String "arc"
2314 toJSON SloppyArc = String "sloppy_arc"
2315 toJSON Plane = String "plane"
2318instance ToJSON OptimizeBbox where
2319 toJSON NoOptimizeBbox = String "none"
2320 toJSON (OptimizeGeoFilterType gft) = toJSON gft
2323instance ToJSON GeoBoundingBoxConstraint where
2324 toJSON (GeoBoundingBoxConstraint
2325 (FieldName gbbcGeoBBField) gbbcConstraintBox cache type') =
2326 object [gbbcGeoBBField .= gbbcConstraintBox
2327 , "_cache" .= cache
2328 , "type" .= type']
2331instance ToJSON GeoFilterType where
2332 toJSON GeoFilterMemory = String "memory"
2333 toJSON GeoFilterIndexed = String "indexed"
2336instance ToJSON GeoBoundingBox where
2337 toJSON (GeoBoundingBox gbbTopLeft gbbBottomRight) =
2338 object ["top_left" .= gbbTopLeft
2339 , "bottom_right" .= gbbBottomRight]
2342instance ToJSON LatLon where
2343 toJSON (LatLon lLat lLon) =
2344 object ["lat" .= lLat
2345 , "lon" .= lLon]
2348-- index for smaller ranges, fielddata for longer ranges
2349instance ToJSON RangeExecution where
2350 toJSON RangeExecutionIndex = "index"
2351 toJSON RangeExecutionFielddata = "fielddata"
2354instance ToJSON RegexpFlags where
2355 toJSON AllRegexpFlags = String "ALL"
2356 toJSON NoRegexpFlags = String "NONE"
2357 toJSON (SomeRegexpFlags (h :| fs)) = String $ T.intercalate "|" flagStrs
2358 where flagStrs = map flagStr . nub $ h:fs
2359 flagStr AnyString = "ANYSTRING"
2360 flagStr Automaton = "AUTOMATON"
2361 flagStr Complement = "COMPLEMENT"
2362 flagStr Empty = "EMPTY"
2363 flagStr Intersection = "INTERSECTION"
2364 flagStr Interval = "INTERVAL"
2366instance ToJSON Term where
2367 toJSON (Term field value) = object ["term" .= object
2368 [field .= value]]
2371instance ToJSON BoolMatch where
2372 toJSON (MustMatch term cache) = object ["must" .= term,
2373 "_cache" .= cache]
2374 toJSON (MustNotMatch term cache) = object ["must_not" .= term,
2375 "_cache" .= cache]
2376 toJSON (ShouldMatch terms cache) = object ["should" .= fmap toJSON terms,
2377 "_cache" .= cache]
2380instance (FromJSON a) => FromJSON (SearchResult a) where
2381 parseJSON (Object v) = SearchResult <$>
2382 v .: "took" <*>
2383 v .: "timed_out" <*>
2384 v .: "_shards" <*>
2385 v .: "hits" <*>
2386 v .:? "aggregations" <*>
2387 v .:? "_scroll_id"
2388 parseJSON _ = empty
2390instance (FromJSON a) => FromJSON (SearchHits a) where
2391 parseJSON (Object v) = SearchHits <$>
2392 v .: "total" <*>
2393 v .: "max_score" <*>
2394 v .: "hits"
2395 parseJSON _ = empty
2397instance (FromJSON a) => FromJSON (Hit a) where
2398 parseJSON (Object v) = Hit <$>
2399 v .: "_index" <*>
2400 v .: "_type" <*>
2401 v .: "_id" <*>
2402 v .: "_score" <*>
2403 v .: "_source" <*>
2404 v .:? "highlight"
2405 parseJSON _ = empty
2407instance FromJSON ShardResult where
2408 parseJSON (Object v) = ShardResult <$>
2409 v .: "total" <*>
2410 v .: "successful" <*>
2411 v .: "failed"
2412 parseJSON _ = empty
2415instance FromJSON DocVersion where
2416 parseJSON v = do
2417 i <- parseJSON v
2418 maybe (fail "DocVersion out of range") return $ mkDocVersion i
2420instance Bounded DocVersion where
2421 minBound = DocVersion 1
2422 maxBound = DocVersion 9200000000000000000 -- 9.2e+18
2424instance Enum DocVersion where
2425 succ x
2426 | x /= maxBound = DocVersion (succ $ docVersionNumber x)
2427 | otherwise = succError "DocVersion"
2428 pred x
2429 | x /= minBound = DocVersion (pred $ docVersionNumber x)
2430 | otherwise = predError "DocVersion"
2431 toEnum i =
2432 fromMaybe (error $ show i ++ " out of DocVersion range") $ mkDocVersion i
2433 fromEnum = docVersionNumber
2434 enumFrom = boundedEnumFrom
2435 enumFromThen = boundedEnumFromThen