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-------------------------------------------------------------------------------
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
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
25-------------------------------------------------------------------------------
29module Database.Bloodhound.Types
31 , defaultIndexSettings
32 , defaultIndexDocumentSettings
43 , mkTermsScriptAggregation
59 , UpdatableIndexSetting(..)
60 , IndexSettingsSummary(..)
61 , AllocationPolicy(..)
65 , InitialShardCount(..)
76 , ExternalDocVersion(..)
79 , IndexDocumentSettings(..)
90 , PatternOrPatterns(..)
101 , GeoBoundingBoxConstraint(..)
127 , TemplatePattern(..)
145 , MultiMatchQuery(..)
148 , CommonTermsQuery(..)
151 , FuzzyLikeThisQuery(..)
152 , FuzzyLikeFieldQuery(..)
157 , MoreLikeThisQuery(..)
158 , MoreLikeThisFieldQuery(..)
161 , QueryStringQuery(..)
162 , SimpleQueryStringQuery(..)
166 , BooleanOperator(..)
168 , CutoffFrequency(..)
173 , MultiMatchQueryType(..)
177 , CommonMinimumMatch(..)
178 , MinimumMatchHighLow(..)
181 , IgnoreTermFrequency(..)
190 , MaxDocFrequency(..)
191 , MinDocFrequency(..)
195 , MinimumTermFrequency(..)
197 , FieldDefinition(..)
200 , AllowLeadingWildcard(..)
201 , LowercaseExpanded(..)
202 , GeneratePhraseQueries(..)
204 , AnalyzeWildcard(..)
205 , EnablePositionIncrements(..)
206 , SimpleQueryFlag(..)
221 , BucketAggregation(..)
222 , TermsAggregation(..)
223 , ValueCountAggregation(..)
224 , FilterAggregation(..)
225 , DateHistogramAggregation(..)
229 , HighlightSettings(..)
231 , PostingsHighlight(..)
232 , FastVectorHighlight(..)
233 , CommonHighlight(..)
235 , HighlightEncoder(..)
240 , DateHistogramResult(..)
243import Control.Applicative
244import Control.Monad.Catch
245import Control.Monad.Except
246import Control.Monad.Reader
247import Control.Monad.State
248import Control.Monad.Writer
250import Data.Aeson.Types (Pair, emptyObject, parseMaybe)
251import qualified Data.ByteString.Lazy.Char8 as L
252import qualified Data.HashMap.Strict as HM (union)
253import Data.List (foldl', nub)
254import Data.List.NonEmpty (NonEmpty (..), toList)
255import qualified Data.Map.Strict as M
257import Data.Text (Text)
258import qualified Data.Text as T
259import Data.Time.Clock (UTCTime, NominalDiffTime)
260import qualified Data.Vector as V
262import GHC.Generics (Generic)
263import Network.HTTP.Client
264import qualified Network.HTTP.Types.Method as NHTM
266import Database.Bloodhound.Types.Class
269-- >>> :set -XOverloadedStrings
270-- >>> import Database.Bloodhound
271-- >>> let testServer = (Server "http://localhost:9200")
272-- >>> let testIndex = IndexName "twitter"
273-- >>> let testMapping = MappingName "tweet"
274-- >>> let defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
276-- defaultIndexSettings is exported by Database.Bloodhound as well
277-- no trailing slashes in servers, library handles building the path.
279{-| Common environment for Elasticsearch calls. Connections will be
280 pipelined according to the provided HTTP connection manager.
282data BHEnv = BHEnv { bhServer :: Server
283 , bhManager :: Manager
286{-| All API calls to Elasticsearch operate within
287 MonadBH. The idea is that it can be easily embedded in your
288 own monad transformer stack. A default instance for a ReaderT and
289 alias 'BH' is provided for the simple case.
291class (Functor m, Applicative m, MonadIO m) => MonadBH m where
295 unBH :: ReaderT BHEnv m a
310instance MonadTrans BH where
313instance (MonadReader r m) => MonadReader r (BH m) where
315 local f (BH (ReaderT m)) = BH $ ReaderT $ \r ->
318instance (Functor m, Applicative m, MonadIO m) => MonadBH (BH m) where
319 getBHEnv = BH getBHEnv
322instance (Functor m, Applicative m, MonadIO m) => MonadBH (ReaderT BHEnv m) where
325runBH :: BHEnv -> BH m a -> m a
326runBH e f = runReaderT (unBH f) e
328{-| 'Version' is embedded in 'Status' -}
329data Version = Version { number :: Text
331 , build_timestamp :: UTCTime
332 , build_snapshot :: Bool
333 , lucene_version :: Text } deriving (Eq, Show, Generic)
335{-| 'Status' is a data type for describing the JSON body returned by
336 Elasticsearch when you query its status. This was deprecated in 1.2.0.
338 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-status.html#indices-status>
341data Status = Status { ok :: Maybe Bool
345 , tagline :: Text } deriving (Eq, Show)
347{-| 'IndexSettings' is used to configure the shards and replicas when you create
348 an Elasticsearch Index.
350 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html>
354 IndexSettings { indexShards :: ShardCount
355 , indexReplicas :: ReplicaCount } deriving (Eq, Show)
357{-| 'defaultIndexSettings' is an 'IndexSettings' with 3 shards and 2 replicas. -}
358defaultIndexSettings :: IndexSettings
359defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
361{-| 'UpdatableIndexSetting' are settings which may be updated after an index is created.
363 <https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html>
365data UpdatableIndexSetting = NumberOfReplicas ReplicaCount
366 -- ^ The number of replicas each shard has.
367 | AutoExpandReplicas ReplicaBounds
368 | BlocksReadOnly Bool
369 -- ^ Set to True to have the index read only. False to allow writes and metadata changes.
371 -- ^ Set to True to disable read operations against the index.
373 -- ^ Set to True to disable write operations against the index.
374 | BlocksMetaData Bool
375 -- ^ Set to True to disable metadata operations against the index.
376 | RefreshInterval NominalDiffTime
377 -- ^ The async refresh interval of a shard
378 | IndexConcurrency Int
379 | FailOnMergeFailure Bool
380 | TranslogFlushThresholdOps Int
381 -- ^ When to flush on operations.
382 | TranslogFlushThresholdSize Bytes
383 -- ^ When to flush based on translog (bytes) size.
384 | TranslogFlushThresholdPeriod NominalDiffTime
385 -- ^ When to flush based on a period of not flushing.
386 | TranslogDisableFlush Bool
387 -- ^ Disables flushing. Note, should be set for a short interval and then enabled.
388 | CacheFilterMaxSize (Maybe Bytes)
389 -- ^ The maximum size of filter cache (per segment in shard).
390 | CacheFilterExpire (Maybe NominalDiffTime)
391 -- ^ The expire after access time for filter cache.
392 | GatewaySnapshotInterval NominalDiffTime
393 -- ^ The gateway snapshot interval (only applies to shared gateways).
394 | RoutingAllocationInclude (NonEmpty NodeAttrFilter)
395 -- ^ A node matching any rule will be allowed to host shards from the index.
396 | RoutingAllocationExclude (NonEmpty NodeAttrFilter)
397 -- ^ A node matching any rule will NOT be allowed to host shards from the index.
398 | RoutingAllocationRequire (NonEmpty NodeAttrFilter)
399 -- ^ Only nodes matching all rules will be allowed to host shards from the index.
400 | RoutingAllocationEnable AllocationPolicy
401 -- ^ Enables shard allocation for a specific index.
402 | RoutingAllocationShardsPerNode ShardCount
403 -- ^ Controls the total number of shards (replicas and primaries) allowed to be allocated on a single node.
404 | RecoveryInitialShards InitialShardCount
405 -- ^ When using local gateway a particular shard is recovered only if there can be allocated quorum shards in the cluster.
406 | GCDeletes NominalDiffTime
407 | TTLDisablePurge Bool
408 -- ^ Disables temporarily the purge of expired docs.
409 | TranslogFSType FSType
410 | IndexCompoundFormat CompoundFormat
411 | IndexCompoundOnFlush Bool
415data AllocationPolicy = AllocAll
416 -- ^ Allows shard allocation for all shards.
418 -- ^ Allows shard allocation only for primary shards.
420 -- ^ Allows shard allocation only for primary shards for new indices.
422 -- ^ No shard allocation is allowed
425data ReplicaBounds = ReplicasBounded Int Int
426 | ReplicasLowerBounded Int
430newtype Bytes = Bytes Int deriving (Eq, Show, Ord, ToJSON)
432data FSType = FSSimple
433 | FSBuffered deriving (Eq, Show, Ord)
435data InitialShardCount = QuorumShards
442data NodeAttrFilter = NodeAttrFilter { nodeAttrFilterName :: NodeAttrName
443 , nodeAttrFilterValues :: NonEmpty Text}
446newtype NodeAttrName = NodeAttrName Text deriving (Eq, Show)
448data CompoundFormat = CompoundFileFormat Bool
449 | MergeSegmentVsTotalIndex Double
450 -- ^ percentage between 0 and 1 where 0 is false, 1 is true
453newtype NominalDiffTimeJSON = NominalDiffTimeJSON NominalDiffTime
455data IndexSettingsSummary = IndexSettingsSummary { sSummaryShardCount :: ShardCount
456 , sSummaryUpdateable :: [UpdatableIndexSetting]}
459{-| 'Reply' and 'Method' are type synonyms from 'Network.HTTP.Types.Method.Method' -}
460type Reply = Network.HTTP.Client.Response L.ByteString
461type Method = NHTM.Method
463{-| 'OpenCloseIndex' is a sum type for opening and closing indices.
465 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-open-close.html>
467data OpenCloseIndex = OpenIndex | CloseIndex deriving (Eq, Show)
469data FieldType = GeoPointType
475 | ByteType deriving (Eq, Show)
477data FieldDefinition =
478 FieldDefinition { fieldType :: FieldType } deriving (Eq, Show)
480{-| An 'IndexTemplate' defines a template that will automatically be
481 applied to new indices created. The templates include both
482 'IndexSettings' and mappings, and a simple 'TemplatePattern' that
483 controls if the template will be applied to the index created.
484 Specify mappings as follows: @[toJSON TweetMapping, ...]@
486 https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-templates.html
489 IndexTemplate { templatePattern :: TemplatePattern
490 , templateSettings :: Maybe IndexSettings
491 , templateMappings :: [Value]
495 MappingField { mappingFieldName :: FieldName
496 , fieldDefinition :: FieldDefinition } deriving (Eq, Show)
498{-| Support for type reification of 'Mapping's is currently incomplete, for
499 now the mapping API verbiage expects a 'ToJSON'able blob.
501 Indexes have mappings, mappings are schemas for the documents contained in the
502 index. I'd recommend having only one mapping per index, always having a mapping,
503 and keeping different kinds of documents separated if possible.
505data Mapping = Mapping { typeName :: TypeName
506 , mappingFields :: [MappingField] } deriving (Eq, Show)
508{-| 'BulkOperation' is a sum type for expressing the four kinds of bulk
509 operation index, create, delete, and update. 'BulkIndex' behaves like an
510 "upsert", 'BulkCreate' will fail if a document already exists at the DocId.
512 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-bulk.html#docs-bulk>
515 BulkIndex IndexName MappingName DocId Value
516 | BulkCreate IndexName MappingName DocId Value
517 | BulkDelete IndexName MappingName DocId
518 | BulkUpdate IndexName MappingName DocId Value deriving (Eq, Show)
520{-| 'EsResult' describes the standard wrapper JSON document that you see in
521 successful Elasticsearch lookups or lookups that couldn't find the document.
523data EsResult a = EsResult { _index :: Text
526 , foundResult :: Maybe (EsResultFound a)} deriving (Eq, Show)
528{-| 'EsResultFound' contains the document and its metadata inside of an
529 'EsResult' when the document was successfully found.
531data EsResultFound a = EsResultFound { _version :: DocVersion
532 , _source :: a } deriving (Eq, Show)
534{-| 'EsError' is the generic type that will be returned when there was a
535 problem. If you can't parse the expected response, its a good idea to
538data EsError = EsError { errorStatus :: Int
539 , errorMessage :: Text } deriving (Eq, Show)
542{-| 'DocVersion' is an integer version number for a document between 1
543and 9.2e+18 used for <<https://www.elastic.co/guide/en/elasticsearch/guide/current/optimistic-concurrency-control.html optimistic concurrency control>>.
545newtype DocVersion = DocVersion {
546 docVersionNumber :: Int
547 } deriving (Eq, Show, Ord, ToJSON)
549-- | Smart constructor for in-range doc version
550mkDocVersion :: Int -> Maybe DocVersion
552 | i >= (docVersionNumber minBound) && i <= (docVersionNumber maxBound) =
554 | otherwise = Nothing
557{-| 'ExternalDocVersion' is a convenience wrapper if your code uses its
558own version numbers instead of ones from ES.
560newtype ExternalDocVersion = ExternalDocVersion DocVersion
561 deriving (Eq, Show, Ord, Bounded, Enum, ToJSON)
563{-| 'VersionControl' is specified when indexing documents as a
564optimistic concurrency control.
566data VersionControl = NoVersionControl
567 -- ^ Don't send a version. This is a pure overwrite.
568 | InternalVersion DocVersion
569 -- ^ Use the default ES versioning scheme. Only
570 -- index the document if the version is the same
571 -- as the one specified. Only applicable to
572 -- updates, as you should be getting Version from
574 | ExternalGT ExternalDocVersion
575 -- ^ Use your own version numbering. Only index
576 -- the document if the version is strictly higher
577 -- OR the document doesn't exist. The given
578 -- version will be used as the new version number
579 -- for the stored document. N.B. All updates must
580 -- increment this number, meaning there is some
581 -- global, external ordering of updates.
582 | ExternalGTE ExternalDocVersion
583 -- ^ Use your own version numbering. Only index
584 -- the document if the version is equal or higher
585 -- than the stored version. Will succeed if there
586 -- is no existing document. The given version will
587 -- be used as the new version number for the
588 -- stored document. Use with care, as this could
589 -- result in data loss.
590 | ForceVersion ExternalDocVersion
591 -- ^ The document will always be indexed and the
592 -- given version will be the new version. This is
593 -- typically used for correcting errors. Use with
594 -- care, as this could result in data loss.
595 deriving (Show, Eq, Ord)
597{-| 'DocumentParent' is used to specify a parent document.
599newtype DocumentParent = DocumentParent DocId
602{-| 'IndexDocumentSettings' are special settings supplied when indexing
603a document. For the best backwards compatiblity when new fields are
604added, you should probably prefer to start with 'defaultIndexDocumentSettings'
606data IndexDocumentSettings =
607 IndexDocumentSettings { idsVersionControl :: VersionControl
608 , idsParent :: Maybe DocumentParent
609 } deriving (Eq, Show)
611{-| Reasonable default settings. Chooses no version control and no parent.
613defaultIndexDocumentSettings :: IndexDocumentSettings
614defaultIndexDocumentSettings = IndexDocumentSettings NoVersionControl Nothing
616{-| 'Sort' is a synonym for a list of 'SortSpec's. Sort behavior is order
617 dependent with later sorts acting as tie-breakers for earlier sorts.
619type Sort = [SortSpec]
621{-| The two main kinds of 'SortSpec' are 'DefaultSortSpec' and
622 'GeoDistanceSortSpec'. The latter takes a 'SortOrder', 'GeoPoint', and
623 'DistanceUnit' to express "nearness" to a single geographical point as a
626<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
628data SortSpec = DefaultSortSpec DefaultSort
629 | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit deriving (Eq, Show)
631{-| 'DefaultSort' is usually the kind of 'SortSpec' you'll want. There's a
632 'mkSort' convenience function for when you want to specify only the most
635<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
638 DefaultSort { sortFieldName :: FieldName
639 , sortOrder :: SortOrder
641 , ignoreUnmapped :: Bool
642 , sortMode :: Maybe SortMode
643 , missingSort :: Maybe Missing
644 , nestedFilter :: Maybe Filter } deriving (Eq, Show)
646{-| 'SortOrder' is 'Ascending' or 'Descending', as you might expect. These get
647 encoded into "asc" or "desc" when turned into JSON.
649<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
651data SortOrder = Ascending
652 | Descending deriving (Eq, Show)
654{-| 'Missing' prescribes how to handle missing fields. A missing field can be
655 sorted last, first, or using a custom value as a substitute.
657<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_missing_values>
659data Missing = LastMissing
661 | CustomMissing Text deriving (Eq, Show)
663{-| 'SortMode' prescribes how to handle sorting array/multi-valued fields.
665http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_sort_mode_option
667data SortMode = SortMin
670 | SortAvg deriving (Eq, Show)
672{-| 'mkSort' defaults everything but the 'FieldName' and the 'SortOrder' so
673 that you can concisely describe the usual kind of 'SortSpec's you want.
675mkSort :: FieldName -> SortOrder -> DefaultSort
676mkSort fieldName sOrder = DefaultSort fieldName sOrder False Nothing Nothing Nothing
678{-| 'Cache' is for telling ES whether it should cache a 'Filter' not.
679 'Query's cannot be cached.
681type Cache = Bool -- caching on/off
685{-| 'PrefixValue' is used in 'PrefixQuery' as the main query component.
687type PrefixValue = Text
689{-| 'BooleanOperator' is the usual And/Or operators with an ES compatible
690 JSON encoding baked in. Used all over the place.
692data BooleanOperator = And | Or deriving (Eq, Show)
694{-| 'ShardCount' is part of 'IndexSettings'
696newtype ShardCount = ShardCount Int deriving (Eq, Show, Generic)
698{-| 'ReplicaCount' is part of 'IndexSettings'
700newtype ReplicaCount = ReplicaCount Int deriving (Eq, Show, Generic)
702{-| 'Server' is used with the client functions to point at the ES instance
704newtype Server = Server Text deriving (Eq, Show)
706{-| 'IndexName' is used to describe which index to query/create/delete
708newtype IndexName = IndexName Text deriving (Eq, Generic, Show)
710{-| 'TemplateName' is used to describe which template to query/create/delete
712newtype TemplateName = TemplateName Text deriving (Eq, Show, Generic)
714{-| 'TemplatePattern' represents a pattern which is matched against index names
716newtype TemplatePattern = TemplatePattern Text deriving (Eq, Show, Generic)
718{-| 'MappingName' is part of mappings which are how ES describes and schematizes
719 the data in the indices.
721newtype MappingName = MappingName Text deriving (Eq, Generic, Show)
723{-| 'DocId' is a generic wrapper value for expressing unique Document IDs.
724 Can be set by the user or created by ES itself. Often used in client
725 functions for poking at specific documents.
727newtype DocId = DocId Text deriving (Eq, Generic, Show)
729{-| 'QueryString' is used to wrap query text bodies, be they human written or not.
731newtype QueryString = QueryString Text deriving (Eq, Generic, Show)
733{-| 'FieldName' is used all over the place wherever a specific field within
734 a document needs to be specified, usually in 'Query's or 'Filter's.
736newtype FieldName = FieldName Text deriving (Eq, Show)
739{-| 'Script' is often used in place of 'FieldName' to specify more
740complex ways of extracting a value from a document.
742newtype Script = Script { scriptText :: Text } deriving (Eq, Show)
744{-| 'CacheName' is used in 'RegexpFilter' for describing the
745 'CacheKey' keyed caching behavior.
747newtype CacheName = CacheName Text deriving (Eq, Show)
749{-| 'CacheKey' is used in 'RegexpFilter' to key regex caching.
752 CacheKey Text deriving (Eq, Show)
754 Existence Bool deriving (Eq, Show)
756 NullValue Bool deriving (Eq, Show)
757newtype CutoffFrequency =
758 CutoffFrequency Double deriving (Eq, Show, Generic)
760 Analyzer Text deriving (Eq, Show, Generic)
761newtype MaxExpansions =
762 MaxExpansions Int deriving (Eq, Show, Generic)
764{-| 'Lenient', if set to true, will cause format based failures to be
765 ignored. I don't know what the bloody default is, Elasticsearch
766 documentation didn't say what it was. Let me know if you figure it out.
769 Lenient Bool deriving (Eq, Show, Generic)
771 Tiebreaker Double deriving (Eq, Show, Generic)
773 Boost Double deriving (Eq, Show, Generic)
775 BoostTerms Double deriving (Eq, Show, Generic)
777{-| 'MinimumMatch' controls how many should clauses in the bool query should
778 match. Can be an absolute value (2) or a percentage (30%) or a
781newtype MinimumMatch =
782 MinimumMatch Int deriving (Eq, Show, Generic)
783newtype MinimumMatchText =
784 MinimumMatchText Text deriving (Eq, Show)
785newtype DisableCoord =
786 DisableCoord Bool deriving (Eq, Show, Generic)
787newtype IgnoreTermFrequency =
788 IgnoreTermFrequency Bool deriving (Eq, Show, Generic)
789newtype MinimumTermFrequency =
790 MinimumTermFrequency Int deriving (Eq, Show, Generic)
791newtype MaxQueryTerms =
792 MaxQueryTerms Int deriving (Eq, Show, Generic)
794 Fuzziness Double deriving (Eq, Show, Generic)
796{-| 'PrefixLength' is the prefix length used in queries, defaults to 0. -}
797newtype PrefixLength =
798 PrefixLength Int deriving (Eq, Show, Generic)
800 TypeName Text deriving (Eq, Show, Generic)
801newtype PercentMatch =
802 PercentMatch Double deriving (Eq, Show, Generic)
804 StopWord Text deriving (Eq, Show, Generic)
806 QueryPath Text deriving (Eq, Show, Generic)
808{-| Allowing a wildcard at the beginning of a word (eg "*ing") is particularly
809 heavy, because all terms in the index need to be examined, just in case
810 they match. Leading wildcards can be disabled by setting
811 'AllowLeadingWildcard' to false. -}
812newtype AllowLeadingWildcard =
813 AllowLeadingWildcard Bool deriving (Eq, Show, Generic)
814newtype LowercaseExpanded =
815 LowercaseExpanded Bool deriving (Eq, Show, Generic)
816newtype EnablePositionIncrements =
817 EnablePositionIncrements Bool deriving (Eq, Show, Generic)
819{-| By default, wildcard terms in a query are not analyzed.
820 Setting 'AnalyzeWildcard' to true enables best-effort analysis.
822newtype AnalyzeWildcard = AnalyzeWildcard Bool deriving (Eq, Show, Generic)
824{-| 'GeneratePhraseQueries' defaults to false.
826newtype GeneratePhraseQueries =
827 GeneratePhraseQueries Bool deriving (Eq, Show, Generic)
829{-| 'Locale' is used for string conversions - defaults to ROOT.
831newtype Locale = Locale Text deriving (Eq, Show, Generic)
832newtype MaxWordLength = MaxWordLength Int deriving (Eq, Show, Generic)
833newtype MinWordLength = MinWordLength Int deriving (Eq, Show, Generic)
835{-| 'PhraseSlop' sets the default slop for phrases, 0 means exact
836 phrase matches. Default is 0.
838newtype PhraseSlop = PhraseSlop Int deriving (Eq, Show, Generic)
839newtype MinDocFrequency = MinDocFrequency Int deriving (Eq, Show, Generic)
840newtype MaxDocFrequency = MaxDocFrequency Int deriving (Eq, Show, Generic)
842{-| 'unpackId' is a silly convenience function that gets used once.
844unpackId :: DocId -> Text
845unpackId (DocId docId) = docId
847type TrackSortScores = Bool
848newtype From = From Int deriving (Eq, Show, ToJSON)
849newtype Size = Size Int deriving (Eq, Show, ToJSON)
851data Search = Search { queryBody :: Maybe Query
852 , filterBody :: Maybe Filter
853 , sortBody :: Maybe Sort
854 , aggBody :: Maybe Aggregations
855 , highlight :: Maybe Highlights
857 , trackSortScores :: TrackSortScores
860 , searchType :: SearchType
861 , fields :: Maybe [FieldName]
862 , source :: Maybe Source } deriving (Eq, Show)
864data SearchType = SearchTypeQueryThenFetch
865 | SearchTypeDfsQueryThenFetch
868 | SearchTypeQueryAndFetch
869 | SearchTypeDfsQueryAndFetch
874 | SourcePatterns PatternOrPatterns
875 | SourceIncludeExclude Include Exclude
878data PatternOrPatterns = PopPattern Pattern
879 | PopPatterns [Pattern] deriving (Eq, Show)
881data Include = Include [Pattern] deriving (Eq, Show)
882data Exclude = Exclude [Pattern] deriving (Eq, Show)
884newtype Pattern = Pattern Text deriving (Eq, Show)
886data Highlights = Highlights { globalsettings :: Maybe HighlightSettings
887 , highlightFields :: [FieldHighlight]
888 } deriving (Show, Eq)
890data FieldHighlight = FieldHighlight FieldName (Maybe HighlightSettings)
894data HighlightSettings = Plain PlainHighlight
895 | Postings PostingsHighlight
896 | FastVector FastVectorHighlight
899 PlainHighlight { plainCommon :: Maybe CommonHighlight
900 , plainNonPost :: Maybe NonPostings } deriving (Show, Eq)
902 -- This requires that index_options are set to 'offset' in the mapping.
903data PostingsHighlight = PostingsHighlight (Maybe CommonHighlight) deriving (Show, Eq)
905-- This requires that term_vector is set to 'with_positions_offsets' in the mapping.
906data FastVectorHighlight =
907 FastVectorHighlight { fvCommon :: Maybe CommonHighlight
908 , fvNonPostSettings :: Maybe NonPostings
909 , boundaryChars :: Maybe Text
910 , boundaryMaxScan :: Maybe Int
911 , fragmentOffset :: Maybe Int
912 , matchedFields :: [Text]
913 , phraseLimit :: Maybe Int
914 } deriving (Show, Eq)
916data CommonHighlight =
917 CommonHighlight { order :: Maybe Text
918 , forceSource :: Maybe Bool
919 , tag :: Maybe HighlightTag
920 , encoder :: Maybe HighlightEncoder
921 , noMatchSize :: Maybe Int
922 , highlightQuery :: Maybe Query
923 , requireFieldMatch :: Maybe Bool
924 } deriving (Show, Eq)
926-- Settings that are only applicable to FastVector and Plain highlighters.
928 NonPostings { fragmentSize :: Maybe Int
929 , numberOfFragments :: Maybe Int} deriving (Show, Eq)
931data HighlightEncoder = DefaultEncoder
935-- NOTE: Should the tags use some kind of HTML type, rather than Text?
936data HighlightTag = TagSchema Text
937 | CustomTags ([Text], [Text]) -- Only uses more than the first value in the lists if fvh
942 TermQuery Term (Maybe Boost)
943 | TermsQuery (NonEmpty Term)
944 | QueryMatchQuery MatchQuery
945 | QueryMultiMatchQuery MultiMatchQuery
946 | QueryBoolQuery BoolQuery
947 | QueryBoostingQuery BoostingQuery
948 | QueryCommonTermsQuery CommonTermsQuery
949 | ConstantScoreFilter Filter Boost
950 | ConstantScoreQuery Query Boost
951 | QueryDisMaxQuery DisMaxQuery
952 | QueryFilteredQuery FilteredQuery
953 | QueryFuzzyLikeThisQuery FuzzyLikeThisQuery
954 | QueryFuzzyLikeFieldQuery FuzzyLikeFieldQuery
955 | QueryFuzzyQuery FuzzyQuery
956 | QueryHasChildQuery HasChildQuery
957 | QueryHasParentQuery HasParentQuery
958 | IdsQuery MappingName [DocId]
959 | QueryIndicesQuery IndicesQuery
960 | MatchAllQuery (Maybe Boost)
961 | QueryMoreLikeThisQuery MoreLikeThisQuery
962 | QueryMoreLikeThisFieldQuery MoreLikeThisFieldQuery
963 | QueryNestedQuery NestedQuery
964 | QueryPrefixQuery PrefixQuery
965 | QueryQueryStringQuery QueryStringQuery
966 | QuerySimpleQueryStringQuery SimpleQueryStringQuery
967 | QueryRangeQuery RangeQuery
968 | QueryRegexpQuery RegexpQuery
972 RegexpQuery { regexpQueryField :: FieldName
973 , regexpQuery :: Regexp
974 , regexpQueryFlags :: RegexpFlags
975 , regexpQueryBoost :: Maybe Boost
976 } deriving (Eq, Show)
979 RangeQuery { rangeQueryField :: FieldName
980 , rangeQueryRange :: RangeValue
981 , rangeQueryBoost :: Boost } deriving (Eq, Show)
983mkRangeQuery :: FieldName -> RangeValue -> RangeQuery
984mkRangeQuery f r = RangeQuery f r (Boost 1.0)
986data SimpleQueryStringQuery =
987 SimpleQueryStringQuery
988 { simpleQueryStringQuery :: QueryString
989 , simpleQueryStringField :: Maybe FieldOrFields
990 , simpleQueryStringOperator :: Maybe BooleanOperator
991 , simpleQueryStringAnalyzer :: Maybe Analyzer
992 , simpleQueryStringFlags :: Maybe [SimpleQueryFlag]
993 , simpleQueryStringLowercaseExpanded :: Maybe LowercaseExpanded
994 , simpleQueryStringLocale :: Maybe Locale
995 } deriving (Eq, Show)
997data SimpleQueryFlag =
1004 | SimpleQueryPrecedence
1006 | SimpleQueryWhitespace
1009 | SimpleQuerySlop deriving (Eq, Show)
1011-- use_dis_max and tie_breaker when fields are plural?
1012data QueryStringQuery =
1014 { queryStringQuery :: QueryString
1015 , queryStringDefaultField :: Maybe FieldName
1016 , queryStringOperator :: Maybe BooleanOperator
1017 , queryStringAnalyzer :: Maybe Analyzer
1018 , queryStringAllowLeadingWildcard :: Maybe AllowLeadingWildcard
1019 , queryStringLowercaseExpanded :: Maybe LowercaseExpanded
1020 , queryStringEnablePositionIncrements :: Maybe EnablePositionIncrements
1021 , queryStringFuzzyMaxExpansions :: Maybe MaxExpansions
1022 , queryStringFuzziness :: Maybe Fuzziness
1023 , queryStringFuzzyPrefixLength :: Maybe PrefixLength
1024 , queryStringPhraseSlop :: Maybe PhraseSlop
1025 , queryStringBoost :: Maybe Boost
1026 , queryStringAnalyzeWildcard :: Maybe AnalyzeWildcard
1027 , queryStringGeneratePhraseQueries :: Maybe GeneratePhraseQueries
1028 , queryStringMinimumShouldMatch :: Maybe MinimumMatch
1029 , queryStringLenient :: Maybe Lenient
1030 , queryStringLocale :: Maybe Locale
1031 } deriving (Eq, Show)
1033mkQueryStringQuery :: QueryString -> QueryStringQuery
1034mkQueryStringQuery qs =
1035 QueryStringQuery qs Nothing Nothing
1036 Nothing Nothing Nothing Nothing
1037 Nothing Nothing Nothing Nothing
1038 Nothing Nothing Nothing Nothing
1041data FieldOrFields = FofField FieldName
1042 | FofFields [FieldName] deriving (Eq, Show)
1046 { prefixQueryField :: FieldName
1047 , prefixQueryPrefixValue :: Text
1048 , prefixQueryBoost :: Maybe Boost } deriving (Eq, Show)
1052 { nestedQueryPath :: QueryPath
1053 , nestedQueryScoreType :: ScoreType
1054 , nestedQuery :: Query } deriving (Eq, Show)
1056data MoreLikeThisFieldQuery =
1057 MoreLikeThisFieldQuery
1058 { moreLikeThisFieldText :: Text
1059 , moreLikeThisFieldFields :: FieldName
1060 -- default 0.3 (30%)
1061 , moreLikeThisFieldPercentMatch :: Maybe PercentMatch
1062 , moreLikeThisFieldMinimumTermFreq :: Maybe MinimumTermFrequency
1063 , moreLikeThisFieldMaxQueryTerms :: Maybe MaxQueryTerms
1064 , moreLikeThisFieldStopWords :: Maybe [StopWord]
1065 , moreLikeThisFieldMinDocFrequency :: Maybe MinDocFrequency
1066 , moreLikeThisFieldMaxDocFrequency :: Maybe MaxDocFrequency
1067 , moreLikeThisFieldMinWordLength :: Maybe MinWordLength
1068 , moreLikeThisFieldMaxWordLength :: Maybe MaxWordLength
1069 , moreLikeThisFieldBoostTerms :: Maybe BoostTerms
1070 , moreLikeThisFieldBoost :: Maybe Boost
1071 , moreLikeThisFieldAnalyzer :: Maybe Analyzer
1072 } deriving (Eq, Show)
1074data MoreLikeThisQuery =
1076 { moreLikeThisText :: Text
1077 , moreLikeThisFields :: Maybe [FieldName]
1078 -- default 0.3 (30%)
1079 , moreLikeThisPercentMatch :: Maybe PercentMatch
1080 , moreLikeThisMinimumTermFreq :: Maybe MinimumTermFrequency
1081 , moreLikeThisMaxQueryTerms :: Maybe MaxQueryTerms
1082 , moreLikeThisStopWords :: Maybe [StopWord]
1083 , moreLikeThisMinDocFrequency :: Maybe MinDocFrequency
1084 , moreLikeThisMaxDocFrequency :: Maybe MaxDocFrequency
1085 , moreLikeThisMinWordLength :: Maybe MinWordLength
1086 , moreLikeThisMaxWordLength :: Maybe MaxWordLength
1087 , moreLikeThisBoostTerms :: Maybe BoostTerms
1088 , moreLikeThisBoost :: Maybe Boost
1089 , moreLikeThisAnalyzer :: Maybe Analyzer
1090 } deriving (Eq, Show)
1094 { indicesQueryIndices :: [IndexName]
1095 , indicesQuery :: Query
1097 , indicesQueryNoMatch :: Maybe Query } deriving (Eq, Show)
1099data HasParentQuery =
1101 { hasParentQueryType :: TypeName
1102 , hasParentQuery :: Query
1103 , hasParentQueryScoreType :: Maybe ScoreType } deriving (Eq, Show)
1107 { hasChildQueryType :: TypeName
1108 , hasChildQuery :: Query
1109 , hasChildQueryScoreType :: Maybe ScoreType } deriving (Eq, Show)
1115 | ScoreTypeNone deriving (Eq, Show)
1118 FuzzyQuery { fuzzyQueryField :: FieldName
1119 , fuzzyQueryValue :: Text
1120 , fuzzyQueryPrefixLength :: PrefixLength
1121 , fuzzyQueryMaxExpansions :: MaxExpansions
1122 , fuzzyQueryFuzziness :: Fuzziness
1123 , fuzzyQueryBoost :: Maybe Boost
1124 } deriving (Eq, Show)
1126data FuzzyLikeFieldQuery =
1128 { fuzzyLikeField :: FieldName
1129 -- anaphora is good for the soul.
1130 , fuzzyLikeFieldText :: Text
1131 , fuzzyLikeFieldMaxQueryTerms :: MaxQueryTerms
1132 , fuzzyLikeFieldIgnoreTermFrequency :: IgnoreTermFrequency
1133 , fuzzyLikeFieldFuzziness :: Fuzziness
1134 , fuzzyLikeFieldPrefixLength :: PrefixLength
1135 , fuzzyLikeFieldBoost :: Boost
1136 , fuzzyLikeFieldAnalyzer :: Maybe Analyzer
1137 } deriving (Eq, Show)
1139data FuzzyLikeThisQuery =
1141 { fuzzyLikeFields :: [FieldName]
1142 , fuzzyLikeText :: Text
1143 , fuzzyLikeMaxQueryTerms :: MaxQueryTerms
1144 , fuzzyLikeIgnoreTermFrequency :: IgnoreTermFrequency
1145 , fuzzyLikeFuzziness :: Fuzziness
1146 , fuzzyLikePrefixLength :: PrefixLength
1147 , fuzzyLikeBoost :: Boost
1148 , fuzzyLikeAnalyzer :: Maybe Analyzer
1149 } deriving (Eq, Show)
1153 { filteredQuery :: Query
1154 , filteredFilter :: Filter } deriving (Eq, Show)
1157 DisMaxQuery { disMaxQueries :: [Query]
1159 , disMaxTiebreaker :: Tiebreaker
1160 , disMaxBoost :: Maybe Boost
1161 } deriving (Eq, Show)
1164 MatchQuery { matchQueryField :: FieldName
1165 , matchQueryQueryString :: QueryString
1166 , matchQueryOperator :: BooleanOperator
1167 , matchQueryZeroTerms :: ZeroTermsQuery
1168 , matchQueryCutoffFrequency :: Maybe CutoffFrequency
1169 , matchQueryMatchType :: Maybe MatchQueryType
1170 , matchQueryAnalyzer :: Maybe Analyzer
1171 , matchQueryMaxExpansions :: Maybe MaxExpansions
1172 , matchQueryLenient :: Maybe Lenient
1173 , matchQueryBoost :: Maybe Boost } deriving (Eq, Show)
1175{-| 'mkMatchQuery' is a convenience function that defaults the less common parameters,
1176 enabling you to provide only the 'FieldName' and 'QueryString' to make a 'MatchQuery'
1178mkMatchQuery :: FieldName -> QueryString -> MatchQuery
1179mkMatchQuery field query = MatchQuery field query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1181data MatchQueryType =
1183 | MatchPhrasePrefix deriving (Eq, Show)
1185data MultiMatchQuery =
1186 MultiMatchQuery { multiMatchQueryFields :: [FieldName]
1187 , multiMatchQueryString :: QueryString
1188 , multiMatchQueryOperator :: BooleanOperator
1189 , multiMatchQueryZeroTerms :: ZeroTermsQuery
1190 , multiMatchQueryTiebreaker :: Maybe Tiebreaker
1191 , multiMatchQueryType :: Maybe MultiMatchQueryType
1192 , multiMatchQueryCutoffFrequency :: Maybe CutoffFrequency
1193 , multiMatchQueryAnalyzer :: Maybe Analyzer
1194 , multiMatchQueryMaxExpansions :: Maybe MaxExpansions
1195 , multiMatchQueryLenient :: Maybe Lenient } deriving (Eq, Show)
1197{-| 'mkMultiMatchQuery' is a convenience function that defaults the less common parameters,
1198 enabling you to provide only the list of 'FieldName's and 'QueryString' to
1199 make a 'MultiMatchQuery'.
1202mkMultiMatchQuery :: [FieldName] -> QueryString -> MultiMatchQuery
1203mkMultiMatchQuery matchFields query =
1204 MultiMatchQuery matchFields query
1205 Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1207data MultiMatchQueryType =
1208 MultiMatchBestFields
1209 | MultiMatchMostFields
1210 | MultiMatchCrossFields
1212 | MultiMatchPhrasePrefix deriving (Eq, Show)
1215 BoolQuery { boolQueryMustMatch :: [Query]
1216 , boolQueryMustNotMatch :: [Query]
1217 , boolQueryShouldMatch :: [Query]
1218 , boolQueryMinimumShouldMatch :: Maybe MinimumMatch
1219 , boolQueryBoost :: Maybe Boost
1220 , boolQueryDisableCoord :: Maybe DisableCoord
1221 } deriving (Eq, Show)
1223mkBoolQuery :: [Query] -> [Query] -> [Query] -> BoolQuery
1224mkBoolQuery must mustNot should =
1225 BoolQuery must mustNot should Nothing Nothing Nothing
1228 BoostingQuery { positiveQuery :: Query
1229 , negativeQuery :: Query
1230 , negativeBoost :: Boost } deriving (Eq, Show)
1232data CommonTermsQuery =
1233 CommonTermsQuery { commonField :: FieldName
1234 , commonQuery :: QueryString
1235 , commonCutoffFrequency :: CutoffFrequency
1236 , commonLowFreqOperator :: BooleanOperator
1237 , commonHighFreqOperator :: BooleanOperator
1238 , commonMinimumShouldMatch :: Maybe CommonMinimumMatch
1239 , commonBoost :: Maybe Boost
1240 , commonAnalyzer :: Maybe Analyzer
1241 , commonDisableCoord :: Maybe DisableCoord
1242 } deriving (Eq, Show)
1244data CommonMinimumMatch =
1245 CommonMinimumMatchHighLow MinimumMatchHighLow
1246 | CommonMinimumMatch MinimumMatch
1249data MinimumMatchHighLow =
1250 MinimumMatchHighLow { lowFreq :: MinimumMatch
1251 , highFreq :: MinimumMatch } deriving (Eq, Show)
1253data Filter = AndFilter [Filter] Cache
1254 | OrFilter [Filter] Cache
1255 | NotFilter Filter Cache
1257 | BoolFilter BoolMatch
1258 | ExistsFilter FieldName -- always cached
1259 | GeoBoundingBoxFilter GeoBoundingBoxConstraint
1260 | GeoDistanceFilter GeoPoint Distance DistanceType OptimizeBbox Cache
1261 | GeoDistanceRangeFilter GeoPoint DistanceRange
1262 | GeoPolygonFilter FieldName [LatLon]
1263 | IdsFilter MappingName [DocId]
1265 | MissingFilter FieldName Existence NullValue
1266 | PrefixFilter FieldName PrefixValue Cache
1267 | QueryFilter Query Cache
1268 | RangeFilter FieldName RangeValue RangeExecution Cache
1269 | RegexpFilter FieldName Regexp RegexpFlags CacheName Cache CacheKey
1270 | TermFilter Term Cache
1273data ZeroTermsQuery = ZeroTermsNone
1274 | ZeroTermsAll deriving (Eq, Show)
1276data RangeExecution = RangeExecutionIndex
1277 | RangeExecutionFielddata deriving (Eq, Show)
1279newtype Regexp = Regexp Text deriving (Eq, Show)
1281data RegexpFlags = AllRegexpFlags
1283 | SomeRegexpFlags (NonEmpty RegexpFlag) deriving (Eq, Show)
1285data RegexpFlag = AnyString
1290 | Interval deriving (Eq, Show)
1292newtype LessThan = LessThan Double deriving (Eq, Show)
1293newtype LessThanEq = LessThanEq Double deriving (Eq, Show)
1294newtype GreaterThan = GreaterThan Double deriving (Eq, Show)
1295newtype GreaterThanEq = GreaterThanEq Double deriving (Eq, Show)
1297newtype LessThanD = LessThanD UTCTime deriving (Eq, Show)
1298newtype LessThanEqD = LessThanEqD UTCTime deriving (Eq, Show)
1299newtype GreaterThanD = GreaterThanD UTCTime deriving (Eq, Show)
1300newtype GreaterThanEqD = GreaterThanEqD UTCTime deriving (Eq, Show)
1302data RangeValue = RangeDateLte LessThanEqD
1303 | RangeDateLt LessThanD
1304 | RangeDateGte GreaterThanEqD
1305 | RangeDateGt GreaterThanD
1306 | RangeDateGtLt GreaterThanD LessThanD
1307 | RangeDateGteLte GreaterThanEqD LessThanEqD
1308 | RangeDateGteLt GreaterThanEqD LessThanD
1309 | RangeDateGtLte GreaterThanD LessThanEqD
1310 | RangeDoubleLte LessThanEq
1311 | RangeDoubleLt LessThan
1312 | RangeDoubleGte GreaterThanEq
1313 | RangeDoubleGt GreaterThan
1314 | RangeDoubleGtLt GreaterThan LessThan
1315 | RangeDoubleGteLte GreaterThanEq LessThanEq
1316 | RangeDoubleGteLt GreaterThanEq LessThan
1317 | RangeDoubleGtLte GreaterThan LessThanEq
1320rangeValueToPair :: RangeValue -> [Pair]
1321rangeValueToPair rv = case rv of
1322 RangeDateLte (LessThanEqD t) -> ["lte" .= t]
1323 RangeDateGte (GreaterThanEqD t) -> ["gte" .= t]
1324 RangeDateLt (LessThanD t) -> ["lt" .= t]
1325 RangeDateGt (GreaterThanD t) -> ["gt" .= t]
1326 RangeDateGteLte (GreaterThanEqD l) (LessThanEqD g) -> ["gte" .= l, "lte" .= g]
1327 RangeDateGtLte (GreaterThanD l) (LessThanEqD g) -> ["gt" .= l, "lte" .= g]
1328 RangeDateGteLt (GreaterThanEqD l) (LessThanD g) -> ["gte" .= l, "lt" .= g]
1329 RangeDateGtLt (GreaterThanD l) (LessThanD g) -> ["gt" .= l, "lt" .= g]
1330 RangeDoubleLte (LessThanEq t) -> ["lte" .= t]
1331 RangeDoubleGte (GreaterThanEq t) -> ["gte" .= t]
1332 RangeDoubleLt (LessThan t) -> ["lt" .= t]
1333 RangeDoubleGt (GreaterThan t) -> ["gt" .= t]
1334 RangeDoubleGteLte (GreaterThanEq l) (LessThanEq g) -> ["gte" .= l, "lte" .= g]
1335 RangeDoubleGtLte (GreaterThan l) (LessThanEq g) -> ["gt" .= l, "lte" .= g]
1336 RangeDoubleGteLt (GreaterThanEq l) (LessThan g) -> ["gte" .= l, "lt" .= g]
1337 RangeDoubleGtLt (GreaterThan l) (LessThan g) -> ["gt" .= l, "lt" .= g]
1339data Term = Term { termField :: Text
1340 , termValue :: Text } deriving (Eq, Show)
1342data BoolMatch = MustMatch Term Cache
1343 | MustNotMatch Term Cache
1344 | ShouldMatch [Term] Cache deriving (Eq, Show)
1346-- "memory" or "indexed"
1347data GeoFilterType = GeoFilterMemory
1348 | GeoFilterIndexed deriving (Eq, Show)
1350data LatLon = LatLon { lat :: Double
1351 , lon :: Double } deriving (Eq, Show)
1353data GeoBoundingBox =
1354 GeoBoundingBox { topLeft :: LatLon
1355 , bottomRight :: LatLon } deriving (Eq, Show)
1357data GeoBoundingBoxConstraint =
1358 GeoBoundingBoxConstraint { geoBBField :: FieldName
1359 , constraintBox :: GeoBoundingBox
1360 , bbConstraintcache :: Cache
1361 , geoType :: GeoFilterType
1362 } deriving (Eq, Show)
1365 GeoPoint { geoField :: FieldName
1366 , latLon :: LatLon} deriving (Eq, Show)
1368data DistanceUnit = Miles
1376 | NauticalMiles deriving (Eq, Show)
1378data DistanceType = Arc
1379 | SloppyArc -- doesn't exist <1.0
1380 | Plane deriving (Eq, Show)
1382data OptimizeBbox = OptimizeGeoFilterType GeoFilterType
1383 | NoOptimizeBbox deriving (Eq, Show)
1386 Distance { coefficient :: Double
1387 , unit :: DistanceUnit } deriving (Eq, Show)
1390 DistanceRange { distanceFrom :: Distance
1391 , distanceTo :: Distance } deriving (Eq, Show)
1393data SearchResult a =
1394 SearchResult { took :: Int
1396 , shards :: ShardResult
1397 , searchHits :: SearchHits a
1398 , aggregations :: Maybe AggregationResults
1399 , scrollId :: Maybe ScrollId } deriving (Eq, Show)
1401type ScrollId = Text -- Fixme: Newtype
1403type Score = Maybe Double
1406 SearchHits { hitsTotal :: Int
1408 , hits :: [Hit a] } deriving (Eq, Show)
1411instance Monoid (SearchHits a) where
1412 mempty = SearchHits 0 Nothing mempty
1413 mappend (SearchHits ta ma ha) (SearchHits tb mb hb) =
1414 SearchHits (ta + tb) (max ma mb) (ha <> hb)
1418 Hit { hitIndex :: IndexName
1419 , hitType :: MappingName
1422 , hitSource :: Maybe a
1423 , hitHighlight :: Maybe HitHighlight } deriving (Eq, Show)
1426 ShardResult { shardTotal :: Int
1427 , shardsSuccessful :: Int
1428 , shardsFailed :: Int } deriving (Eq, Show, Generic)
1430type HitHighlight = M.Map Text [Text]
1432showText :: Show a => a -> Text
1433showText = T.pack . show
1435type Aggregations = M.Map Text Aggregation
1437emptyAggregations :: Aggregations
1438emptyAggregations = M.empty
1440mkAggregations :: Text -> Aggregation -> Aggregations
1441mkAggregations name aggregation = M.insert name aggregation emptyAggregations
1443data TermOrder = TermOrder{ termSortField :: Text
1444 , termSortOrder :: SortOrder } deriving (Eq, Show)
1446data TermInclusion = TermInclusion Text
1447 | TermPattern Text Text deriving (Eq, Show)
1449data CollectionMode = BreadthFirst
1450 | DepthFirst deriving (Eq, Show)
1452data ExecutionHint = Ordinals
1454 | GlobalOrdinalsHash
1455 | GlobalOrdinalsLowCardinality
1456 | Map deriving (Eq, Show)
1458data TimeInterval = Weeks
1462 | Seconds deriving (Eq)
1472 | FractionalInterval Float TimeInterval deriving (Eq, Show)
1474data Aggregation = TermsAgg TermsAggregation
1475 | DateHistogramAgg DateHistogramAggregation
1476 | ValueCountAgg ValueCountAggregation
1477 | FilterAgg FilterAggregation deriving (Eq, Show)
1480data TermsAggregation = TermsAggregation { term :: Either Text Text
1481 , termInclude :: Maybe TermInclusion
1482 , termExclude :: Maybe TermInclusion
1483 , termOrder :: Maybe TermOrder
1484 , termMinDocCount :: Maybe Int
1485 , termSize :: Maybe Int
1486 , termShardSize :: Maybe Int
1487 , termCollectMode :: Maybe CollectionMode
1488 , termExecutionHint :: Maybe ExecutionHint
1489 , termAggs :: Maybe Aggregations
1490 } deriving (Eq, Show)
1492data DateHistogramAggregation = DateHistogramAggregation { dateField :: FieldName
1493 , dateInterval :: Interval
1494 , dateFormat :: Maybe Text
1495 -- pre and post deprecated in 1.5
1496 , datePreZone :: Maybe Text
1497 , datePostZone :: Maybe Text
1498 , datePreOffset :: Maybe Text
1499 , datePostOffset :: Maybe Text
1500 , dateAggs :: Maybe Aggregations
1501 } deriving (Eq, Show)
1503-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html> for more information.
1504data ValueCountAggregation = FieldValueCount FieldName
1505 | ScriptValueCount Script deriving (Eq, Show)
1507-- | 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.
1508data FilterAggregation = FilterAggregation { faFilter :: Filter
1509 , faAggs :: Maybe Aggregations} deriving (Eq, Show)
1511mkTermsAggregation :: Text -> TermsAggregation
1512mkTermsAggregation t = TermsAggregation (Left t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1514mkTermsScriptAggregation :: Text -> TermsAggregation
1515mkTermsScriptAggregation t = TermsAggregation (Right t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1517mkDateHistogram :: FieldName -> Interval -> DateHistogramAggregation
1518mkDateHistogram t i = DateHistogramAggregation t i Nothing Nothing Nothing Nothing Nothing Nothing
1520instance ToJSON TermOrder where
1521 toJSON (TermOrder termSortField termSortOrder) = object [termSortField .= termSortOrder]
1523instance ToJSON TermInclusion where
1524 toJSON (TermInclusion x) = toJSON x
1525 toJSON (TermPattern pattern flags) = omitNulls [ "pattern" .= pattern,
1528instance ToJSON CollectionMode where
1529 toJSON BreadthFirst = "breadth_first"
1530 toJSON DepthFirst = "depth_first"
1532instance ToJSON ExecutionHint where
1533 toJSON Ordinals = "ordinals"
1534 toJSON GlobalOrdinals = "global_ordinals"
1535 toJSON GlobalOrdinalsHash = "global_ordinals_hash"
1536 toJSON GlobalOrdinalsLowCardinality = "global_ordinals_low_cardinality"
1539instance ToJSON Interval where
1540 toJSON Year = "year"
1541 toJSON Quarter = "quarter"
1542 toJSON Month = "month"
1543 toJSON Week = "week"
1545 toJSON Hour = "hour"
1546 toJSON Minute = "minute"
1547 toJSON Second = "second"
1548 toJSON (FractionalInterval fraction interval) = toJSON $ show fraction ++ show interval
1550instance Show TimeInterval where
1557instance ToJSON Aggregation where
1558 toJSON (TermsAgg (TermsAggregation term include exclude order minDocCount size shardSize collectMode executionHint termAggs)) =
1559 omitNulls ["terms" .= omitNulls [ toJSON' term,
1560 "include" .= include,
1561 "exclude" .= exclude,
1563 "min_doc_count" .= minDocCount,
1565 "shard_size" .= shardSize,
1566 "collect_mode" .= collectMode,
1567 "execution_hint" .= executionHint
1569 "aggs" .= termAggs ]
1571 toJSON' x = case x of { Left y -> "field" .= y; Right y -> "script" .= y }
1573 toJSON (DateHistogramAgg (DateHistogramAggregation field interval format preZone postZone preOffset postOffset dateHistoAggs)) =
1574 omitNulls ["date_histogram" .= omitNulls [ "field" .= field,
1575 "interval" .= interval,
1577 "pre_zone" .= preZone,
1578 "post_zone" .= postZone,
1579 "pre_offset" .= preOffset,
1580 "post_offset" .= postOffset
1582 "aggs" .= dateHistoAggs ]
1583 toJSON (ValueCountAgg a) = object ["value_count" .= v]
1585 (FieldValueCount (FieldName n)) -> object ["field" .= n]
1586 (ScriptValueCount (Script s)) -> object ["script" .= s]
1587 toJSON (FilterAgg (FilterAggregation filt ags)) =
1588 omitNulls [ "filter" .= filt
1591type AggregationResults = M.Map Text Value
1593class BucketAggregation a where
1595 docCount :: a -> Int
1596 aggs :: a -> Maybe AggregationResults
1599data Bucket a = Bucket { buckets :: [a]} deriving (Show)
1601data TermsResult = TermsResult { termKey :: Text
1602 , termsDocCount :: Int
1603 , termsAggs :: Maybe AggregationResults } deriving (Show)
1605data DateHistogramResult = DateHistogramResult { dateKey :: Int
1606 , dateKeyStr :: Maybe Text
1607 , dateDocCount :: Int
1608 , dateHistogramAggs :: Maybe AggregationResults } deriving (Show)
1610toTerms :: Text -> AggregationResults -> Maybe (Bucket TermsResult)
1611toTerms t a = M.lookup t a >>= deserialize
1612 where deserialize = parseMaybe parseJSON
1614toDateHistogram :: Text -> AggregationResults -> Maybe (Bucket DateHistogramResult)
1615toDateHistogram t a = M.lookup t a >>= deserialize
1616 where deserialize = parseMaybe parseJSON
1618instance BucketAggregation TermsResult where
1620 docCount = termsDocCount
1623instance BucketAggregation DateHistogramResult where
1624 key = showText . dateKey
1625 docCount = dateDocCount
1626 aggs = dateHistogramAggs
1628instance (FromJSON a, BucketAggregation a) => FromJSON (Bucket a) where
1629 parseJSON (Object v) = Bucket <$>
1631 parseJSON _ = mempty
1633instance FromJSON TermsResult where
1634 parseJSON (Object v) = TermsResult <$>
1636 v .: "doc_count" <*>
1637 v .:? "aggregations"
1638 parseJSON _ = mempty
1640instance FromJSON DateHistogramResult where
1641 parseJSON (Object v) = DateHistogramResult <$>
1643 v .:? "key_as_string" <*>
1644 v .: "doc_count" <*>
1645 v .:? "aggregations"
1646 parseJSON _ = mempty
1648instance Monoid Filter where
1649 mempty = IdentityFilter
1650 mappend a b = AndFilter [a, b] defaultCache
1652instance Seminearring Filter where
1653 a <||> b = OrFilter [a, b] defaultCache
1655instance ToJSON Filter where
1656 toJSON (AndFilter filters cache) =
1658 object [ "filters" .= fmap toJSON filters
1659 , "_cache" .= cache]]
1661 toJSON (OrFilter filters cache) =
1663 object [ "filters" .= fmap toJSON filters
1664 , "_cache" .= cache]]
1666 toJSON (NotFilter notFilter cache) =
1668 object ["filter" .= notFilter
1669 , "_cache" .= cache]]
1671 toJSON (IdentityFilter) =
1672 object ["match_all" .= object []]
1674 toJSON (TermFilter (Term termFilterField termFilterValue) cache) =
1675 object ["term" .= object base]
1676 where base = [termFilterField .= termFilterValue,
1679 toJSON (ExistsFilter (FieldName fieldName)) =
1680 object ["exists" .= object
1681 ["field" .= fieldName]]
1683 toJSON (BoolFilter boolMatch) =
1684 object ["bool" .= boolMatch]
1686 toJSON (GeoBoundingBoxFilter bbConstraint) =
1687 object ["geo_bounding_box" .= bbConstraint]
1689 toJSON (GeoDistanceFilter (GeoPoint (FieldName distanceGeoField) geoDistLatLon)
1690 distance distanceType optimizeBbox cache) =
1691 object ["geo_distance" .=
1692 object ["distance" .= distance
1693 , "distance_type" .= distanceType
1694 , "optimize_bbox" .= optimizeBbox
1695 , distanceGeoField .= geoDistLatLon
1696 , "_cache" .= cache]]
1698 toJSON (GeoDistanceRangeFilter (GeoPoint (FieldName gddrField) drLatLon)
1699 (DistanceRange geoDistRangeDistFrom drDistanceTo)) =
1700 object ["geo_distance_range" .=
1701 object ["from" .= geoDistRangeDistFrom
1702 , "to" .= drDistanceTo
1703 , gddrField .= drLatLon]]
1705 toJSON (GeoPolygonFilter (FieldName geoPolygonFilterField) latLons) =
1706 object ["geo_polygon" .=
1707 object [geoPolygonFilterField .=
1708 object ["points" .= fmap toJSON latLons]]]
1710 toJSON (IdsFilter (MappingName mappingName) values) =
1712 object ["type" .= mappingName
1713 , "values" .= fmap unpackId values]]
1715 toJSON (LimitFilter limit) =
1716 object ["limit" .= object ["value" .= limit]]
1718 toJSON (MissingFilter (FieldName fieldName) (Existence existence) (NullValue nullValue)) =
1719 object ["missing" .=
1720 object ["field" .= fieldName
1721 , "existence" .= existence
1722 , "null_value" .= nullValue]]
1724 toJSON (PrefixFilter (FieldName fieldName) fieldValue cache) =
1726 object [fieldName .= fieldValue
1727 , "_cache" .= cache]]
1729 toJSON (QueryFilter query False) =
1730 object ["query" .= toJSON query ]
1731 toJSON (QueryFilter query True) =
1733 object [ "query" .= toJSON query
1734 , "_cache" .= True ]]
1736 toJSON (RangeFilter (FieldName fieldName) rangeValue rangeExecution cache) =
1738 object [ fieldName .= object (rangeValueToPair rangeValue)
1739 , "execution" .= rangeExecution
1740 , "_cache" .= cache]]
1742 toJSON (RegexpFilter (FieldName fieldName)
1743 (Regexp regexText) flags (CacheName cacheName) cache (CacheKey cacheKey)) =
1745 object [fieldName .=
1746 object ["value" .= regexText
1748 , "_name" .= cacheName
1750 , "_cache_key" .= cacheKey]]
1752instance ToJSON GeoPoint where
1753 toJSON (GeoPoint (FieldName geoPointField) geoPointLatLon) =
1754 object [ geoPointField .= geoPointLatLon ]
1757instance ToJSON Query where
1758 toJSON (TermQuery (Term termQueryField termQueryValue) boost) =
1760 object [termQueryField .= object merged]]
1762 base = [ "value" .= termQueryValue ]
1763 boosted = maybe [] (return . ("boost" .=)) boost
1764 merged = mappend base boosted
1766 toJSON (TermsQuery terms) =
1767 object [ "terms" .= object conjoined ]
1768 where conjoined = [ getTermsField terms .=
1769 fmap (toJSON . getTermValue) (toList terms)]
1770 getTermsField ((Term f _ ) :| _) = f
1771 getTermValue (Term _ v) = v
1772 toJSON (IdsQuery idsQueryMappingName docIds) =
1773 object [ "ids" .= object conjoined ]
1774 where conjoined = [ "type" .= idsQueryMappingName
1775 , "values" .= fmap toJSON docIds ]
1777 toJSON (QueryQueryStringQuery qQueryStringQuery) =
1778 object [ "query_string" .= qQueryStringQuery ]
1780 toJSON (QueryMatchQuery matchQuery) =
1781 object [ "match" .= matchQuery ]
1783 toJSON (QueryMultiMatchQuery multiMatchQuery) =
1784 toJSON multiMatchQuery
1786 toJSON (QueryBoolQuery boolQuery) =
1787 object [ "bool" .= boolQuery ]
1789 toJSON (QueryBoostingQuery boostingQuery) =
1790 object [ "boosting" .= boostingQuery ]
1792 toJSON (QueryCommonTermsQuery commonTermsQuery) =
1793 object [ "common" .= commonTermsQuery ]
1795 toJSON (ConstantScoreFilter csFilter boost) =
1796 object [ "constant_score" .= csFilter
1799 toJSON (ConstantScoreQuery query boost) =
1800 object [ "constant_score" .= query
1803 toJSON (QueryDisMaxQuery disMaxQuery) =
1804 object [ "dis_max" .= disMaxQuery ]
1806 toJSON (QueryFilteredQuery qFilteredQuery) =
1807 object [ "filtered" .= qFilteredQuery ]
1809 toJSON (QueryFuzzyLikeThisQuery fuzzyQuery) =
1810 object [ "fuzzy_like_this" .= fuzzyQuery ]
1812 toJSON (QueryFuzzyLikeFieldQuery fuzzyFieldQuery) =
1813 object [ "fuzzy_like_this_field" .= fuzzyFieldQuery ]
1815 toJSON (QueryFuzzyQuery fuzzyQuery) =
1816 object [ "fuzzy" .= fuzzyQuery ]
1818 toJSON (QueryHasChildQuery childQuery) =
1819 object [ "has_child" .= childQuery ]
1821 toJSON (QueryHasParentQuery parentQuery) =
1822 object [ "has_parent" .= parentQuery ]
1824 toJSON (QueryIndicesQuery qIndicesQuery) =
1825 object [ "indices" .= qIndicesQuery ]
1827 toJSON (MatchAllQuery boost) =
1828 object [ "match_all" .= omitNulls [ "boost" .= boost ] ]
1830 toJSON (QueryMoreLikeThisQuery query) =
1831 object [ "more_like_this" .= query ]
1833 toJSON (QueryMoreLikeThisFieldQuery query) =
1834 object [ "more_like_this_field" .= query ]
1836 toJSON (QueryNestedQuery query) =
1837 object [ "nested" .= query ]
1839 toJSON (QueryPrefixQuery query) =
1840 object [ "prefix" .= query ]
1842 toJSON (QueryRangeQuery query) =
1843 object [ "range" .= query ]
1845 toJSON (QueryRegexpQuery query) =
1846 object [ "regexp" .= query ]
1848 toJSON (QuerySimpleQueryStringQuery query) =
1849 object [ "simple_query_string" .= query ]
1852omitNulls :: [(Text, Value)] -> Value
1853omitNulls = object . filter notNull where
1854 notNull (_, Null) = False
1855 notNull (_, Array a) = (not . V.null) a
1859instance ToJSON SimpleQueryStringQuery where
1860 toJSON SimpleQueryStringQuery {..} =
1861 omitNulls (base ++ maybeAdd)
1862 where base = [ "query" .= simpleQueryStringQuery ]
1863 maybeAdd = [ "fields" .= simpleQueryStringField
1864 , "default_operator" .= simpleQueryStringOperator
1865 , "analyzer" .= simpleQueryStringAnalyzer
1866 , "flags" .= simpleQueryStringFlags
1867 , "lowercase_expanded_terms" .= simpleQueryStringLowercaseExpanded
1868 , "locale" .= simpleQueryStringLocale ]
1871instance ToJSON FieldOrFields where
1872 toJSON (FofField fieldName) =
1874 toJSON (FofFields fieldNames) =
1877instance ToJSON SimpleQueryFlag where
1878 toJSON SimpleQueryAll = "ALL"
1879 toJSON SimpleQueryNone = "NONE"
1880 toJSON SimpleQueryAnd = "AND"
1881 toJSON SimpleQueryOr = "OR"
1882 toJSON SimpleQueryPrefix = "PREFIX"
1883 toJSON SimpleQueryPhrase = "PHRASE"
1884 toJSON SimpleQueryPrecedence = "PRECEDENCE"
1885 toJSON SimpleQueryEscape = "ESCAPE"
1886 toJSON SimpleQueryWhitespace = "WHITESPACE"
1887 toJSON SimpleQueryFuzzy = "FUZZY"
1888 toJSON SimpleQueryNear = "NEAR"
1889 toJSON SimpleQuerySlop = "SLOP"
1892instance ToJSON RegexpQuery where
1893 toJSON (RegexpQuery (FieldName rqQueryField)
1894 (Regexp regexpQueryQuery) rqQueryFlags
1896 object [ rqQueryField .= omitNulls base ]
1897 where base = [ "value" .= regexpQueryQuery
1898 , "flags" .= rqQueryFlags
1899 , "boost" .= rqQueryBoost ]
1902instance ToJSON QueryStringQuery where
1903 toJSON (QueryStringQuery qsQueryString
1904 qsDefaultField qsOperator
1905 qsAnalyzer qsAllowWildcard
1906 qsLowercaseExpanded qsEnablePositionIncrements
1907 qsFuzzyMaxExpansions qsFuzziness
1908 qsFuzzyPrefixLength qsPhraseSlop
1909 qsBoost qsAnalyzeWildcard
1910 qsGeneratePhraseQueries qsMinimumShouldMatch
1911 qsLenient qsLocale) =
1914 base = [ "query" .= qsQueryString
1915 , "default_field" .= qsDefaultField
1916 , "default_operator" .= qsOperator
1917 , "analyzer" .= qsAnalyzer
1918 , "allow_leading_wildcard" .= qsAllowWildcard
1919 , "lowercase_expanded_terms" .= qsLowercaseExpanded
1920 , "enable_position_increments" .= qsEnablePositionIncrements
1921 , "fuzzy_max_expansions" .= qsFuzzyMaxExpansions
1922 , "fuzziness" .= qsFuzziness
1923 , "fuzzy_prefix_length" .= qsFuzzyPrefixLength
1924 , "phrase_slop" .= qsPhraseSlop
1925 , "boost" .= qsBoost
1926 , "analyze_wildcard" .= qsAnalyzeWildcard
1927 , "auto_generate_phrase_queries" .= qsGeneratePhraseQueries
1928 , "minimum_should_match" .= qsMinimumShouldMatch
1929 , "lenient" .= qsLenient
1930 , "locale" .= qsLocale ]
1933instance ToJSON RangeQuery where
1934 toJSON (RangeQuery (FieldName fieldName) range boost) =
1935 object [ fieldName .= conjoined ]
1936 where conjoined = [ "boost" .= boost ] ++ (rangeValueToPair range)
1939instance ToJSON PrefixQuery where
1940 toJSON (PrefixQuery (FieldName fieldName) queryValue boost) =
1941 object [ fieldName .= omitNulls base ]
1942 where base = [ "value" .= queryValue
1943 , "boost" .= boost ]
1946instance ToJSON NestedQuery where
1947 toJSON (NestedQuery nqPath nqScoreType nqQuery) =
1948 object [ "path" .= nqPath
1949 , "score_mode" .= nqScoreType
1950 , "query" .= nqQuery ]
1953instance ToJSON MoreLikeThisFieldQuery where
1954 toJSON (MoreLikeThisFieldQuery text (FieldName fieldName)
1955 percent mtf mqt stopwords mindf maxdf
1956 minwl maxwl boostTerms boost analyzer) =
1957 object [ fieldName .= omitNulls base ]
1958 where base = [ "like_text" .= text
1959 , "percent_terms_to_match" .= percent
1960 , "min_term_freq" .= mtf
1961 , "max_query_terms" .= mqt
1962 , "stop_words" .= stopwords
1963 , "min_doc_freq" .= mindf
1964 , "max_doc_freq" .= maxdf
1965 , "min_word_length" .= minwl
1966 , "max_word_length" .= maxwl
1967 , "boost_terms" .= boostTerms
1969 , "analyzer" .= analyzer ]
1972instance ToJSON MoreLikeThisQuery where
1973 toJSON (MoreLikeThisQuery text fields percent
1974 mtf mqt stopwords mindf maxdf
1975 minwl maxwl boostTerms boost analyzer) =
1977 where base = [ "like_text" .= text
1978 , "fields" .= fields
1979 , "percent_terms_to_match" .= percent
1980 , "min_term_freq" .= mtf
1981 , "max_query_terms" .= mqt
1982 , "stop_words" .= stopwords
1983 , "min_doc_freq" .= mindf
1984 , "max_doc_freq" .= maxdf
1985 , "min_word_length" .= minwl
1986 , "max_word_length" .= maxwl
1987 , "boost_terms" .= boostTerms
1989 , "analyzer" .= analyzer ]
1992instance ToJSON IndicesQuery where
1993 toJSON (IndicesQuery indices query noMatch) =
1994 omitNulls [ "indices" .= indices
1995 , "no_match_query" .= noMatch
1996 , "query" .= query ]
1999instance ToJSON HasParentQuery where
2000 toJSON (HasParentQuery queryType query scoreType) =
2001 omitNulls [ "parent_type" .= queryType
2002 , "score_type" .= scoreType
2003 , "query" .= query ]
2006instance ToJSON HasChildQuery where
2007 toJSON (HasChildQuery queryType query scoreType) =
2008 omitNulls [ "query" .= query
2009 , "score_type" .= scoreType
2010 , "type" .= queryType ]
2013instance ToJSON FuzzyQuery where
2014 toJSON (FuzzyQuery (FieldName fieldName) queryText
2015 prefixLength maxEx fuzziness boost) =
2016 object [ fieldName .= omitNulls base ]
2017 where base = [ "value" .= queryText
2018 , "fuzziness" .= fuzziness
2019 , "prefix_length" .= prefixLength
2021 , "max_expansions" .= maxEx ]
2024instance ToJSON FuzzyLikeFieldQuery where
2025 toJSON (FuzzyLikeFieldQuery (FieldName fieldName)
2026 fieldText maxTerms ignoreFreq fuzziness prefixLength
2028 object [ fieldName .=
2029 omitNulls [ "like_text" .= fieldText
2030 , "max_query_terms" .= maxTerms
2031 , "ignore_tf" .= ignoreFreq
2032 , "fuzziness" .= fuzziness
2033 , "prefix_length" .= prefixLength
2034 , "analyzer" .= analyzer
2035 , "boost" .= boost ]]
2038instance ToJSON FuzzyLikeThisQuery where
2039 toJSON (FuzzyLikeThisQuery fields text maxTerms
2040 ignoreFreq fuzziness prefixLength boost analyzer) =
2042 where base = [ "fields" .= fields
2043 , "like_text" .= text
2044 , "max_query_terms" .= maxTerms
2045 , "ignore_tf" .= ignoreFreq
2046 , "fuzziness" .= fuzziness
2047 , "prefix_length" .= prefixLength
2048 , "analyzer" .= analyzer
2049 , "boost" .= boost ]
2052instance ToJSON FilteredQuery where
2053 toJSON (FilteredQuery query fFilter) =
2054 object [ "query" .= query
2055 , "filter" .= fFilter ]
2058instance ToJSON DisMaxQuery where
2059 toJSON (DisMaxQuery queries tiebreaker boost) =
2061 where base = [ "queries" .= queries
2063 , "tie_breaker" .= tiebreaker ]
2066instance ToJSON CommonTermsQuery where
2067 toJSON (CommonTermsQuery (FieldName fieldName)
2068 (QueryString query) cf lfo hfo msm
2069 boost analyzer disableCoord) =
2070 object [fieldName .= omitNulls base ]
2071 where base = [ "query" .= query
2072 , "cutoff_frequency" .= cf
2073 , "low_freq_operator" .= lfo
2074 , "minimum_should_match" .= msm
2076 , "analyzer" .= analyzer
2077 , "disable_coord" .= disableCoord
2078 , "high_freq_operator" .= hfo ]
2081instance ToJSON CommonMinimumMatch where
2082 toJSON (CommonMinimumMatch mm) = toJSON mm
2083 toJSON (CommonMinimumMatchHighLow (MinimumMatchHighLow lowF highF)) =
2084 object [ "low_freq" .= lowF
2085 , "high_freq" .= highF ]
2087instance ToJSON BoostingQuery where
2088 toJSON (BoostingQuery bqPositiveQuery bqNegativeQuery bqNegativeBoost) =
2089 object [ "positive" .= bqPositiveQuery
2090 , "negative" .= bqNegativeQuery
2091 , "negative_boost" .= bqNegativeBoost ]
2094instance ToJSON BoolQuery where
2095 toJSON (BoolQuery mustM notM shouldM bqMin boost disableCoord) =
2097 where base = [ "must" .= mustM
2098 , "must_not" .= notM
2099 , "should" .= shouldM
2100 , "minimum_should_match" .= bqMin
2102 , "disable_coord" .= disableCoord ]
2105instance ToJSON MatchQuery where
2106 toJSON (MatchQuery (FieldName fieldName)
2107 (QueryString mqQueryString) booleanOperator
2108 zeroTermsQuery cutoffFrequency matchQueryType
2109 analyzer maxExpansions lenient boost) =
2110 object [ fieldName .= omitNulls base ]
2111 where base = [ "query" .= mqQueryString
2112 , "operator" .= booleanOperator
2113 , "zero_terms_query" .= zeroTermsQuery
2114 , "cutoff_frequency" .= cutoffFrequency
2115 , "type" .= matchQueryType
2116 , "analyzer" .= analyzer
2117 , "max_expansions" .= maxExpansions
2118 , "lenient" .= lenient
2119 , "boost" .= boost ]
2122instance ToJSON MultiMatchQuery where
2123 toJSON (MultiMatchQuery fields (QueryString query) boolOp
2124 ztQ tb mmqt cf analyzer maxEx lenient) =
2125 object ["multi_match" .= omitNulls base]
2126 where base = [ "fields" .= fmap toJSON fields
2128 , "operator" .= boolOp
2129 , "zero_terms_query" .= ztQ
2130 , "tiebreaker" .= tb
2132 , "cutoff_frequency" .= cf
2133 , "analyzer" .= analyzer
2134 , "max_expansions" .= maxEx
2135 , "lenient" .= lenient ]
2138instance ToJSON MultiMatchQueryType where
2139 toJSON MultiMatchBestFields = "best_fields"
2140 toJSON MultiMatchMostFields = "most_fields"
2141 toJSON MultiMatchCrossFields = "cross_fields"
2142 toJSON MultiMatchPhrase = "phrase"
2143 toJSON MultiMatchPhrasePrefix = "phrase_prefix"
2145instance ToJSON BooleanOperator where
2146 toJSON And = String "and"
2147 toJSON Or = String "or"
2149instance ToJSON ZeroTermsQuery where
2150 toJSON ZeroTermsNone = String "none"
2151 toJSON ZeroTermsAll = String "all"
2153instance ToJSON MatchQueryType where
2154 toJSON MatchPhrase = "phrase"
2155 toJSON MatchPhrasePrefix = "phrase_prefix"
2157instance ToJSON FieldName where
2158 toJSON (FieldName fieldName) = String fieldName
2160instance ToJSON ReplicaCount where
2161 toJSON = genericToJSON defaultOptions
2162instance ToJSON ShardCount where
2163 toJSON = genericToJSON defaultOptions
2164instance ToJSON CutoffFrequency where
2165 toJSON = genericToJSON defaultOptions
2166instance ToJSON Analyzer where
2167 toJSON = genericToJSON defaultOptions
2168instance ToJSON MaxExpansions where
2169 toJSON = genericToJSON defaultOptions
2170instance ToJSON Lenient where
2171 toJSON = genericToJSON defaultOptions
2172instance ToJSON Boost where
2173 toJSON = genericToJSON defaultOptions
2174instance ToJSON Version where
2175 toJSON = genericToJSON defaultOptions
2176instance ToJSON Tiebreaker where
2177 toJSON = genericToJSON defaultOptions
2178instance ToJSON MinimumMatch where
2179 toJSON = genericToJSON defaultOptions
2180instance ToJSON DisableCoord where
2181 toJSON = genericToJSON defaultOptions
2182instance ToJSON PrefixLength where
2183 toJSON = genericToJSON defaultOptions
2184instance ToJSON Fuzziness where
2185 toJSON = genericToJSON defaultOptions
2186instance ToJSON IgnoreTermFrequency where
2187 toJSON = genericToJSON defaultOptions
2188instance ToJSON MaxQueryTerms where
2189 toJSON = genericToJSON defaultOptions
2190instance ToJSON TypeName where
2191 toJSON = genericToJSON defaultOptions
2192instance ToJSON IndexName where
2193 toJSON = genericToJSON defaultOptions
2194instance ToJSON TemplateName where
2195 toJSON = genericToJSON defaultOptions
2196instance ToJSON TemplatePattern where
2197 toJSON = genericToJSON defaultOptions
2198instance ToJSON BoostTerms where
2199 toJSON = genericToJSON defaultOptions
2200instance ToJSON MaxWordLength where
2201 toJSON = genericToJSON defaultOptions
2202instance ToJSON MinWordLength where
2203 toJSON = genericToJSON defaultOptions
2204instance ToJSON MaxDocFrequency where
2205 toJSON = genericToJSON defaultOptions
2206instance ToJSON MinDocFrequency where
2207 toJSON = genericToJSON defaultOptions
2208instance ToJSON PhraseSlop where
2209 toJSON = genericToJSON defaultOptions
2210instance ToJSON StopWord where
2211 toJSON = genericToJSON defaultOptions
2212instance ToJSON QueryPath where
2213 toJSON = genericToJSON defaultOptions
2214instance ToJSON MinimumTermFrequency where
2215 toJSON = genericToJSON defaultOptions
2216instance ToJSON PercentMatch where
2217 toJSON = genericToJSON defaultOptions
2218instance ToJSON MappingName where
2219 toJSON = genericToJSON defaultOptions
2220instance ToJSON DocId where
2221 toJSON = genericToJSON defaultOptions
2222instance ToJSON QueryString where
2223 toJSON = genericToJSON defaultOptions
2224instance ToJSON AllowLeadingWildcard where
2225 toJSON = genericToJSON defaultOptions
2226instance ToJSON LowercaseExpanded where
2227 toJSON = genericToJSON defaultOptions
2228instance ToJSON AnalyzeWildcard where
2229 toJSON = genericToJSON defaultOptions
2230instance ToJSON GeneratePhraseQueries where
2231 toJSON = genericToJSON defaultOptions
2232instance ToJSON Locale where
2233 toJSON = genericToJSON defaultOptions
2234instance ToJSON EnablePositionIncrements where
2235 toJSON = genericToJSON defaultOptions
2237instance FromJSON Version where
2238 parseJSON = genericParseJSON defaultOptions
2239instance FromJSON IndexName where
2240 parseJSON = genericParseJSON defaultOptions
2241instance FromJSON MappingName where
2242 parseJSON = genericParseJSON defaultOptions
2243instance FromJSON DocId where
2244 parseJSON = genericParseJSON defaultOptions
2247instance FromJSON Status where
2248 parseJSON (Object v) = Status <$>
2257instance ToJSON IndexSettings where
2258 toJSON (IndexSettings s r) = object ["settings" .=
2260 object ["number_of_shards" .= s, "number_of_replicas" .= r]
2264instance ToJSON UpdatableIndexSetting where
2265 toJSON (NumberOfReplicas x) = oPath ("index" :| ["number_of_replicas"]) x
2266 toJSON (AutoExpandReplicas x) = oPath ("index" :| ["auto_expand_replicas"]) x
2267 toJSON (BlocksReadOnly x) = oPath ("blocks" :| ["read_only"]) x
2268 toJSON (BlocksRead x) = oPath ("blocks" :| ["read"]) x
2269 toJSON (BlocksWrite x) = oPath ("blocks" :| ["write"]) x
2270 toJSON (BlocksMetaData x) = oPath ("blocks" :| ["metadata"]) x
2271 toJSON (RefreshInterval x) = oPath ("index" :| ["refresh_interval"]) (NominalDiffTimeJSON x)
2272 toJSON (IndexConcurrency x) = oPath ("index" :| ["concurrency"]) x
2273 toJSON (FailOnMergeFailure x) = oPath ("index" :| ["fail_on_merge_failure"]) x
2274 toJSON (TranslogFlushThresholdOps x) = oPath ("index" :| ["translog", "flush_threshold_ops"]) x
2275 toJSON (TranslogFlushThresholdSize x) = oPath ("index" :| ["translog", "flush_threshold_size"]) x
2276 toJSON (TranslogFlushThresholdPeriod x) = oPath ("index" :| ["translog", "flush_threshold_period"]) (NominalDiffTimeJSON x)
2277 toJSON (TranslogDisableFlush x) = oPath ("index" :| ["translog", "disable_flush"]) x
2278 toJSON (CacheFilterMaxSize x) = oPath ("index" :| ["cache", "filter", "max_size"]) x
2279 toJSON (CacheFilterExpire x) = oPath ("index" :| ["cache", "filter", "expire"]) (NominalDiffTimeJSON <$> x)
2280 toJSON (GatewaySnapshotInterval x) = oPath ("index" :| ["gateway", "snapshot_interval"]) (NominalDiffTimeJSON x)
2281 toJSON (RoutingAllocationInclude fs) = oPath ("index" :| ["routing", "allocation", "include"]) (attrFilterJSON fs)
2282 toJSON (RoutingAllocationExclude fs) = oPath ("index" :| ["routing", "allocation", "exclude"]) (attrFilterJSON fs)
2283 toJSON (RoutingAllocationRequire fs) = oPath ("index" :| ["routing", "allocation", "require"]) (attrFilterJSON fs)
2284 toJSON (RoutingAllocationEnable x) = oPath ("index" :| ["routing", "allocation", "enable"]) x
2285 toJSON (RoutingAllocationShardsPerNode x) = oPath ("index" :| ["routing", "allocation", "total_shards_per_node"]) x
2286 toJSON (RecoveryInitialShards x) = oPath ("index" :| ["recovery", "initial_shards"]) x
2287 toJSON (GCDeletes x) = oPath ("index" :| ["gc_deletes"]) (NominalDiffTimeJSON x)
2288 toJSON (TTLDisablePurge x) = oPath ("index" :| ["ttl", "disable_purge"]) x
2289 toJSON (TranslogFSType x) = oPath ("index" :| ["translog", "fs", "type"]) x
2290 toJSON (IndexCompoundFormat x) = oPath ("index" :| ["compound_format"]) x
2291 toJSON (IndexCompoundOnFlush x) = oPath ("index" :| ["compound_on_flush"]) x
2292 toJSON (WarmerEnabled x) = oPath ("index" :| ["warmer", "enabled"]) x
2294oPath :: ToJSON a => NonEmpty Text -> a -> Value
2295oPath (k :| []) v = object [k .= v]
2296oPath (k:| (h:t)) v = object [k .= oPath (h :| t) v]
2298attrFilterJSON :: NonEmpty NodeAttrFilter -> Value
2299attrFilterJSON fs = object [ n .= T.intercalate "," (toList vs)
2300 | NodeAttrFilter (NodeAttrName n) vs <- toList fs]
2302instance ToJSON ReplicaBounds where
2303 toJSON (ReplicasBounded a b) = String (showText a <> "-" <> showText b)
2304 toJSON (ReplicasLowerBounded a) = String (showText a <> "-all")
2305 toJSON ReplicasUnbounded = Bool False
2307instance ToJSON AllocationPolicy where
2308 toJSON AllocAll = String "all"
2309 toJSON AllocPrimaries = String "primaries"
2310 toJSON AllocNewPrimaries = String "new_primaries"
2311 toJSON AllocNone = String "none"
2313instance ToJSON InitialShardCount where
2314 toJSON QuorumShards = String "quorum"
2315 toJSON QuorumMinus1Shards = String "quorum-1"
2316 toJSON FullShards = String "full"
2317 toJSON FullMinus1Shards = String "full-1"
2318 toJSON (ExplicitShards x) = toJSON x
2320instance ToJSON FSType where
2321 toJSON FSSimple = "simple"
2322 toJSON FSBuffered = "buffered"
2324instance ToJSON CompoundFormat where
2325 toJSON (CompoundFileFormat x) = Bool x
2326 toJSON (MergeSegmentVsTotalIndex x) = toJSON x
2328instance ToJSON NominalDiffTimeJSON where
2329 toJSON (NominalDiffTimeJSON t) = String (showText (round t :: Integer) <> "s")
2331instance ToJSON IndexTemplate where
2332 toJSON (IndexTemplate p s m) = merge
2333 (object [ "template" .= p
2334 , "mappings" .= foldl' merge (object []) m
2338 merge (Object o1) (Object o2) = toJSON $ HM.union o1 o2
2340 merge _ _ = undefined
2342instance (FromJSON a) => FromJSON (EsResult a) where
2343 parseJSON jsonVal@(Object v) = do
2344 found <- v .:? "found" .!= False
2346 then parseJSON jsonVal
2348 EsResult <$> v .: "_index" <*>
2354instance (FromJSON a) => FromJSON (EsResultFound a) where
2355 parseJSON (Object v) = EsResultFound <$>
2360instance FromJSON EsError where
2361 parseJSON (Object v) = EsError <$>
2366instance ToJSON Search where
2367 toJSON (Search query sFilter sort searchAggs highlight sTrackSortScores sFrom sSize _ sFields sSource) =
2368 omitNulls [ "query" .= query
2369 , "filter" .= sFilter
2371 , "aggregations" .= searchAggs
2372 , "highlight" .= highlight
2375 , "track_scores" .= sTrackSortScores
2376 , "fields" .= sFields
2377 , "_source" .= sSource]
2380instance ToJSON Source where
2381 toJSON NoSource = toJSON False
2382 toJSON (SourcePatterns patterns) = toJSON patterns
2383 toJSON (SourceIncludeExclude incl excl) = object [ "include" .= incl, "exclude" .= excl ]
2385instance ToJSON PatternOrPatterns where
2386 toJSON (PopPattern pattern) = toJSON pattern
2387 toJSON (PopPatterns patterns) = toJSON patterns
2389instance ToJSON Include where
2390 toJSON (Include patterns) = toJSON patterns
2392instance ToJSON Exclude where
2393 toJSON (Exclude patterns) = toJSON patterns
2395instance ToJSON Pattern where
2396 toJSON (Pattern pattern) = toJSON pattern
2399instance ToJSON FieldHighlight where
2400 toJSON (FieldHighlight (FieldName fName) (Just fSettings)) =
2401 object [ fName .= fSettings ]
2402 toJSON (FieldHighlight (FieldName fName) Nothing) =
2403 object [ fName .= emptyObject ]
2405instance ToJSON Highlights where
2406 toJSON (Highlights global fields) =
2407 omitNulls (("fields" .= fields)
2408 : highlightSettingsPairs global)
2410instance ToJSON HighlightSettings where
2411 toJSON hs = omitNulls (highlightSettingsPairs (Just hs))
2413highlightSettingsPairs :: Maybe HighlightSettings -> [Pair]
2414highlightSettingsPairs Nothing = []
2415highlightSettingsPairs (Just (Plain plh)) = plainHighPairs (Just plh)
2416highlightSettingsPairs (Just (Postings ph)) = postHighPairs (Just ph)
2417highlightSettingsPairs (Just (FastVector fvh)) = fastVectorHighPairs (Just fvh)
2420plainHighPairs :: Maybe PlainHighlight -> [Pair]
2421plainHighPairs Nothing = []
2422plainHighPairs (Just (PlainHighlight plCom plNonPost)) =
2423 [ "type" .= String "plain"]
2424 ++ commonHighlightPairs plCom
2425 ++ nonPostingsToPairs plNonPost
2427postHighPairs :: Maybe PostingsHighlight -> [Pair]
2428postHighPairs Nothing = []
2429postHighPairs (Just (PostingsHighlight pCom)) =
2430 ("type" .= String "postings")
2431 : commonHighlightPairs pCom
2433fastVectorHighPairs :: Maybe FastVectorHighlight -> [Pair]
2434fastVectorHighPairs Nothing = []
2435fastVectorHighPairs (Just
2436 (FastVectorHighlight fvCom fvNonPostSettings fvBoundChars
2437 fvBoundMaxScan fvFragOff fvMatchedFields
2439 [ "type" .= String "fvh"
2440 , "boundary_chars" .= fvBoundChars
2441 , "boundary_max_scan" .= fvBoundMaxScan
2442 , "fragment_offset" .= fvFragOff
2443 , "matched_fields" .= fvMatchedFields
2444 , "phraseLimit" .= fvPhraseLim]
2445 ++ commonHighlightPairs fvCom
2446 ++ nonPostingsToPairs fvNonPostSettings
2448commonHighlightPairs :: Maybe CommonHighlight -> [Pair]
2449commonHighlightPairs Nothing = []
2450commonHighlightPairs (Just (CommonHighlight chScore chForceSource chTag chEncoder
2451 chNoMatchSize chHighlightQuery
2452 chRequireFieldMatch)) =
2453 [ "order" .= chScore
2454 , "force_source" .= chForceSource
2455 , "encoder" .= chEncoder
2456 , "no_match_size" .= chNoMatchSize
2457 , "highlight_query" .= chHighlightQuery
2458 , "require_fieldMatch" .= chRequireFieldMatch]
2459 ++ highlightTagToPairs chTag
2462nonPostingsToPairs :: Maybe NonPostings -> [Pair]
2463nonPostingsToPairs Nothing = []
2464nonPostingsToPairs (Just (NonPostings npFragSize npNumOfFrags)) =
2465 [ "fragment_size" .= npFragSize
2466 , "number_of_fragments" .= npNumOfFrags]
2470instance ToJSON HighlightEncoder where
2471 toJSON DefaultEncoder = String "default"
2472 toJSON HTMLEncoder = String "html"
2474highlightTagToPairs :: Maybe HighlightTag -> [Pair]
2475highlightTagToPairs (Just (TagSchema _)) = [ "scheme" .= String "default"]
2476highlightTagToPairs (Just (CustomTags (pre, post))) = [ "pre_tags" .= pre
2477 , "post_tags" .= post]
2478highlightTagToPairs Nothing = []
2480instance ToJSON SortSpec where
2481 toJSON (DefaultSortSpec
2482 (DefaultSort (FieldName dsSortFieldName) dsSortOrder dsIgnoreUnmapped
2483 dsSortMode dsMissingSort dsNestedFilter)) =
2484 object [dsSortFieldName .= omitNulls base] where
2485 base = [ "order" .= dsSortOrder
2486 , "ignore_unmapped" .= dsIgnoreUnmapped
2487 , "mode" .= dsSortMode
2488 , "missing" .= dsMissingSort
2489 , "nested_filter" .= dsNestedFilter ]
2491 toJSON (GeoDistanceSortSpec gdsSortOrder (GeoPoint (FieldName field) gdsLatLon) units) =
2492 object [ "unit" .= units
2493 , field .= gdsLatLon
2494 , "order" .= gdsSortOrder ]
2497instance ToJSON SortOrder where
2498 toJSON Ascending = String "asc"
2499 toJSON Descending = String "desc"
2502instance ToJSON SortMode where
2503 toJSON SortMin = String "min"
2504 toJSON SortMax = String "max"
2505 toJSON SortSum = String "sum"
2506 toJSON SortAvg = String "avg"
2509instance ToJSON Missing where
2510 toJSON LastMissing = String "_last"
2511 toJSON FirstMissing = String "_first"
2512 toJSON (CustomMissing txt) = String txt
2515instance ToJSON ScoreType where
2516 toJSON ScoreTypeMax = "max"
2517 toJSON ScoreTypeAvg = "avg"
2518 toJSON ScoreTypeSum = "sum"
2519 toJSON ScoreTypeNone = "none"
2522instance ToJSON Distance where
2523 toJSON (Distance dCoefficient dUnit) =
2524 String boltedTogether where
2525 coefText = showText dCoefficient
2526 (String unitText) = toJSON dUnit
2527 boltedTogether = mappend coefText unitText
2530instance ToJSON DistanceUnit where
2531 toJSON Miles = String "mi"
2532 toJSON Yards = String "yd"
2533 toJSON Feet = String "ft"
2534 toJSON Inches = String "in"
2535 toJSON Kilometers = String "km"
2536 toJSON Meters = String "m"
2537 toJSON Centimeters = String "cm"
2538 toJSON Millimeters = String "mm"
2539 toJSON NauticalMiles = String "nmi"
2542instance ToJSON DistanceType where
2543 toJSON Arc = String "arc"
2544 toJSON SloppyArc = String "sloppy_arc"
2545 toJSON Plane = String "plane"
2548instance ToJSON OptimizeBbox where
2549 toJSON NoOptimizeBbox = String "none"
2550 toJSON (OptimizeGeoFilterType gft) = toJSON gft
2553instance ToJSON GeoBoundingBoxConstraint where
2554 toJSON (GeoBoundingBoxConstraint
2555 (FieldName gbbcGeoBBField) gbbcConstraintBox cache type') =
2556 object [gbbcGeoBBField .= gbbcConstraintBox
2561instance ToJSON GeoFilterType where
2562 toJSON GeoFilterMemory = String "memory"
2563 toJSON GeoFilterIndexed = String "indexed"
2566instance ToJSON GeoBoundingBox where
2567 toJSON (GeoBoundingBox gbbTopLeft gbbBottomRight) =
2568 object ["top_left" .= gbbTopLeft
2569 , "bottom_right" .= gbbBottomRight]
2572instance ToJSON LatLon where
2573 toJSON (LatLon lLat lLon) =
2574 object ["lat" .= lLat
2578-- index for smaller ranges, fielddata for longer ranges
2579instance ToJSON RangeExecution where
2580 toJSON RangeExecutionIndex = "index"
2581 toJSON RangeExecutionFielddata = "fielddata"
2584instance ToJSON RegexpFlags where
2585 toJSON AllRegexpFlags = String "ALL"
2586 toJSON NoRegexpFlags = String "NONE"
2587 toJSON (SomeRegexpFlags (h :| fs)) = String $ T.intercalate "|" flagStrs
2588 where flagStrs = map flagStr . nub $ h:fs
2589 flagStr AnyString = "ANYSTRING"
2590 flagStr Automaton = "AUTOMATON"
2591 flagStr Complement = "COMPLEMENT"
2592 flagStr Empty = "EMPTY"
2593 flagStr Intersection = "INTERSECTION"
2594 flagStr Interval = "INTERVAL"
2596instance ToJSON Term where
2597 toJSON (Term field value) = object ["term" .= object
2601instance ToJSON BoolMatch where
2602 toJSON (MustMatch term cache) = object ["must" .= term,
2604 toJSON (MustNotMatch term cache) = object ["must_not" .= term,
2606 toJSON (ShouldMatch terms cache) = object ["should" .= fmap toJSON terms,
2610instance (FromJSON a) => FromJSON (SearchResult a) where
2611 parseJSON (Object v) = SearchResult <$>
2613 v .: "timed_out" <*>
2616 v .:? "aggregations" <*>
2620instance (FromJSON a) => FromJSON (SearchHits a) where
2621 parseJSON (Object v) = SearchHits <$>
2623 v .: "max_score" <*>
2627instance (FromJSON a) => FromJSON (Hit a) where
2628 parseJSON (Object v) = Hit <$>
2637instance FromJSON ShardResult where
2638 parseJSON (Object v) = ShardResult <$>
2640 v .: "successful" <*>
2645instance FromJSON DocVersion where
2648 maybe (fail "DocVersion out of range") return $ mkDocVersion i
2650instance Bounded DocVersion where
2651 minBound = DocVersion 1
2652 maxBound = DocVersion 9200000000000000000 -- 9.2e+18
2654instance Enum DocVersion where
2656 | x /= maxBound = DocVersion (succ $ docVersionNumber x)
2657 | otherwise = succError "DocVersion"
2659 | x /= minBound = DocVersion (pred $ docVersionNumber x)
2660 | otherwise = predError "DocVersion"
2662 fromMaybe (error $ show i ++ " out of DocVersion range") $ mkDocVersion i
2663 fromEnum = docVersionNumber
2664 enumFrom = boundedEnumFrom
2665 enumFromThen = boundedEnumFromThen
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list