1{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE DeriveGeneric #-}
3{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE GeneralizedNewtypeDeriving #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
7-- {-# LANGUAGE NoMonomorphismRestriction #-}
8{-# LANGUAGE OverloadedStrings #-}
9{-# LANGUAGE RecordWildCards #-}
10{-# LANGUAGE UndecidableInstances #-}
11{-# LANGUAGE NamedFieldPuns #-}
13-------------------------------------------------------------------------------
15-- Module : Database.Bloodhound.Types
16-- Copyright : (C) 2014, 2015, 2016 Chris Allen
17-- License : BSD-style (see the file LICENSE)
18-- Maintainer : Chris Allen <cma@bitemyapp.com
19-- Stability : provisional
20-- Portability : DeriveGeneric, RecordWildCards
22-- Data types for describing actions and data structures performed to interact
23-- with Elasticsearch. The two main buckets your queries against Elasticsearch
24-- will fall into are 'Query's and 'Filter's. 'Filter's are more like
25-- traditional database constraints and often have preferable performance
26-- properties. 'Query's support human-written textual queries, such as fuzzy
28-------------------------------------------------------------------------------
32module Database.Bloodhound.Types
34 , defaultIndexSettings
35 , defaultIndexDocumentSettings
46 , mkTermsScriptAggregation
67 , UpdatableIndexSetting(..)
68 , IndexSettingsSummary(..)
69 , AllocationPolicy(..)
73 , InitialShardCount(..)
83 , EsProtocolException(..)
86 , IndexAliasAction(..)
87 , IndexAliasCreate(..)
88 , IndexAliasSummary(..)
89 , IndexAliasesSummary(..)
91 , SearchAliasRouting(..)
92 , IndexAliasRouting(..)
95 , ExternalDocVersion(..)
98 , IndexDocumentSettings(..)
109 , PatternOrPatterns(..)
120 , GeoBoundingBoxConstraint(..)
146 , IndexOptimizationSettings(..)
147 , defaultIndexOptimizationSettings
149 , TemplatePattern(..)
167 , MultiMatchQuery(..)
170 , CommonTermsQuery(..)
173 , FuzzyLikeThisQuery(..)
174 , FuzzyLikeFieldQuery(..)
179 , MoreLikeThisQuery(..)
180 , MoreLikeThisFieldQuery(..)
183 , QueryStringQuery(..)
184 , SimpleQueryStringQuery(..)
188 , BooleanOperator(..)
190 , CutoffFrequency(..)
195 , MultiMatchQueryType(..)
199 , CommonMinimumMatch(..)
200 , MinimumMatchHighLow(..)
203 , IgnoreTermFrequency(..)
212 , MaxDocFrequency(..)
213 , MinDocFrequency(..)
217 , MinimumTermFrequency(..)
219 , FieldDefinition(..)
222 , AllowLeadingWildcard(..)
223 , LowercaseExpanded(..)
224 , GeneratePhraseQueries(..)
226 , AnalyzeWildcard(..)
227 , EnablePositionIncrements(..)
228 , SimpleQueryFlag(..)
244 , BucketAggregation(..)
245 , TermsAggregation(..)
246 , MissingAggregation(..)
247 , ValueCountAggregation(..)
248 , FilterAggregation(..)
249 , DateHistogramAggregation(..)
250 , DateRangeAggregation(..)
251 , DateRangeAggRange(..)
254 , DateMathModifier(..)
259 , HighlightSettings(..)
261 , PostingsHighlight(..)
262 , FastVectorHighlight(..)
263 , CommonHighlight(..)
265 , HighlightEncoder(..)
271 , DateHistogramResult(..)
272 , DateRangeResult(..)
278import Control.Applicative
279import Control.Monad.Catch
280import Control.Monad.Except
281import Control.Monad.Reader
282import Control.Monad.State
283import Control.Monad.Writer
285import Data.Aeson.Types (Pair, Parser, emptyObject,
287import qualified Data.ByteString.Lazy.Char8 as L
289import Data.Hashable (Hashable)
290import qualified Data.HashMap.Strict as HM
291import Data.List (foldl', nub)
292import Data.List.NonEmpty (NonEmpty (..), toList)
293import qualified Data.Map.Strict as M
295import Data.Scientific (Scientific)
296import Data.Text (Text)
297import qualified Data.Text as T
298import Data.Time.Calendar
299import Data.Time.Clock (NominalDiffTime, UTCTime)
300import Data.Time.Clock.POSIX
301import qualified Data.Traversable as DT
302import Data.Typeable (Typeable)
303import qualified Data.Vector as V
305import GHC.Generics (Generic)
306import Network.HTTP.Client
307import qualified Network.HTTP.Types.Method as NHTM
308import qualified Text.Read as TR
310import Database.Bloodhound.Types.Class
311import Database.Bloodhound.Types.Internal
314-- >>> :set -XOverloadedStrings
315-- >>> import Data.Aeson
316-- >>> import Database.Bloodhound
317-- >>> let testServer = (Server "http://localhost:9200")
318-- >>> let testIndex = IndexName "twitter"
319-- >>> let testMapping = MappingName "tweet"
320-- >>> let defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
322-- defaultIndexSettings is exported by Database.Bloodhound as well
323-- no trailing slashes in servers, library handles building the path.
325-- | Create a 'BHEnv' with all optional fields defaulted. HTTP hook
326-- will be a noop. You can use the exported fields to customize it further, e.g.:
328-- >> (mkBHEnv myServer myManager) { bhRequestHook = customHook }
329mkBHEnv :: Server -> Manager -> BHEnv
330mkBHEnv s m = BHEnv s m return
333 unBH :: ReaderT BHEnv m a
348instance MonadTrans BH where
351instance (MonadReader r m) => MonadReader r (BH m) where
353 local f (BH (ReaderT m)) = BH $ ReaderT $ \r ->
356instance (Functor m, Applicative m, MonadIO m) => MonadBH (BH m) where
357 getBHEnv = BH getBHEnv
359runBH :: BHEnv -> BH m a -> m a
360runBH e f = runReaderT (unBH f) e
362{-| 'Version' is embedded in 'Status' -}
363data Version = Version { number :: Text
365 , build_timestamp :: UTCTime
366 , build_snapshot :: Bool
367 , lucene_version :: Text } deriving (Eq, Read, Show, Generic, Typeable)
369{-| 'Status' is a data type for describing the JSON body returned by
370 Elasticsearch when you query its status. This was deprecated in 1.2.0.
372 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-status.html#indices-status>
375data Status = Status { ok :: Maybe Bool
379 , tagline :: Text } deriving (Eq, Read, Show, Generic)
381{-| 'IndexSettings' is used to configure the shards and replicas when you create
382 an Elasticsearch Index.
384 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html>
388 IndexSettings { indexShards :: ShardCount
389 , indexReplicas :: ReplicaCount } deriving (Eq, Read, Show, Generic, Typeable)
391{-| 'defaultIndexSettings' is an 'IndexSettings' with 3 shards and 2 replicas. -}
392defaultIndexSettings :: IndexSettings
393defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
396{-| 'IndexOptimizationSettings' is used to configure index optimization. See
397 <https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-optimize.html>
400data IndexOptimizationSettings =
401 IndexOptimizationSettings { maxNumSegments :: Maybe Int
402 -- ^ Number of segments to optimize to. 1 will fully optimize the index. If omitted, the default behavior is to only optimize if the server deems it necessary.
403 , onlyExpungeDeletes :: Bool
404 -- ^ Should the optimize process only expunge segments with deletes in them? If the purpose of the optimization is to free disk space, this should be set to True.
405 , flushAfterOptimize :: Bool
406 -- ^ Should a flush be performed after the optimize.
407 } deriving (Eq, Show, Generic, Typeable)
410{-| 'defaultIndexOptimizationSettings' implements the default settings that
411 ElasticSearch uses for index optimization. 'maxNumSegments' is Nothing,
412 'onlyExpungeDeletes' is False, and flushAfterOptimize is True.
414defaultIndexOptimizationSettings :: IndexOptimizationSettings
415defaultIndexOptimizationSettings = IndexOptimizationSettings Nothing False True
417{-| 'UpdatableIndexSetting' are settings which may be updated after an index is created.
419 <https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html>
421data UpdatableIndexSetting = NumberOfReplicas ReplicaCount
422 -- ^ The number of replicas each shard has.
423 | AutoExpandReplicas ReplicaBounds
424 | BlocksReadOnly Bool
425 -- ^ Set to True to have the index read only. False to allow writes and metadata changes.
427 -- ^ Set to True to disable read operations against the index.
429 -- ^ Set to True to disable write operations against the index.
430 | BlocksMetaData Bool
431 -- ^ Set to True to disable metadata operations against the index.
432 | RefreshInterval NominalDiffTime
433 -- ^ The async refresh interval of a shard
434 | IndexConcurrency Int
435 | FailOnMergeFailure Bool
436 | TranslogFlushThresholdOps Int
437 -- ^ When to flush on operations.
438 | TranslogFlushThresholdSize Bytes
439 -- ^ When to flush based on translog (bytes) size.
440 | TranslogFlushThresholdPeriod NominalDiffTime
441 -- ^ When to flush based on a period of not flushing.
442 | TranslogDisableFlush Bool
443 -- ^ Disables flushing. Note, should be set for a short interval and then enabled.
444 | CacheFilterMaxSize (Maybe Bytes)
445 -- ^ The maximum size of filter cache (per segment in shard).
446 | CacheFilterExpire (Maybe NominalDiffTime)
447 -- ^ The expire after access time for filter cache.
448 | GatewaySnapshotInterval NominalDiffTime
449 -- ^ The gateway snapshot interval (only applies to shared gateways).
450 | RoutingAllocationInclude (NonEmpty NodeAttrFilter)
451 -- ^ A node matching any rule will be allowed to host shards from the index.
452 | RoutingAllocationExclude (NonEmpty NodeAttrFilter)
453 -- ^ A node matching any rule will NOT be allowed to host shards from the index.
454 | RoutingAllocationRequire (NonEmpty NodeAttrFilter)
455 -- ^ Only nodes matching all rules will be allowed to host shards from the index.
456 | RoutingAllocationEnable AllocationPolicy
457 -- ^ Enables shard allocation for a specific index.
458 | RoutingAllocationShardsPerNode ShardCount
459 -- ^ Controls the total number of shards (replicas and primaries) allowed to be allocated on a single node.
460 | RecoveryInitialShards InitialShardCount
461 -- ^ When using local gateway a particular shard is recovered only if there can be allocated quorum shards in the cluster.
462 | GCDeletes NominalDiffTime
463 | TTLDisablePurge Bool
464 -- ^ Disables temporarily the purge of expired docs.
465 | TranslogFSType FSType
466 | IndexCompoundFormat CompoundFormat
467 | IndexCompoundOnFlush Bool
469 deriving (Eq, Show, Generic, Typeable)
471data AllocationPolicy = AllocAll
472 -- ^ Allows shard allocation for all shards.
474 -- ^ Allows shard allocation only for primary shards.
476 -- ^ Allows shard allocation only for primary shards for new indices.
478 -- ^ No shard allocation is allowed
479 deriving (Eq, Read, Show, Generic, Typeable)
481data ReplicaBounds = ReplicasBounded Int Int
482 | ReplicasLowerBounded Int
484 deriving (Eq, Read, Show, Generic, Typeable)
486newtype Bytes = Bytes Int deriving (Eq, Read, Show, Generic, Typeable, Ord, ToJSON, FromJSON)
488data FSType = FSSimple
489 | FSBuffered deriving (Eq, Read, Show, Generic, Typeable, Ord)
491data InitialShardCount = QuorumShards
496 deriving (Eq, Read, Show, Generic, Typeable)
498data NodeAttrFilter = NodeAttrFilter { nodeAttrFilterName :: NodeAttrName
499 , nodeAttrFilterValues :: NonEmpty Text}
500 deriving (Eq, Read, Show, Generic, Ord)
502newtype NodeAttrName = NodeAttrName Text deriving (Eq, Read, Show, Ord, Generic, Typeable)
504data CompoundFormat = CompoundFileFormat Bool
505 | MergeSegmentVsTotalIndex Double
506 -- ^ percentage between 0 and 1 where 0 is false, 1 is true
507 deriving (Eq, Read, Show, Generic, Typeable)
509newtype NominalDiffTimeJSON = NominalDiffTimeJSON { ndtJSON :: NominalDiffTime }
511data IndexSettingsSummary = IndexSettingsSummary { sSummaryIndexName :: IndexName
512 , sSummaryFixedSettings :: IndexSettings
513 , sSummaryUpdateable :: [UpdatableIndexSetting]}
514 deriving (Eq, Show, Generic, Typeable)
516{-| 'Reply' and 'Method' are type synonyms from 'Network.HTTP.Types.Method.Method' -}
517type Reply = Network.HTTP.Client.Response L.ByteString
518type Method = NHTM.Method
520{-| 'OpenCloseIndex' is a sum type for opening and closing indices.
522 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-open-close.html>
524data OpenCloseIndex = OpenIndex | CloseIndex deriving (Eq, Read, Show, Generic, Typeable)
526data FieldType = GeoPointType
532 | ByteType deriving (Eq, Read, Show, Generic, Typeable)
534data FieldDefinition =
535 FieldDefinition { fieldType :: FieldType } deriving (Eq, Read, Show, Generic, Typeable)
537{-| An 'IndexTemplate' defines a template that will automatically be
538 applied to new indices created. The templates include both
539 'IndexSettings' and mappings, and a simple 'TemplatePattern' that
540 controls if the template will be applied to the index created.
541 Specify mappings as follows: @[toJSON TweetMapping, ...]@
543 https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-templates.html
546 IndexTemplate { templatePattern :: TemplatePattern
547 , templateSettings :: Maybe IndexSettings
548 , templateMappings :: [Value]
552 MappingField { mappingFieldName :: FieldName
553 , fieldDefinition :: FieldDefinition } deriving (Eq, Read, Show, Generic, Typeable)
555{-| Support for type reification of 'Mapping's is currently incomplete, for
556 now the mapping API verbiage expects a 'ToJSON'able blob.
558 Indexes have mappings, mappings are schemas for the documents contained in the
559 index. I'd recommend having only one mapping per index, always having a mapping,
560 and keeping different kinds of documents separated if possible.
562data Mapping = Mapping { typeName :: TypeName
563 , mappingFields :: [MappingField] } deriving (Eq, Read, Show, Generic, Typeable)
565{-| 'BulkOperation' is a sum type for expressing the four kinds of bulk
566 operation index, create, delete, and update. 'BulkIndex' behaves like an
567 "upsert", 'BulkCreate' will fail if a document already exists at the DocId.
569 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-bulk.html#docs-bulk>
572 BulkIndex IndexName MappingName DocId Value
573 | BulkCreate IndexName MappingName DocId Value
574 | BulkDelete IndexName MappingName DocId
575 | BulkUpdate IndexName MappingName DocId Value deriving (Eq, Read, Show, Generic, Typeable)
577{-| 'EsResult' describes the standard wrapper JSON document that you see in
578 successful Elasticsearch lookups or lookups that couldn't find the document.
580data EsResult a = EsResult { _index :: Text
583 , foundResult :: Maybe (EsResultFound a)} deriving (Eq, Read, Show, Generic, Typeable)
585{-| 'EsResultFound' contains the document and its metadata inside of an
586 'EsResult' when the document was successfully found.
588data EsResultFound a = EsResultFound { _version :: DocVersion
589 , _source :: a } deriving (Eq, Read, Show, Generic, Typeable)
591{-| 'EsError' is the generic type that will be returned when there was a
592 problem. If you can't parse the expected response, its a good idea to
595data EsError = EsError { errorStatus :: Int
596 , errorMessage :: Text } deriving (Eq, Read, Show, Generic, Typeable)
598{-| 'EsProtocolException' will be thrown if Bloodhound cannot parse a response
599returned by the ElasticSearch server. If you encounter this error, please
600verify that your domain data types and FromJSON instances are working properly
601(for example, the 'a' of '[Hit a]' in 'SearchResult.searchHits.hits'). If you're
602sure that your mappings are correct, then this error may be an indication of an
603incompatibility between Bloodhound and ElasticSearch. Please open a bug report
604and be sure to include the exception body.
606data EsProtocolException = EsProtocolException { esProtoExBody :: L.ByteString }
607 deriving (Eq, Read, Show, Generic, Typeable)
609instance Exception EsProtocolException
611data IndexAlias = IndexAlias { srcIndex :: IndexName
612 , indexAlias :: IndexAliasName } deriving (Eq, Read, Show, Generic, Typeable)
614newtype IndexAliasName = IndexAliasName { indexAliasName :: IndexName } deriving (Eq, Read, Show, Generic, ToJSON)
616data IndexAliasAction = AddAlias IndexAlias IndexAliasCreate
617 | RemoveAlias IndexAlias deriving (Read, Show, Eq, Generic, Typeable)
619data IndexAliasCreate = IndexAliasCreate { aliasCreateRouting :: Maybe AliasRouting
620 , aliasCreateFilter :: Maybe Filter}
621 deriving (Read, Show, Eq, Generic, Typeable)
623data AliasRouting = AllAliasRouting RoutingValue
624 | GranularAliasRouting (Maybe SearchAliasRouting) (Maybe IndexAliasRouting)
625 deriving (Read, Show, Eq, Generic, Typeable)
627newtype SearchAliasRouting = SearchAliasRouting (NonEmpty RoutingValue) deriving (Read, Show, Eq, Generic, Typeable)
629newtype IndexAliasRouting = IndexAliasRouting RoutingValue deriving (Read, Show, Eq, Generic, ToJSON, FromJSON, Typeable)
631newtype RoutingValue = RoutingValue { routingValue :: Text } deriving (Read, Show, Eq, Generic, ToJSON, FromJSON, Typeable)
633newtype IndexAliasesSummary = IndexAliasesSummary { indexAliasesSummary :: [IndexAliasSummary] } deriving (Read, Show, Eq, Generic, Typeable)
635{-| 'IndexAliasSummary' is a summary of an index alias configured for a server. -}
636data IndexAliasSummary = IndexAliasSummary { indexAliasSummaryAlias :: IndexAlias
637 , indexAliasSummaryCreate :: IndexAliasCreate} deriving (Read, Show, Eq, Generic, Typeable)
639{-| 'DocVersion' is an integer version number for a document between 1
640and 9.2e+18 used for <<https://www.elastic.co/guide/en/elasticsearch/guide/current/optimistic-concurrency-control.html optimistic concurrency control>>.
642newtype DocVersion = DocVersion {
643 docVersionNumber :: Int
644 } deriving (Eq, Read, Show, Generic, Ord, ToJSON)
646-- | Smart constructor for in-range doc version
647mkDocVersion :: Int -> Maybe DocVersion
649 | i >= (docVersionNumber minBound) && i <= (docVersionNumber maxBound) =
651 | otherwise = Nothing
654{-| 'ExternalDocVersion' is a convenience wrapper if your code uses its
655own version numbers instead of ones from ES.
657newtype ExternalDocVersion = ExternalDocVersion DocVersion
658 deriving (Eq, Read, Show, Generic, Ord, Bounded, Enum, ToJSON)
660{-| 'VersionControl' is specified when indexing documents as a
661optimistic concurrency control.
663data VersionControl = NoVersionControl
664 -- ^ Don't send a version. This is a pure overwrite.
665 | InternalVersion DocVersion
666 -- ^ Use the default ES versioning scheme. Only
667 -- index the document if the version is the same
668 -- as the one specified. Only applicable to
669 -- updates, as you should be getting Version from
671 | ExternalGT ExternalDocVersion
672 -- ^ Use your own version numbering. Only index
673 -- the document if the version is strictly higher
674 -- OR the document doesn't exist. The given
675 -- version will be used as the new version number
676 -- for the stored document. N.B. All updates must
677 -- increment this number, meaning there is some
678 -- global, external ordering of updates.
679 | ExternalGTE ExternalDocVersion
680 -- ^ Use your own version numbering. Only index
681 -- the document if the version is equal or higher
682 -- than the stored version. Will succeed if there
683 -- is no existing document. The given version will
684 -- be used as the new version number for the
685 -- stored document. Use with care, as this could
686 -- result in data loss.
687 | ForceVersion ExternalDocVersion
688 -- ^ The document will always be indexed and the
689 -- given version will be the new version. This is
690 -- typically used for correcting errors. Use with
691 -- care, as this could result in data loss.
692 deriving (Read, Show, Eq, Generic, Ord)
694{-| 'DocumentParent' is used to specify a parent document.
696newtype DocumentParent = DocumentParent DocId
697 deriving (Eq, Read, Show, Generic, Typeable)
699{-| 'IndexDocumentSettings' are special settings supplied when indexing
700a document. For the best backwards compatiblity when new fields are
701added, you should probably prefer to start with 'defaultIndexDocumentSettings'
703data IndexDocumentSettings =
704 IndexDocumentSettings { idsVersionControl :: VersionControl
705 , idsParent :: Maybe DocumentParent
706 } deriving (Eq, Read, Show, Generic, Typeable)
708{-| Reasonable default settings. Chooses no version control and no parent.
710defaultIndexDocumentSettings :: IndexDocumentSettings
711defaultIndexDocumentSettings = IndexDocumentSettings NoVersionControl Nothing
713{-| 'Sort' is a synonym for a list of 'SortSpec's. Sort behavior is order
714 dependent with later sorts acting as tie-breakers for earlier sorts.
716type Sort = [SortSpec]
718{-| The two main kinds of 'SortSpec' are 'DefaultSortSpec' and
719 'GeoDistanceSortSpec'. The latter takes a 'SortOrder', 'GeoPoint', and
720 'DistanceUnit' to express "nearness" to a single geographical point as a
723<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
725data SortSpec = DefaultSortSpec DefaultSort
726 | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit deriving (Eq, Read, Show, Generic, Typeable)
728{-| 'DefaultSort' is usually the kind of 'SortSpec' you'll want. There's a
729 'mkSort' convenience function for when you want to specify only the most
732<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
735 DefaultSort { sortFieldName :: FieldName
736 , sortOrder :: SortOrder
738 , ignoreUnmapped :: Bool
739 , sortMode :: Maybe SortMode
740 , missingSort :: Maybe Missing
741 , nestedFilter :: Maybe Filter } deriving (Eq, Read, Show, Generic, Typeable)
743{-| 'SortOrder' is 'Ascending' or 'Descending', as you might expect. These get
744 encoded into "asc" or "desc" when turned into JSON.
746<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
748data SortOrder = Ascending
749 | Descending deriving (Eq, Read, Show, Generic, Typeable)
751{-| 'Missing' prescribes how to handle missing fields. A missing field can be
752 sorted last, first, or using a custom value as a substitute.
754<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_missing_values>
756data Missing = LastMissing
758 | CustomMissing Text deriving (Eq, Read, Show, Generic, Typeable)
760{-| 'SortMode' prescribes how to handle sorting array/multi-valued fields.
762http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_sort_mode_option
764data SortMode = SortMin
767 | SortAvg deriving (Eq, Read, Show, Generic, Typeable)
769{-| 'mkSort' defaults everything but the 'FieldName' and the 'SortOrder' so
770 that you can concisely describe the usual kind of 'SortSpec's you want.
772mkSort :: FieldName -> SortOrder -> DefaultSort
773mkSort fieldName sOrder = DefaultSort fieldName sOrder False Nothing Nothing Nothing
775{-| 'Cache' is for telling ES whether it should cache a 'Filter' not.
776 'Query's cannot be cached.
778type Cache = Bool -- caching on/off
782{-| 'PrefixValue' is used in 'PrefixQuery' as the main query component.
784type PrefixValue = Text
786{-| 'BooleanOperator' is the usual And/Or operators with an ES compatible
787 JSON encoding baked in. Used all over the place.
789data BooleanOperator = And | Or deriving (Eq, Read, Show, Generic, Typeable)
791{-| 'ShardCount' is part of 'IndexSettings'
793newtype ShardCount = ShardCount Int deriving (Eq, Read, Show, Generic, ToJSON, Typeable)
795{-| 'ReplicaCount' is part of 'IndexSettings'
797newtype ReplicaCount = ReplicaCount Int deriving (Eq, Read, Show, Generic, ToJSON, Typeable)
799{-| 'IndexName' is used to describe which index to query/create/delete
801newtype IndexName = IndexName Text deriving (Eq, Generic, Read, Show, ToJSON, FromJSON, Typeable)
803{-| 'IndexSelection' is used for APIs which take a single index, a list of
804 indexes, or the special @_all@ index.
806data IndexSelection = IndexList (NonEmpty IndexName)
807 | AllIndexes deriving (Eq, Generic, Show, Typeable)
809{-| 'TemplateName' is used to describe which template to query/create/delete
811newtype TemplateName = TemplateName Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
813{-| 'TemplatePattern' represents a pattern which is matched against index names
815newtype TemplatePattern = TemplatePattern Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
817{-| 'MappingName' is part of mappings which are how ES describes and schematizes
818 the data in the indices.
820newtype MappingName = MappingName Text deriving (Eq, Generic, Read, Show, ToJSON, FromJSON, Typeable)
822{-| 'DocId' is a generic wrapper value for expressing unique Document IDs.
823 Can be set by the user or created by ES itself. Often used in client
824 functions for poking at specific documents.
826newtype DocId = DocId Text deriving (Eq, Generic, Read, Show, ToJSON, FromJSON, Typeable)
828{-| 'QueryString' is used to wrap query text bodies, be they human written or not.
830newtype QueryString = QueryString Text deriving (Eq, Generic, Read, Show, ToJSON, FromJSON, Typeable)
832{-| 'FieldName' is used all over the place wherever a specific field within
833 a document needs to be specified, usually in 'Query's or 'Filter's.
835newtype FieldName = FieldName Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
838{-| 'Script' is often used in place of 'FieldName' to specify more
839complex ways of extracting a value from a document.
841newtype Script = Script { scriptText :: Text } deriving (Eq, Read, Show, Generic, Typeable)
843{-| 'CacheName' is used in 'RegexpFilter' for describing the
844 'CacheKey' keyed caching behavior.
846newtype CacheName = CacheName Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
848{-| 'CacheKey' is used in 'RegexpFilter' to key regex caching.
851 CacheKey Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
853 Existence Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
855 NullValue Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
856newtype CutoffFrequency =
857 CutoffFrequency Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
859 Analyzer Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
860newtype MaxExpansions =
861 MaxExpansions Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
863{-| 'Lenient', if set to true, will cause format based failures to be
864 ignored. I don't know what the bloody default is, Elasticsearch
865 documentation didn't say what it was. Let me know if you figure it out.
868 Lenient Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
870 Tiebreaker Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
872 Boost Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
874 BoostTerms Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
876{-| 'MinimumMatch' controls how many should clauses in the bool query should
877 match. Can be an absolute value (2) or a percentage (30%) or a
880newtype MinimumMatch =
881 MinimumMatch Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
882newtype DisableCoord =
883 DisableCoord Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
884newtype IgnoreTermFrequency =
885 IgnoreTermFrequency Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
886newtype MinimumTermFrequency =
887 MinimumTermFrequency Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
888newtype MaxQueryTerms =
889 MaxQueryTerms Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
891 Fuzziness Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
893{-| 'PrefixLength' is the prefix length used in queries, defaults to 0. -}
894newtype PrefixLength =
895 PrefixLength Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
897 TypeName Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
898newtype PercentMatch =
899 PercentMatch Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
901 StopWord Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
903 QueryPath Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
905{-| Allowing a wildcard at the beginning of a word (eg "*ing") is particularly
906 heavy, because all terms in the index need to be examined, just in case
907 they match. Leading wildcards can be disabled by setting
908 'AllowLeadingWildcard' to false. -}
909newtype AllowLeadingWildcard =
910 AllowLeadingWildcard Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
911newtype LowercaseExpanded =
912 LowercaseExpanded Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
913newtype EnablePositionIncrements =
914 EnablePositionIncrements Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
916{-| By default, wildcard terms in a query are not analyzed.
917 Setting 'AnalyzeWildcard' to true enables best-effort analysis.
919newtype AnalyzeWildcard = AnalyzeWildcard Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
921{-| 'GeneratePhraseQueries' defaults to false.
923newtype GeneratePhraseQueries =
924 GeneratePhraseQueries Bool deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
926{-| 'Locale' is used for string conversions - defaults to ROOT.
928newtype Locale = Locale Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
929newtype MaxWordLength = MaxWordLength Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
930newtype MinWordLength = MinWordLength Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
932{-| 'PhraseSlop' sets the default slop for phrases, 0 means exact
933 phrase matches. Default is 0.
935newtype PhraseSlop = PhraseSlop Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
936newtype MinDocFrequency = MinDocFrequency Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
937newtype MaxDocFrequency = MaxDocFrequency Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
939-- | Newtype wrapper to parse ES's concerning tendency to in some APIs return a floating point number of milliseconds since epoch ಠ_ಠ
940newtype POSIXMS = POSIXMS { posixMS :: UTCTime }
942{-| 'unpackId' is a silly convenience function that gets used once.
944unpackId :: DocId -> Text
945unpackId (DocId docId) = docId
947type TrackSortScores = Bool
948newtype From = From Int deriving (Eq, Read, Show, Generic, ToJSON)
949newtype Size = Size Int deriving (Eq, Read, Show, Generic, ToJSON)
951data Search = Search { queryBody :: Maybe Query
952 , filterBody :: Maybe Filter
953 , sortBody :: Maybe Sort
954 , aggBody :: Maybe Aggregations
955 , highlight :: Maybe Highlights
957 , trackSortScores :: TrackSortScores
960 , searchType :: SearchType
961 , fields :: Maybe [FieldName]
962 , source :: Maybe Source } deriving (Eq, Read, Show, Generic, Typeable)
964data SearchType = SearchTypeQueryThenFetch
965 | SearchTypeDfsQueryThenFetch
968 | SearchTypeQueryAndFetch
969 | SearchTypeDfsQueryAndFetch
970 deriving (Eq, Read, Show, Generic, Typeable)
974 | SourcePatterns PatternOrPatterns
975 | SourceIncludeExclude Include Exclude
976 deriving (Read, Show, Eq, Generic, Typeable)
978data PatternOrPatterns = PopPattern Pattern
979 | PopPatterns [Pattern] deriving (Eq, Read, Show, Generic, Typeable)
981data Include = Include [Pattern] deriving (Eq, Read, Show, Generic, Typeable)
982data Exclude = Exclude [Pattern] deriving (Eq, Read, Show, Generic, Typeable)
984newtype Pattern = Pattern Text deriving (Eq, Read, Show, Generic, Typeable)
986data Highlights = Highlights { globalsettings :: Maybe HighlightSettings
987 , highlightFields :: [FieldHighlight]
988 } deriving (Read, Show, Eq, Generic, Typeable)
990data FieldHighlight = FieldHighlight FieldName (Maybe HighlightSettings)
991 deriving (Read, Show, Eq, Generic, Typeable)
994data HighlightSettings = Plain PlainHighlight
995 | Postings PostingsHighlight
996 | FastVector FastVectorHighlight
997 deriving (Read, Show, Eq, Generic, Typeable)
999 PlainHighlight { plainCommon :: Maybe CommonHighlight
1000 , plainNonPost :: Maybe NonPostings } deriving (Read, Show, Eq, Generic, Typeable)
1002 -- This requires that index_options are set to 'offset' in the mapping.
1003data PostingsHighlight = PostingsHighlight (Maybe CommonHighlight) deriving (Read, Show, Eq, Generic, Typeable)
1005-- This requires that term_vector is set to 'with_positions_offsets' in the mapping.
1006data FastVectorHighlight =
1007 FastVectorHighlight { fvCommon :: Maybe CommonHighlight
1008 , fvNonPostSettings :: Maybe NonPostings
1009 , boundaryChars :: Maybe Text
1010 , boundaryMaxScan :: Maybe Int
1011 , fragmentOffset :: Maybe Int
1012 , matchedFields :: [Text]
1013 , phraseLimit :: Maybe Int
1014 } deriving (Read, Show, Eq, Generic, Typeable)
1016data CommonHighlight =
1017 CommonHighlight { order :: Maybe Text
1018 , forceSource :: Maybe Bool
1019 , tag :: Maybe HighlightTag
1020 , encoder :: Maybe HighlightEncoder
1021 , noMatchSize :: Maybe Int
1022 , highlightQuery :: Maybe Query
1023 , requireFieldMatch :: Maybe Bool
1024 } deriving (Read, Show, Eq, Generic, Typeable)
1026-- Settings that are only applicable to FastVector and Plain highlighters.
1028 NonPostings { fragmentSize :: Maybe Int
1029 , numberOfFragments :: Maybe Int} deriving (Read, Show, Eq, Generic, Typeable)
1031data HighlightEncoder = DefaultEncoder
1033 deriving (Read, Show, Eq, Generic, Typeable)
1035-- NOTE: Should the tags use some kind of HTML type, rather than Text?
1036data HighlightTag = TagSchema Text
1037 | CustomTags ([Text], [Text]) -- Only uses more than the first value in the lists if fvh
1038 deriving (Read, Show, Eq, Generic, Typeable)
1042 TermQuery Term (Maybe Boost)
1043 | TermsQuery Text (NonEmpty Text)
1044 | QueryMatchQuery MatchQuery
1045 | QueryMultiMatchQuery MultiMatchQuery
1046 | QueryBoolQuery BoolQuery
1047 | QueryBoostingQuery BoostingQuery
1048 | QueryCommonTermsQuery CommonTermsQuery
1049 | ConstantScoreFilter Filter Boost
1050 | ConstantScoreQuery Query Boost
1051 | QueryDisMaxQuery DisMaxQuery
1052 | QueryFilteredQuery FilteredQuery
1053 | QueryFuzzyLikeThisQuery FuzzyLikeThisQuery
1054 | QueryFuzzyLikeFieldQuery FuzzyLikeFieldQuery
1055 | QueryFuzzyQuery FuzzyQuery
1056 | QueryHasChildQuery HasChildQuery
1057 | QueryHasParentQuery HasParentQuery
1058 | IdsQuery MappingName [DocId]
1059 | QueryIndicesQuery IndicesQuery
1060 | MatchAllQuery (Maybe Boost)
1061 | QueryMoreLikeThisQuery MoreLikeThisQuery
1062 | QueryMoreLikeThisFieldQuery MoreLikeThisFieldQuery
1063 | QueryNestedQuery NestedQuery
1064 | QueryPrefixQuery PrefixQuery
1065 | QueryQueryStringQuery QueryStringQuery
1066 | QuerySimpleQueryStringQuery SimpleQueryStringQuery
1067 | QueryRangeQuery RangeQuery
1068 | QueryRegexpQuery RegexpQuery
1069 deriving (Eq, Read, Show, Generic, Typeable)
1072 RegexpQuery { regexpQueryField :: FieldName
1073 , regexpQuery :: Regexp
1074 , regexpQueryFlags :: RegexpFlags
1075 , regexpQueryBoost :: Maybe Boost
1076 } deriving (Eq, Read, Show, Generic, Typeable)
1079 RangeQuery { rangeQueryField :: FieldName
1080 , rangeQueryRange :: RangeValue
1081 , rangeQueryBoost :: Boost } deriving (Eq, Read, Show, Generic, Typeable)
1083mkRangeQuery :: FieldName -> RangeValue -> RangeQuery
1084mkRangeQuery f r = RangeQuery f r (Boost 1.0)
1086data SimpleQueryStringQuery =
1087 SimpleQueryStringQuery
1088 { simpleQueryStringQuery :: QueryString
1089 , simpleQueryStringField :: Maybe FieldOrFields
1090 , simpleQueryStringOperator :: Maybe BooleanOperator
1091 , simpleQueryStringAnalyzer :: Maybe Analyzer
1092 , simpleQueryStringFlags :: Maybe (NonEmpty SimpleQueryFlag)
1093 , simpleQueryStringLowercaseExpanded :: Maybe LowercaseExpanded
1094 , simpleQueryStringLocale :: Maybe Locale
1095 } deriving (Eq, Read, Show, Generic, Typeable)
1097data SimpleQueryFlag =
1104 | SimpleQueryPrecedence
1106 | SimpleQueryWhitespace
1109 | SimpleQuerySlop deriving (Eq, Read, Show, Generic, Typeable)
1111-- use_dis_max and tie_breaker when fields are plural?
1112data QueryStringQuery =
1114 { queryStringQuery :: QueryString
1115 , queryStringDefaultField :: Maybe FieldName
1116 , queryStringOperator :: Maybe BooleanOperator
1117 , queryStringAnalyzer :: Maybe Analyzer
1118 , queryStringAllowLeadingWildcard :: Maybe AllowLeadingWildcard
1119 , queryStringLowercaseExpanded :: Maybe LowercaseExpanded
1120 , queryStringEnablePositionIncrements :: Maybe EnablePositionIncrements
1121 , queryStringFuzzyMaxExpansions :: Maybe MaxExpansions
1122 , queryStringFuzziness :: Maybe Fuzziness
1123 , queryStringFuzzyPrefixLength :: Maybe PrefixLength
1124 , queryStringPhraseSlop :: Maybe PhraseSlop
1125 , queryStringBoost :: Maybe Boost
1126 , queryStringAnalyzeWildcard :: Maybe AnalyzeWildcard
1127 , queryStringGeneratePhraseQueries :: Maybe GeneratePhraseQueries
1128 , queryStringMinimumShouldMatch :: Maybe MinimumMatch
1129 , queryStringLenient :: Maybe Lenient
1130 , queryStringLocale :: Maybe Locale
1131 } deriving (Eq, Read, Show, Generic, Typeable)
1133mkQueryStringQuery :: QueryString -> QueryStringQuery
1134mkQueryStringQuery qs =
1135 QueryStringQuery qs Nothing Nothing
1136 Nothing Nothing Nothing Nothing
1137 Nothing Nothing Nothing Nothing
1138 Nothing Nothing Nothing Nothing
1141data FieldOrFields = FofField FieldName
1142 | FofFields (NonEmpty FieldName) deriving (Eq, Read, Show, Generic, Typeable)
1146 { prefixQueryField :: FieldName
1147 , prefixQueryPrefixValue :: Text
1148 , prefixQueryBoost :: Maybe Boost } deriving (Eq, Read, Show, Generic, Typeable)
1152 { nestedQueryPath :: QueryPath
1153 , nestedQueryScoreType :: ScoreType
1154 , nestedQuery :: Query } deriving (Eq, Read, Show, Generic, Typeable)
1156data MoreLikeThisFieldQuery =
1157 MoreLikeThisFieldQuery
1158 { moreLikeThisFieldText :: Text
1159 , moreLikeThisFieldFields :: FieldName
1160 -- default 0.3 (30%)
1161 , moreLikeThisFieldPercentMatch :: Maybe PercentMatch
1162 , moreLikeThisFieldMinimumTermFreq :: Maybe MinimumTermFrequency
1163 , moreLikeThisFieldMaxQueryTerms :: Maybe MaxQueryTerms
1164 , moreLikeThisFieldStopWords :: Maybe (NonEmpty StopWord)
1165 , moreLikeThisFieldMinDocFrequency :: Maybe MinDocFrequency
1166 , moreLikeThisFieldMaxDocFrequency :: Maybe MaxDocFrequency
1167 , moreLikeThisFieldMinWordLength :: Maybe MinWordLength
1168 , moreLikeThisFieldMaxWordLength :: Maybe MaxWordLength
1169 , moreLikeThisFieldBoostTerms :: Maybe BoostTerms
1170 , moreLikeThisFieldBoost :: Maybe Boost
1171 , moreLikeThisFieldAnalyzer :: Maybe Analyzer
1172 } deriving (Eq, Read, Show, Generic, Typeable)
1174data MoreLikeThisQuery =
1176 { moreLikeThisText :: Text
1177 , moreLikeThisFields :: Maybe (NonEmpty FieldName)
1178 -- default 0.3 (30%)
1179 , moreLikeThisPercentMatch :: Maybe PercentMatch
1180 , moreLikeThisMinimumTermFreq :: Maybe MinimumTermFrequency
1181 , moreLikeThisMaxQueryTerms :: Maybe MaxQueryTerms
1182 , moreLikeThisStopWords :: Maybe (NonEmpty StopWord)
1183 , moreLikeThisMinDocFrequency :: Maybe MinDocFrequency
1184 , moreLikeThisMaxDocFrequency :: Maybe MaxDocFrequency
1185 , moreLikeThisMinWordLength :: Maybe MinWordLength
1186 , moreLikeThisMaxWordLength :: Maybe MaxWordLength
1187 , moreLikeThisBoostTerms :: Maybe BoostTerms
1188 , moreLikeThisBoost :: Maybe Boost
1189 , moreLikeThisAnalyzer :: Maybe Analyzer
1190 } deriving (Eq, Read, Show, Generic, Typeable)
1194 { indicesQueryIndices :: [IndexName]
1195 , indicesQuery :: Query
1197 , indicesQueryNoMatch :: Maybe Query } deriving (Eq, Read, Show, Generic, Typeable)
1199data HasParentQuery =
1201 { hasParentQueryType :: TypeName
1202 , hasParentQuery :: Query
1203 , hasParentQueryScoreType :: Maybe ScoreType } deriving (Eq, Read, Show, Generic, Typeable)
1207 { hasChildQueryType :: TypeName
1208 , hasChildQuery :: Query
1209 , hasChildQueryScoreType :: Maybe ScoreType } deriving (Eq, Read, Show, Generic, Typeable)
1215 | ScoreTypeNone deriving (Eq, Read, Show, Generic, Typeable)
1218 FuzzyQuery { fuzzyQueryField :: FieldName
1219 , fuzzyQueryValue :: Text
1220 , fuzzyQueryPrefixLength :: PrefixLength
1221 , fuzzyQueryMaxExpansions :: MaxExpansions
1222 , fuzzyQueryFuzziness :: Fuzziness
1223 , fuzzyQueryBoost :: Maybe Boost
1224 } deriving (Eq, Read, Show, Generic, Typeable)
1226data FuzzyLikeFieldQuery =
1228 { fuzzyLikeField :: FieldName
1229 -- anaphora is good for the soul.
1230 , fuzzyLikeFieldText :: Text
1231 , fuzzyLikeFieldMaxQueryTerms :: MaxQueryTerms
1232 , fuzzyLikeFieldIgnoreTermFrequency :: IgnoreTermFrequency
1233 , fuzzyLikeFieldFuzziness :: Fuzziness
1234 , fuzzyLikeFieldPrefixLength :: PrefixLength
1235 , fuzzyLikeFieldBoost :: Boost
1236 , fuzzyLikeFieldAnalyzer :: Maybe Analyzer
1237 } deriving (Eq, Read, Show, Generic, Typeable)
1239data FuzzyLikeThisQuery =
1241 { fuzzyLikeFields :: [FieldName]
1242 , fuzzyLikeText :: Text
1243 , fuzzyLikeMaxQueryTerms :: MaxQueryTerms
1244 , fuzzyLikeIgnoreTermFrequency :: IgnoreTermFrequency
1245 , fuzzyLikeFuzziness :: Fuzziness
1246 , fuzzyLikePrefixLength :: PrefixLength
1247 , fuzzyLikeBoost :: Boost
1248 , fuzzyLikeAnalyzer :: Maybe Analyzer
1249 } deriving (Eq, Read, Show, Generic, Typeable)
1253 { filteredQuery :: Query
1254 , filteredFilter :: Filter } deriving (Eq, Read, Show, Generic, Typeable)
1257 DisMaxQuery { disMaxQueries :: [Query]
1259 , disMaxTiebreaker :: Tiebreaker
1260 , disMaxBoost :: Maybe Boost
1261 } deriving (Eq, Read, Show, Generic, Typeable)
1264 MatchQuery { matchQueryField :: FieldName
1265 , matchQueryQueryString :: QueryString
1266 , matchQueryOperator :: BooleanOperator
1267 , matchQueryZeroTerms :: ZeroTermsQuery
1268 , matchQueryCutoffFrequency :: Maybe CutoffFrequency
1269 , matchQueryMatchType :: Maybe MatchQueryType
1270 , matchQueryAnalyzer :: Maybe Analyzer
1271 , matchQueryMaxExpansions :: Maybe MaxExpansions
1272 , matchQueryLenient :: Maybe Lenient
1273 , matchQueryBoost :: Maybe Boost } deriving (Eq, Read, Show, Generic, Typeable)
1275{-| 'mkMatchQuery' is a convenience function that defaults the less common parameters,
1276 enabling you to provide only the 'FieldName' and 'QueryString' to make a 'MatchQuery'
1278mkMatchQuery :: FieldName -> QueryString -> MatchQuery
1279mkMatchQuery field query = MatchQuery field query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1281data MatchQueryType =
1283 | MatchPhrasePrefix deriving (Eq, Read, Show, Generic, Typeable)
1285data MultiMatchQuery =
1286 MultiMatchQuery { multiMatchQueryFields :: [FieldName]
1287 , multiMatchQueryString :: QueryString
1288 , multiMatchQueryOperator :: BooleanOperator
1289 , multiMatchQueryZeroTerms :: ZeroTermsQuery
1290 , multiMatchQueryTiebreaker :: Maybe Tiebreaker
1291 , multiMatchQueryType :: Maybe MultiMatchQueryType
1292 , multiMatchQueryCutoffFrequency :: Maybe CutoffFrequency
1293 , multiMatchQueryAnalyzer :: Maybe Analyzer
1294 , multiMatchQueryMaxExpansions :: Maybe MaxExpansions
1295 , multiMatchQueryLenient :: Maybe Lenient } deriving (Eq, Read, Show, Generic, Typeable)
1297{-| 'mkMultiMatchQuery' is a convenience function that defaults the less common parameters,
1298 enabling you to provide only the list of 'FieldName's and 'QueryString' to
1299 make a 'MultiMatchQuery'.
1302mkMultiMatchQuery :: [FieldName] -> QueryString -> MultiMatchQuery
1303mkMultiMatchQuery matchFields query =
1304 MultiMatchQuery matchFields query
1305 Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1307data MultiMatchQueryType =
1308 MultiMatchBestFields
1309 | MultiMatchMostFields
1310 | MultiMatchCrossFields
1312 | MultiMatchPhrasePrefix deriving (Eq, Read, Show, Generic, Typeable)
1315 BoolQuery { boolQueryMustMatch :: [Query]
1316 , boolQueryMustNotMatch :: [Query]
1317 , boolQueryShouldMatch :: [Query]
1318 , boolQueryMinimumShouldMatch :: Maybe MinimumMatch
1319 , boolQueryBoost :: Maybe Boost
1320 , boolQueryDisableCoord :: Maybe DisableCoord
1321 } deriving (Eq, Read, Show, Generic, Typeable)
1323mkBoolQuery :: [Query] -> [Query] -> [Query] -> BoolQuery
1324mkBoolQuery must mustNot should =
1325 BoolQuery must mustNot should Nothing Nothing Nothing
1328 BoostingQuery { positiveQuery :: Query
1329 , negativeQuery :: Query
1330 , negativeBoost :: Boost } deriving (Eq, Read, Show, Generic, Typeable)
1332data CommonTermsQuery =
1333 CommonTermsQuery { commonField :: FieldName
1334 , commonQuery :: QueryString
1335 , commonCutoffFrequency :: CutoffFrequency
1336 , commonLowFreqOperator :: BooleanOperator
1337 , commonHighFreqOperator :: BooleanOperator
1338 , commonMinimumShouldMatch :: Maybe CommonMinimumMatch
1339 , commonBoost :: Maybe Boost
1340 , commonAnalyzer :: Maybe Analyzer
1341 , commonDisableCoord :: Maybe DisableCoord
1342 } deriving (Eq, Read, Show, Generic, Typeable)
1344data CommonMinimumMatch =
1345 CommonMinimumMatchHighLow MinimumMatchHighLow
1346 | CommonMinimumMatch MinimumMatch
1347 deriving (Eq, Read, Show, Generic, Typeable)
1349data MinimumMatchHighLow =
1350 MinimumMatchHighLow { lowFreq :: MinimumMatch
1351 , highFreq :: MinimumMatch } deriving (Eq, Read, Show, Generic, Typeable)
1353data Filter = AndFilter [Filter] Cache
1354 | OrFilter [Filter] Cache
1355 | NotFilter Filter Cache
1357 | BoolFilter BoolMatch
1358 | ExistsFilter FieldName -- always cached
1359 | GeoBoundingBoxFilter GeoBoundingBoxConstraint
1360 | GeoDistanceFilter GeoPoint Distance DistanceType OptimizeBbox Cache
1361 | GeoDistanceRangeFilter GeoPoint DistanceRange
1362 | GeoPolygonFilter FieldName [LatLon]
1363 | IdsFilter MappingName [DocId]
1365 | MissingFilter FieldName Existence NullValue
1366 | PrefixFilter FieldName PrefixValue Cache
1367 | QueryFilter Query Cache
1368 | RangeFilter FieldName RangeValue RangeExecution Cache
1369 | RegexpFilter FieldName Regexp RegexpFlags CacheName Cache CacheKey
1370 | TermFilter Term Cache
1371 deriving (Eq, Read, Show, Generic, Typeable)
1373data ZeroTermsQuery = ZeroTermsNone
1374 | ZeroTermsAll deriving (Eq, Read, Show, Generic, Typeable)
1376data RangeExecution = RangeExecutionIndex
1377 | RangeExecutionFielddata deriving (Eq, Read, Show, Generic, Typeable)
1379newtype Regexp = Regexp Text deriving (Eq, Read, Show, Generic, Typeable, FromJSON)
1381data RegexpFlags = AllRegexpFlags
1383 | SomeRegexpFlags (NonEmpty RegexpFlag) deriving (Eq, Read, Show, Generic, Typeable)
1385data RegexpFlag = AnyString
1390 | Interval deriving (Eq, Read, Show, Generic, Typeable)
1392newtype LessThan = LessThan Double deriving (Eq, Read, Show, Generic, Typeable)
1393newtype LessThanEq = LessThanEq Double deriving (Eq, Read, Show, Generic, Typeable)
1394newtype GreaterThan = GreaterThan Double deriving (Eq, Read, Show, Generic, Typeable)
1395newtype GreaterThanEq = GreaterThanEq Double deriving (Eq, Read, Show, Generic, Typeable)
1397newtype LessThanD = LessThanD UTCTime deriving (Eq, Read, Show, Generic, Typeable)
1398newtype LessThanEqD = LessThanEqD UTCTime deriving (Eq, Read, Show, Generic, Typeable)
1399newtype GreaterThanD = GreaterThanD UTCTime deriving (Eq, Read, Show, Generic, Typeable)
1400newtype GreaterThanEqD = GreaterThanEqD UTCTime deriving (Eq, Read, Show, Generic, Typeable)
1402data RangeValue = RangeDateLte LessThanEqD
1403 | RangeDateLt LessThanD
1404 | RangeDateGte GreaterThanEqD
1405 | RangeDateGt GreaterThanD
1406 | RangeDateGtLt GreaterThanD LessThanD
1407 | RangeDateGteLte GreaterThanEqD LessThanEqD
1408 | RangeDateGteLt GreaterThanEqD LessThanD
1409 | RangeDateGtLte GreaterThanD LessThanEqD
1410 | RangeDoubleLte LessThanEq
1411 | RangeDoubleLt LessThan
1412 | RangeDoubleGte GreaterThanEq
1413 | RangeDoubleGt GreaterThan
1414 | RangeDoubleGtLt GreaterThan LessThan
1415 | RangeDoubleGteLte GreaterThanEq LessThanEq
1416 | RangeDoubleGteLt GreaterThanEq LessThan
1417 | RangeDoubleGtLte GreaterThan LessThanEq
1418 deriving (Eq, Read, Show, Generic, Typeable)
1420rangeValueToPair :: RangeValue -> [Pair]
1421rangeValueToPair rv = case rv of
1422 RangeDateLte (LessThanEqD t) -> ["lte" .= t]
1423 RangeDateGte (GreaterThanEqD t) -> ["gte" .= t]
1424 RangeDateLt (LessThanD t) -> ["lt" .= t]
1425 RangeDateGt (GreaterThanD t) -> ["gt" .= t]
1426 RangeDateGteLte (GreaterThanEqD l) (LessThanEqD g) -> ["gte" .= l, "lte" .= g]
1427 RangeDateGtLte (GreaterThanD l) (LessThanEqD g) -> ["gt" .= l, "lte" .= g]
1428 RangeDateGteLt (GreaterThanEqD l) (LessThanD g) -> ["gte" .= l, "lt" .= g]
1429 RangeDateGtLt (GreaterThanD l) (LessThanD g) -> ["gt" .= l, "lt" .= g]
1430 RangeDoubleLte (LessThanEq t) -> ["lte" .= t]
1431 RangeDoubleGte (GreaterThanEq t) -> ["gte" .= t]
1432 RangeDoubleLt (LessThan t) -> ["lt" .= t]
1433 RangeDoubleGt (GreaterThan t) -> ["gt" .= t]
1434 RangeDoubleGteLte (GreaterThanEq l) (LessThanEq g) -> ["gte" .= l, "lte" .= g]
1435 RangeDoubleGtLte (GreaterThan l) (LessThanEq g) -> ["gt" .= l, "lte" .= g]
1436 RangeDoubleGteLt (GreaterThanEq l) (LessThan g) -> ["gte" .= l, "lt" .= g]
1437 RangeDoubleGtLt (GreaterThan l) (LessThan g) -> ["gt" .= l, "lt" .= g]
1439data Term = Term { termField :: Text
1440 , termValue :: Text } deriving (Eq, Read, Show, Generic, Typeable)
1442data BoolMatch = MustMatch Term Cache
1443 | MustNotMatch Term Cache
1444 | ShouldMatch [Term] Cache deriving (Eq, Read, Show, Generic, Typeable)
1446-- "memory" or "indexed"
1447data GeoFilterType = GeoFilterMemory
1448 | GeoFilterIndexed deriving (Eq, Read, Show, Generic, Typeable)
1450data LatLon = LatLon { lat :: Double
1451 , lon :: Double } deriving (Eq, Read, Show, Generic, Typeable)
1453data GeoBoundingBox =
1454 GeoBoundingBox { topLeft :: LatLon
1455 , bottomRight :: LatLon } deriving (Eq, Read, Show, Generic, Typeable)
1457data GeoBoundingBoxConstraint =
1458 GeoBoundingBoxConstraint { geoBBField :: FieldName
1459 , constraintBox :: GeoBoundingBox
1460 , bbConstraintcache :: Cache
1461 , geoType :: GeoFilterType
1462 } deriving (Eq, Read, Show, Generic, Typeable)
1465 GeoPoint { geoField :: FieldName
1466 , latLon :: LatLon} deriving (Eq, Read, Show, Generic, Typeable)
1468data DistanceUnit = Miles
1476 | NauticalMiles deriving (Eq, Read, Show, Generic, Typeable)
1478data DistanceType = Arc
1479 | SloppyArc -- doesn't exist <1.0
1480 | Plane deriving (Eq, Read, Show, Generic, Typeable)
1482data OptimizeBbox = OptimizeGeoFilterType GeoFilterType
1483 | NoOptimizeBbox deriving (Eq, Read, Show, Generic, Typeable)
1486 Distance { coefficient :: Double
1487 , unit :: DistanceUnit } deriving (Eq, Read, Show, Generic, Typeable)
1490 DistanceRange { distanceFrom :: Distance
1491 , distanceTo :: Distance } deriving (Eq, Read, Show, Generic, Typeable)
1493data SearchResult a =
1494 SearchResult { took :: Int
1496 , shards :: ShardResult
1497 , searchHits :: SearchHits a
1498 , aggregations :: Maybe AggregationResults
1499 , scrollId :: Maybe ScrollId } deriving (Eq, Read, Show, Generic, Typeable)
1501newtype ScrollId = ScrollId Text deriving (Eq, Read, Show, Generic, Ord, ToJSON, FromJSON)
1503type Score = Maybe Double
1506 SearchHits { hitsTotal :: Int
1508 , hits :: [Hit a] } deriving (Eq, Read, Show, Generic, Typeable)
1511instance Monoid (SearchHits a) where
1512 mempty = SearchHits 0 Nothing mempty
1513 mappend (SearchHits ta ma ha) (SearchHits tb mb hb) =
1514 SearchHits (ta + tb) (max ma mb) (ha <> hb)
1518 Hit { hitIndex :: IndexName
1519 , hitType :: MappingName
1522 , hitSource :: Maybe a
1523 , hitHighlight :: Maybe HitHighlight } deriving (Eq, Read, Show, Generic, Typeable)
1526 ShardResult { shardTotal :: Int
1527 , shardsSuccessful :: Int
1528 , shardsFailed :: Int } deriving (Eq, Read, Show, Generic, Typeable)
1530type HitHighlight = M.Map Text [Text]
1532showText :: Show a => a -> Text
1533showText = T.pack . show
1535readMay :: Read a => String -> Maybe a
1536readMay s = case reads s of
1540parseReadText :: Read a => Text -> Parser a
1541parseReadText = maybe mzero return . readMay . T.unpack
1543type Aggregations = M.Map Text Aggregation
1545emptyAggregations :: Aggregations
1546emptyAggregations = M.empty
1548mkAggregations :: Text -> Aggregation -> Aggregations
1549mkAggregations name aggregation = M.insert name aggregation emptyAggregations
1551data TermOrder = TermOrder{ termSortField :: Text
1552 , termSortOrder :: SortOrder } deriving (Eq, Read, Show, Generic, Typeable)
1554data TermInclusion = TermInclusion Text
1555 | TermPattern Text Text deriving (Eq, Read, Show, Generic, Typeable)
1557data CollectionMode = BreadthFirst
1558 | DepthFirst deriving (Eq, Read, Show, Generic, Typeable)
1560data ExecutionHint = Ordinals
1562 | GlobalOrdinalsHash
1563 | GlobalOrdinalsLowCardinality
1564 | Map deriving (Eq, Read, Show, Generic, Typeable)
1566data TimeInterval = Weeks
1570 | Seconds deriving Eq
1580 | FractionalInterval Float TimeInterval deriving (Eq, Read, Show, Generic, Typeable)
1582data Aggregation = TermsAgg TermsAggregation
1583 | DateHistogramAgg DateHistogramAggregation
1584 | ValueCountAgg ValueCountAggregation
1585 | FilterAgg FilterAggregation
1586 | DateRangeAgg DateRangeAggregation
1587 | MissingAgg MissingAggregation deriving (Eq, Read, Show, Generic, Typeable)
1589data MissingAggregation = MissingAggregation
1591 } deriving (Eq, Read, Show, Generic, Typeable)
1593data TermsAggregation = TermsAggregation { term :: Either Text Text
1594 , termInclude :: Maybe TermInclusion
1595 , termExclude :: Maybe TermInclusion
1596 , termOrder :: Maybe TermOrder
1597 , termMinDocCount :: Maybe Int
1598 , termSize :: Maybe Int
1599 , termShardSize :: Maybe Int
1600 , termCollectMode :: Maybe CollectionMode
1601 , termExecutionHint :: Maybe ExecutionHint
1602 , termAggs :: Maybe Aggregations
1603 } deriving (Eq, Read, Show, Generic, Typeable)
1605data DateHistogramAggregation = DateHistogramAggregation { dateField :: FieldName
1606 , dateInterval :: Interval
1607 , dateFormat :: Maybe Text
1608 -- pre and post deprecated in 1.5
1609 , datePreZone :: Maybe Text
1610 , datePostZone :: Maybe Text
1611 , datePreOffset :: Maybe Text
1612 , datePostOffset :: Maybe Text
1613 , dateAggs :: Maybe Aggregations
1614 } deriving (Eq, Read, Show, Generic, Typeable)
1617data DateRangeAggregation = DateRangeAggregation { draField :: FieldName
1618 , draFormat :: Maybe Text
1619 , draRanges :: NonEmpty DateRangeAggRange
1620 } deriving (Eq, Read, Show, Generic, Typeable)
1622data DateRangeAggRange = DateRangeFrom DateMathExpr
1623 | DateRangeTo DateMathExpr
1624 | DateRangeFromAndTo DateMathExpr DateMathExpr deriving (Eq, Read, Show, Generic, Typeable)
1626-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math> for more information.
1627data DateMathExpr = DateMathExpr DateMathAnchor [DateMathModifier] deriving (Eq, Read, Show, Generic, Typeable)
1630-- | Starting point for a date range. This along with the 'DateMathModifiers' gets you the date ES will start from.
1631data DateMathAnchor = DMNow
1632 | DMDate Day deriving (Eq, Read, Show, Generic, Typeable)
1634data DateMathModifier = AddTime Int DateMathUnit
1635 | SubtractTime Int DateMathUnit
1636 | RoundDownTo DateMathUnit deriving (Eq, Read, Show, Generic, Typeable)
1638data DateMathUnit = DMYear
1644 | DMSecond deriving (Eq, Read, Show, Generic, Typeable)
1646-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html> for more information.
1647data ValueCountAggregation = FieldValueCount FieldName
1648 | ScriptValueCount Script deriving (Eq, Read, Show, Generic, Typeable)
1650-- | 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.
1651data FilterAggregation = FilterAggregation { faFilter :: Filter
1652 , faAggs :: Maybe Aggregations} deriving (Eq, Read, Show, Generic, Typeable)
1654mkTermsAggregation :: Text -> TermsAggregation
1655mkTermsAggregation t = TermsAggregation (Left t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1657mkTermsScriptAggregation :: Text -> TermsAggregation
1658mkTermsScriptAggregation t = TermsAggregation (Right t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1660mkDateHistogram :: FieldName -> Interval -> DateHistogramAggregation
1661mkDateHistogram t i = DateHistogramAggregation t i Nothing Nothing Nothing Nothing Nothing Nothing
1663instance ToJSON Version where
1664 toJSON Version {..} = object ["number" .= number
1665 ,"build_hash" .= build_hash
1666 ,"build_timestamp" .= build_timestamp
1667 ,"build_snapshot" .= build_snapshot
1668 ,"lucene_version" .= lucene_version]
1670instance FromJSON Version where
1671 parseJSON = withObject "Version" parse
1672 where parse o = Version
1674 <*> o .: "build_hash"
1675 <*> o .: "build_timestamp"
1676 <*> o .: "build_snapshot"
1677 <*> o .: "lucene_version"
1679instance ToJSON TermOrder where
1680 toJSON (TermOrder termSortField termSortOrder) = object [termSortField .= termSortOrder]
1682instance ToJSON TermInclusion where
1683 toJSON (TermInclusion x) = toJSON x
1684 toJSON (TermPattern pattern flags) = omitNulls [ "pattern" .= pattern,
1687instance ToJSON CollectionMode where
1688 toJSON BreadthFirst = "breadth_first"
1689 toJSON DepthFirst = "depth_first"
1691instance ToJSON ExecutionHint where
1692 toJSON Ordinals = "ordinals"
1693 toJSON GlobalOrdinals = "global_ordinals"
1694 toJSON GlobalOrdinalsHash = "global_ordinals_hash"
1695 toJSON GlobalOrdinalsLowCardinality = "global_ordinals_low_cardinality"
1698instance ToJSON Interval where
1699 toJSON Year = "year"
1700 toJSON Quarter = "quarter"
1701 toJSON Month = "month"
1702 toJSON Week = "week"
1704 toJSON Hour = "hour"
1705 toJSON Minute = "minute"
1706 toJSON Second = "second"
1707 toJSON (FractionalInterval fraction interval) = toJSON $ show fraction ++ show interval
1709instance Show TimeInterval where
1716instance Read TimeInterval where
1717 readPrec = f =<< TR.get
1719 f 'w' = return Weeks
1721 f 'h' = return Hours
1722 f 'm' = return Minutes
1723 f 's' = return Seconds
1724 f _ = fail "TimeInterval expected one of w, d, h, m, s"
1726instance ToJSON Aggregation where
1727 toJSON (TermsAgg (TermsAggregation term include exclude order minDocCount size shardSize collectMode executionHint termAggs)) =
1728 omitNulls ["terms" .= omitNulls [ toJSON' term,
1729 "include" .= include,
1730 "exclude" .= exclude,
1732 "min_doc_count" .= minDocCount,
1734 "shard_size" .= shardSize,
1735 "collect_mode" .= collectMode,
1736 "execution_hint" .= executionHint
1738 "aggs" .= termAggs ]
1740 toJSON' x = case x of { Left y -> "field" .= y; Right y -> "script" .= y }
1742 toJSON (DateHistogramAgg (DateHistogramAggregation field interval format preZone postZone preOffset postOffset dateHistoAggs)) =
1743 omitNulls ["date_histogram" .= omitNulls [ "field" .= field,
1744 "interval" .= interval,
1746 "pre_zone" .= preZone,
1747 "post_zone" .= postZone,
1748 "pre_offset" .= preOffset,
1749 "post_offset" .= postOffset
1751 "aggs" .= dateHistoAggs ]
1752 toJSON (ValueCountAgg a) = object ["value_count" .= v]
1754 (FieldValueCount (FieldName n)) -> object ["field" .= n]
1755 (ScriptValueCount (Script s)) -> object ["script" .= s]
1756 toJSON (FilterAgg (FilterAggregation filt ags)) =
1757 omitNulls [ "filter" .= filt
1759 toJSON (DateRangeAgg a) = object [ "date_range" .= a
1761 toJSON (MissingAgg (MissingAggregation{..})) =
1762 object ["missing" .= object ["field" .= maField]]
1764instance ToJSON DateRangeAggregation where
1765 toJSON DateRangeAggregation {..} =
1766 omitNulls [ "field" .= draField
1767 , "format" .= draFormat
1768 , "ranges" .= toList draRanges
1771instance ToJSON DateRangeAggRange where
1772 toJSON (DateRangeFrom e) = object [ "from" .= e ]
1773 toJSON (DateRangeTo e) = object [ "to" .= e ]
1774 toJSON (DateRangeFromAndTo f t) = object [ "from" .= f, "to" .= t ]
1776instance ToJSON DateMathExpr where
1777 toJSON (DateMathExpr a mods) = String (fmtA a <> mconcat (fmtMod <$> mods))
1778 where fmtA DMNow = "now"
1779 fmtA (DMDate date) = case toGregorian date of
1780 (y,m,d) -> showText y <> "-" <>
1781 showText m <> "-" <>
1783 fmtMod (AddTime n u) = "+" <> showText n <> fmtU u
1784 fmtMod (SubtractTime n u) = "-" <> showText n <> fmtU u
1785 fmtMod (RoundDownTo u) = "/" <> fmtU u
1795type AggregationResults = M.Map Text Value
1797class BucketAggregation a where
1798 key :: a -> BucketValue
1799 docCount :: a -> Int
1800 aggs :: a -> Maybe AggregationResults
1803data Bucket a = Bucket { buckets :: [a]} deriving (Read, Show)
1805data BucketValue = TextValue Text
1806 | ScientificValue Scientific
1807 | BoolValue Bool deriving (Read, Show)
1809data MissingResult = MissingResult { missingDocCount :: Int } deriving (Show)
1811data TermsResult = TermsResult { termKey :: BucketValue
1812 , termsDocCount :: Int
1813 , termsAggs :: Maybe AggregationResults } deriving (Read, Show)
1815data DateHistogramResult = DateHistogramResult { dateKey :: Int
1816 , dateKeyStr :: Maybe Text
1817 , dateDocCount :: Int
1818 , dateHistogramAggs :: Maybe AggregationResults } deriving (Read, Show)
1820data DateRangeResult = DateRangeResult { dateRangeKey :: Text
1821 , dateRangeFrom :: Maybe UTCTime
1822 , dateRangeFromAsString :: Maybe Text
1823 , dateRangeTo :: Maybe UTCTime
1824 , dateRangeToAsString :: Maybe Text
1825 , dateRangeDocCount :: Int
1826 , dateRangeAggs :: Maybe AggregationResults } deriving (Read, Show, Eq, Generic, Typeable)
1828toTerms :: Text -> AggregationResults -> Maybe (Bucket TermsResult)
1829toTerms = toAggResult
1831toDateHistogram :: Text -> AggregationResults -> Maybe (Bucket DateHistogramResult)
1832toDateHistogram = toAggResult
1834toMissing :: Text -> AggregationResults -> Maybe MissingResult
1835toMissing = toAggResult
1837toAggResult :: (FromJSON a) => Text -> AggregationResults -> Maybe a
1838toAggResult t a = M.lookup t a >>= deserialize
1839 where deserialize = parseMaybe parseJSON
1841instance BucketAggregation TermsResult where
1843 docCount = termsDocCount
1846instance BucketAggregation DateHistogramResult where
1847 key = TextValue . showText . dateKey
1848 docCount = dateDocCount
1849 aggs = dateHistogramAggs
1851instance BucketAggregation DateRangeResult where
1852 key = TextValue . dateRangeKey
1853 docCount = dateRangeDocCount
1854 aggs = dateRangeAggs
1856instance (FromJSON a, BucketAggregation a) => FromJSON (Bucket a) where
1857 parseJSON (Object v) = Bucket <$>
1859 parseJSON _ = mempty
1861instance FromJSON BucketValue where
1862 parseJSON (String t) = return $ TextValue t
1863 parseJSON (Number s) = return $ ScientificValue s
1864 parseJSON (Bool b) = return $ BoolValue b
1865 parseJSON _ = mempty
1867instance FromJSON MissingResult where
1868 parseJSON = withObject "MissingResult" parse
1869 where parse v = MissingResult <$> v .: "doc_count"
1871instance FromJSON TermsResult where
1872 parseJSON (Object v) = TermsResult <$>
1874 v .: "doc_count" <*>
1875 v .:? "aggregations"
1876 parseJSON _ = mempty
1878instance FromJSON DateHistogramResult where
1879 parseJSON (Object v) = DateHistogramResult <$>
1881 v .:? "key_as_string" <*>
1882 v .: "doc_count" <*>
1883 v .:? "aggregations"
1884 parseJSON _ = mempty
1886instance FromJSON DateRangeResult where
1887 parseJSON = withObject "DateRangeResult" parse
1888 where parse v = DateRangeResult <$>
1890 (fmap posixMS <$> v .:? "from") <*>
1891 v .:? "from_as_string" <*>
1892 (fmap posixMS <$> v .:? "to") <*>
1893 v .:? "to_as_string" <*>
1894 v .: "doc_count" <*>
1895 v .:? "aggregations"
1897instance FromJSON POSIXMS where
1898 parseJSON = withScientific "POSIXMS" (return . parse)
1899 where parse n = let n' = truncate n :: Integer
1900 in POSIXMS (posixSecondsToUTCTime (fromInteger (n' `div` 1000)))
1902instance Monoid Filter where
1903 mempty = IdentityFilter
1904 mappend a b = AndFilter [a, b] defaultCache
1906instance Seminearring Filter where
1907 a <||> b = OrFilter [a, b] defaultCache
1909instance ToJSON Filter where
1910 toJSON (AndFilter filters cache) =
1912 object [ "filters" .= fmap toJSON filters
1913 , "_cache" .= cache]]
1915 toJSON (OrFilter filters cache) =
1917 object [ "filters" .= fmap toJSON filters
1918 , "_cache" .= cache]]
1920 toJSON (NotFilter notFilter cache) =
1922 object ["filter" .= notFilter
1923 , "_cache" .= cache]]
1925 toJSON (IdentityFilter) =
1926 object ["match_all" .= object []]
1928 toJSON (TermFilter (Term termFilterField termFilterValue) cache) =
1929 object ["term" .= object base]
1930 where base = [termFilterField .= termFilterValue,
1933 toJSON (ExistsFilter (FieldName fieldName)) =
1934 object ["exists" .= object
1935 ["field" .= fieldName]]
1937 toJSON (BoolFilter boolMatch) =
1938 object ["bool" .= boolMatch]
1940 toJSON (GeoBoundingBoxFilter bbConstraint) =
1941 object ["geo_bounding_box" .= bbConstraint]
1943 toJSON (GeoDistanceFilter (GeoPoint (FieldName distanceGeoField) geoDistLatLon)
1944 distance distanceType optimizeBbox cache) =
1945 object ["geo_distance" .=
1946 object ["distance" .= distance
1947 , "distance_type" .= distanceType
1948 , "optimize_bbox" .= optimizeBbox
1949 , distanceGeoField .= geoDistLatLon
1950 , "_cache" .= cache]]
1952 toJSON (GeoDistanceRangeFilter (GeoPoint (FieldName gddrField) drLatLon)
1953 (DistanceRange geoDistRangeDistFrom drDistanceTo)) =
1954 object ["geo_distance_range" .=
1955 object ["from" .= geoDistRangeDistFrom
1956 , "to" .= drDistanceTo
1957 , gddrField .= drLatLon]]
1959 toJSON (GeoPolygonFilter (FieldName geoPolygonFilterField) latLons) =
1960 object ["geo_polygon" .=
1961 object [geoPolygonFilterField .=
1962 object ["points" .= fmap toJSON latLons]]]
1964 toJSON (IdsFilter (MappingName mappingName) values) =
1966 object ["type" .= mappingName
1967 , "values" .= fmap unpackId values]]
1969 toJSON (LimitFilter limit) =
1970 object ["limit" .= object ["value" .= limit]]
1972 toJSON (MissingFilter (FieldName fieldName) (Existence existence) (NullValue nullValue)) =
1973 object ["missing" .=
1974 object ["field" .= fieldName
1975 , "existence" .= existence
1976 , "null_value" .= nullValue]]
1978 toJSON (PrefixFilter (FieldName fieldName) fieldValue cache) =
1980 object [fieldName .= fieldValue
1981 , "_cache" .= cache]]
1983 toJSON (QueryFilter query False) =
1984 object ["query" .= toJSON query ]
1985 toJSON (QueryFilter query True) =
1987 object [ "query" .= toJSON query
1988 , "_cache" .= True ]]
1990 toJSON (RangeFilter (FieldName fieldName) rangeValue rangeExecution cache) =
1992 object [ fieldName .= object (rangeValueToPair rangeValue)
1993 , "execution" .= rangeExecution
1994 , "_cache" .= cache]]
1996 toJSON (RegexpFilter (FieldName fieldName)
1997 (Regexp regexText) flags (CacheName cacheName) cache (CacheKey cacheKey)) =
1999 object [fieldName .=
2000 object ["value" .= regexText
2002 , "_name" .= cacheName
2004 , "_cache_key" .= cacheKey]]
2006instance FromJSON Filter where
2007 parseJSON = withObject "Filter" parse
2008 where parse o = andFilter `taggedWith` "and"
2009 <|> orFilter `taggedWith` "or"
2010 <|> notFilter `taggedWith` "not"
2011 <|> identityFilter `taggedWith` "match_all"
2012 <|> boolFilter `taggedWith` "bool"
2013 <|> existsFilter `taggedWith` "exists"
2014 <|> geoBoundingBoxFilter `taggedWith` "geo_bounding_box"
2015 <|> geoDistanceFilter `taggedWith` "geo_distance"
2016 <|> geoDistanceRangeFilter `taggedWith` "geo_distance_range"
2017 <|> geoPolygonFilter `taggedWith` "geo_polygon"
2018 <|> idsFilter `taggedWith` "ids"
2019 <|> limitFilter `taggedWith` "limit"
2020 <|> missingFilter `taggedWith` "missing"
2021 <|> prefixFilter `taggedWith` "prefix"
2022 <|> queryFilter `taggedWith` "query"
2023 <|> fqueryFilter `taggedWith` "fquery"
2024 <|> rangeFilter `taggedWith` "range"
2025 <|> regexpFilter `taggedWith` "regexp"
2026 <|> termFilter `taggedWith` "term"
2027 where taggedWith parser k = parser =<< o .: k
2028 andFilter o = AndFilter <$> o .: "filters"
2029 <*> o .:? "_cache" .!= defaultCache
2030 orFilter o = OrFilter <$> o .: "filters"
2031 <*> o .:? "_cache" .!= defaultCache
2032 notFilter o = NotFilter <$> o .: "filter"
2033 <*> o .: "_cache" .!= defaultCache
2034 identityFilter :: Object -> Parser Filter
2036 | HM.null m = pure IdentityFilter
2037 | otherwise = fail ("Identityfilter expected empty object but got " <> show m)
2038 boolFilter = pure . BoolFilter
2039 existsFilter o = ExistsFilter <$> o .: "field"
2040 geoBoundingBoxFilter = pure . GeoBoundingBoxFilter
2041 geoDistanceFilter o = do
2042 case HM.toList (deleteSeveral ["distance", "distance_type", "optimize_bbox", "_cache"] o) of
2044 gp <- GeoPoint (FieldName fn) <$> parseJSON v
2045 GeoDistanceFilter gp <$> o .: "distance"
2046 <*> o .: "distance_type"
2047 <*> o .: "optimize_bbox"
2048 <*> o .:? "_cache" .!= defaultCache
2049 _ -> fail "Could not find GeoDistanceFilter field name"
2050 geoDistanceRangeFilter o = do
2051 case HM.toList (deleteSeveral ["from", "to"] o) of
2053 gp <- GeoPoint (FieldName fn) <$> parseJSON v
2054 rng <- DistanceRange <$> o .: "from" <*> o .: "to"
2055 return (GeoDistanceRangeFilter gp rng)
2056 _ -> fail "Could not find GeoDistanceRangeFilter field name"
2057 geoPolygonFilter = fieldTagged $ \fn o -> GeoPolygonFilter fn <$> o .: "points"
2058 idsFilter o = IdsFilter <$> o .: "type"
2060 limitFilter o = LimitFilter <$> o .: "value"
2061 missingFilter o = MissingFilter <$> o .: "field"
2062 <*> o .: "existence"
2063 <*> o .: "null_value"
2064 prefixFilter o = case HM.toList (HM.delete "_cache" o) of
2065 [(fn, String v)] -> PrefixFilter (FieldName fn) v <$> o .:? "_cache" .!= defaultCache
2066 _ -> fail "Could not parse PrefixFilter"
2068 queryFilter q = pure (QueryFilter q False)
2069 fqueryFilter o = QueryFilter <$> o .: "query" <*> pure True
2070 rangeFilter o = case HM.toList (deleteSeveral ["execution", "_cache"] o) of
2071 [(fn, v)] -> RangeFilter (FieldName fn)
2073 <*> o .: "execution"
2074 <*> o .:? "_cache" .!= defaultCache
2075 _ -> fail "Could not find field name for RangeFilter"
2076 regexpFilter o = case HM.toList (deleteSeveral ["_name", "_cache", "_cache_key"] o) of
2077 [(fn, Object o')] -> RegexpFilter (FieldName fn)
2081 <*> o .:? "_cache" .!= defaultCache
2082 <*> o .: "_cache_key"
2083 _ -> fail "Could not find field name for RegexpFilter"
2084 termFilter o = case HM.toList (HM.delete "_cache" o) of
2085 [(termField, String termVal)] -> TermFilter (Term termField termVal)
2086 <$> o .:? "_cache" .!= defaultCache
2087 _ -> fail "Could not find term field for TermFilter"
2089fieldTagged :: Monad m => (FieldName -> Object -> m a) -> Object -> m a
2090fieldTagged f o = case HM.toList o of
2091 [(k, Object o')] -> f (FieldName k) o'
2092 _ -> fail "Expected object with 1 field-named key"
2094instance ToJSON GeoPoint where
2095 toJSON (GeoPoint (FieldName geoPointField) geoPointLatLon) =
2096 object [ geoPointField .= geoPointLatLon ]
2099instance ToJSON Query where
2100 toJSON (TermQuery (Term termQueryField termQueryValue) boost) =
2102 object [termQueryField .= object merged]]
2104 base = [ "value" .= termQueryValue ]
2105 boosted = maybe [] (return . ("boost" .=)) boost
2106 merged = mappend base boosted
2108 toJSON (TermsQuery fieldName terms) =
2109 object [ "terms" .= object conjoined ]
2110 where conjoined = [fieldName .= terms]
2112 toJSON (IdsQuery idsQueryMappingName docIds) =
2113 object [ "ids" .= object conjoined ]
2114 where conjoined = [ "type" .= idsQueryMappingName
2115 , "values" .= fmap toJSON docIds ]
2117 toJSON (QueryQueryStringQuery qQueryStringQuery) =
2118 object [ "query_string" .= qQueryStringQuery ]
2120 toJSON (QueryMatchQuery matchQuery) =
2121 object [ "match" .= matchQuery ]
2123 toJSON (QueryMultiMatchQuery multiMatchQuery) =
2124 toJSON multiMatchQuery
2126 toJSON (QueryBoolQuery boolQuery) =
2127 object [ "bool" .= boolQuery ]
2129 toJSON (QueryBoostingQuery boostingQuery) =
2130 object [ "boosting" .= boostingQuery ]
2132 toJSON (QueryCommonTermsQuery commonTermsQuery) =
2133 object [ "common" .= commonTermsQuery ]
2135 toJSON (ConstantScoreFilter csFilter boost) =
2136 object ["constant_score" .= object ["filter" .= csFilter
2137 , "boost" .= boost]]
2139 toJSON (ConstantScoreQuery query boost) =
2140 object ["constant_score" .= object ["query" .= query
2141 , "boost" .= boost]]
2143 toJSON (QueryDisMaxQuery disMaxQuery) =
2144 object [ "dis_max" .= disMaxQuery ]
2146 toJSON (QueryFilteredQuery qFilteredQuery) =
2147 object [ "filtered" .= qFilteredQuery ]
2149 toJSON (QueryFuzzyLikeThisQuery fuzzyQuery) =
2150 object [ "fuzzy_like_this" .= fuzzyQuery ]
2152 toJSON (QueryFuzzyLikeFieldQuery fuzzyFieldQuery) =
2153 object [ "fuzzy_like_this_field" .= fuzzyFieldQuery ]
2155 toJSON (QueryFuzzyQuery fuzzyQuery) =
2156 object [ "fuzzy" .= fuzzyQuery ]
2158 toJSON (QueryHasChildQuery childQuery) =
2159 object [ "has_child" .= childQuery ]
2161 toJSON (QueryHasParentQuery parentQuery) =
2162 object [ "has_parent" .= parentQuery ]
2164 toJSON (QueryIndicesQuery qIndicesQuery) =
2165 object [ "indices" .= qIndicesQuery ]
2167 toJSON (MatchAllQuery boost) =
2168 object [ "match_all" .= omitNulls [ "boost" .= boost ] ]
2170 toJSON (QueryMoreLikeThisQuery query) =
2171 object [ "more_like_this" .= query ]
2173 toJSON (QueryMoreLikeThisFieldQuery query) =
2174 object [ "more_like_this_field" .= query ]
2176 toJSON (QueryNestedQuery query) =
2177 object [ "nested" .= query ]
2179 toJSON (QueryPrefixQuery query) =
2180 object [ "prefix" .= query ]
2182 toJSON (QueryRangeQuery query) =
2183 object [ "range" .= query ]
2185 toJSON (QueryRegexpQuery query) =
2186 object [ "regexp" .= query ]
2188 toJSON (QuerySimpleQueryStringQuery query) =
2189 object [ "simple_query_string" .= query ]
2191instance FromJSON Query where
2192 parseJSON v = withObject "Query" parse v
2193 where parse o = termQuery `taggedWith` "term"
2194 <|> termsQuery `taggedWith` "terms"
2195 <|> idsQuery `taggedWith` "ids"
2196 <|> queryQueryStringQuery `taggedWith` "query_string"
2197 <|> queryMatchQuery `taggedWith` "match"
2198 <|> queryMultiMatchQuery
2199 <|> queryBoolQuery `taggedWith` "bool"
2200 <|> queryBoostingQuery `taggedWith` "boosting"
2201 <|> queryCommonTermsQuery `taggedWith` "common"
2202 <|> constantScoreFilter `taggedWith` "constant_score"
2203 <|> constantScoreQuery `taggedWith` "constant_score"
2204 <|> queryDisMaxQuery `taggedWith` "dis_max"
2205 <|> queryFilteredQuery `taggedWith` "filtered"
2206 <|> queryFuzzyLikeThisQuery `taggedWith` "fuzzy_like_this"
2207 <|> queryFuzzyLikeFieldQuery `taggedWith` "fuzzy_like_this_field"
2208 <|> queryFuzzyQuery `taggedWith` "fuzzy"
2209 <|> queryHasChildQuery `taggedWith` "has_child"
2210 <|> queryHasParentQuery `taggedWith` "has_parent"
2211 <|> queryIndicesQuery `taggedWith` "indices"
2212 <|> matchAllQuery `taggedWith` "match_all"
2213 <|> queryMoreLikeThisQuery `taggedWith` "more_like_this"
2214 <|> queryMoreLikeThisFieldQuery `taggedWith` "more_like_this_field"
2215 <|> queryNestedQuery `taggedWith` "nested"
2216 <|> queryPrefixQuery `taggedWith` "prefix"
2217 <|> queryRangeQuery `taggedWith` "range"
2218 <|> queryRegexpQuery `taggedWith` "regexp"
2219 <|> querySimpleQueryStringQuery `taggedWith` "simple_query_string"
2220 where taggedWith parser k = parser =<< o .: k
2221 termQuery = fieldTagged $ \(FieldName fn) o ->
2222 TermQuery <$> (Term fn <$> o .: "value") <*> o .:? "boost"
2223 termsQuery o = case HM.toList o of
2224 [(fn, vs)] -> do vals <- parseJSON vs
2226 x:xs -> return (TermsQuery fn (x :| xs))
2227 _ -> fail "Expected non empty list of values"
2228 _ -> fail "Expected object with 1 field-named key"
2229 idsQuery o = IdsQuery <$> o .: "type"
2231 queryQueryStringQuery = pure . QueryQueryStringQuery
2232 queryMatchQuery = pure . QueryMatchQuery
2233 queryMultiMatchQuery = QueryMultiMatchQuery <$> parseJSON v
2234 queryBoolQuery = pure . QueryBoolQuery
2235 queryBoostingQuery = pure . QueryBoostingQuery
2236 queryCommonTermsQuery = pure . QueryCommonTermsQuery
2237 constantScoreFilter o = case HM.lookup "filter" o of
2238 Just x -> ConstantScoreFilter <$> parseJSON x
2240 _ -> fail "Does not appear to be a ConstantScoreFilter"
2241 constantScoreQuery o = case HM.lookup "query" o of
2242 Just x -> ConstantScoreQuery <$> parseJSON x
2244 _ -> fail "Does not appear to be a ConstantScoreQuery"
2245 queryDisMaxQuery = pure . QueryDisMaxQuery
2246 queryFilteredQuery = pure . QueryFilteredQuery
2247 queryFuzzyLikeThisQuery = pure . QueryFuzzyLikeThisQuery
2248 queryFuzzyLikeFieldQuery = pure . QueryFuzzyLikeFieldQuery
2249 queryFuzzyQuery = pure . QueryFuzzyQuery
2250 queryHasChildQuery = pure . QueryHasChildQuery
2251 queryHasParentQuery = pure . QueryHasParentQuery
2252 queryIndicesQuery = pure . QueryIndicesQuery
2253 matchAllQuery o = MatchAllQuery <$> o .:? "boost"
2254 queryMoreLikeThisQuery = pure . QueryMoreLikeThisQuery
2255 queryMoreLikeThisFieldQuery = pure . QueryMoreLikeThisFieldQuery
2256 queryNestedQuery = pure . QueryNestedQuery
2257 queryPrefixQuery = pure . QueryPrefixQuery
2258 queryRangeQuery = pure . QueryRangeQuery
2259 queryRegexpQuery = pure . QueryRegexpQuery
2260 querySimpleQueryStringQuery = pure . QuerySimpleQueryStringQuery
2263omitNulls :: [(Text, Value)] -> Value
2264omitNulls = object . filter notNull where
2265 notNull (_, Null) = False
2266 notNull (_, Array a) = (not . V.null) a
2270instance ToJSON SimpleQueryStringQuery where
2271 toJSON SimpleQueryStringQuery {..} =
2272 omitNulls (base ++ maybeAdd)
2273 where base = [ "query" .= simpleQueryStringQuery ]
2274 maybeAdd = [ "fields" .= simpleQueryStringField
2275 , "default_operator" .= simpleQueryStringOperator
2276 , "analyzer" .= simpleQueryStringAnalyzer
2277 , "flags" .= simpleQueryStringFlags
2278 , "lowercase_expanded_terms" .= simpleQueryStringLowercaseExpanded
2279 , "locale" .= simpleQueryStringLocale ]
2281instance FromJSON SimpleQueryStringQuery where
2282 parseJSON = withObject "SimpleQueryStringQuery" parse
2283 where parse o = SimpleQueryStringQuery <$> o .: "query"
2285 <*> o .:? "default_operator"
2286 <*> o .:? "analyzer"
2287 <*> (parseFlags <$> o .:? "flags")
2288 <*> o .:? "lowercase_expanded_terms"
2290 parseFlags (Just (x:xs)) = Just (x :| xs)
2291 parseFlags _ = Nothing
2293instance ToJSON FieldOrFields where
2294 toJSON (FofField fieldName) =
2296 toJSON (FofFields fieldNames) =
2299instance FromJSON FieldOrFields where
2300 parseJSON v = FofField <$> parseJSON v
2301 <|> FofFields <$> (parseNEJSON =<< parseJSON v)
2303instance ToJSON SimpleQueryFlag where
2304 toJSON SimpleQueryAll = "ALL"
2305 toJSON SimpleQueryNone = "NONE"
2306 toJSON SimpleQueryAnd = "AND"
2307 toJSON SimpleQueryOr = "OR"
2308 toJSON SimpleQueryPrefix = "PREFIX"
2309 toJSON SimpleQueryPhrase = "PHRASE"
2310 toJSON SimpleQueryPrecedence = "PRECEDENCE"
2311 toJSON SimpleQueryEscape = "ESCAPE"
2312 toJSON SimpleQueryWhitespace = "WHITESPACE"
2313 toJSON SimpleQueryFuzzy = "FUZZY"
2314 toJSON SimpleQueryNear = "NEAR"
2315 toJSON SimpleQuerySlop = "SLOP"
2317instance FromJSON SimpleQueryFlag where
2318 parseJSON = withText "SimpleQueryFlag" parse
2319 where parse "ALL" = pure SimpleQueryAll
2320 parse "NONE" = pure SimpleQueryNone
2321 parse "AND" = pure SimpleQueryAnd
2322 parse "OR" = pure SimpleQueryOr
2323 parse "PREFIX" = pure SimpleQueryPrefix
2324 parse "PHRASE" = pure SimpleQueryPhrase
2325 parse "PRECEDENCE" = pure SimpleQueryPrecedence
2326 parse "ESCAPE" = pure SimpleQueryEscape
2327 parse "WHITESPACE" = pure SimpleQueryWhitespace
2328 parse "FUZZY" = pure SimpleQueryFuzzy
2329 parse "NEAR" = pure SimpleQueryNear
2330 parse "SLOP" = pure SimpleQuerySlop
2331 parse f = fail ("Unexpected SimpleQueryFlag: " <> show f)
2333instance ToJSON RegexpQuery where
2334 toJSON (RegexpQuery (FieldName rqQueryField)
2335 (Regexp regexpQueryQuery) rqQueryFlags
2337 object [ rqQueryField .= omitNulls base ]
2338 where base = [ "value" .= regexpQueryQuery
2339 , "flags" .= rqQueryFlags
2340 , "boost" .= rqQueryBoost ]
2342instance FromJSON RegexpQuery where
2343 parseJSON = withObject "RegexpQuery" parse
2344 where parse = fieldTagged $ \fn o ->
2350instance ToJSON QueryStringQuery where
2351 toJSON (QueryStringQuery qsQueryString
2352 qsDefaultField qsOperator
2353 qsAnalyzer qsAllowWildcard
2354 qsLowercaseExpanded qsEnablePositionIncrements
2355 qsFuzzyMaxExpansions qsFuzziness
2356 qsFuzzyPrefixLength qsPhraseSlop
2357 qsBoost qsAnalyzeWildcard
2358 qsGeneratePhraseQueries qsMinimumShouldMatch
2359 qsLenient qsLocale) =
2362 base = [ "query" .= qsQueryString
2363 , "default_field" .= qsDefaultField
2364 , "default_operator" .= qsOperator
2365 , "analyzer" .= qsAnalyzer
2366 , "allow_leading_wildcard" .= qsAllowWildcard
2367 , "lowercase_expanded_terms" .= qsLowercaseExpanded
2368 , "enable_position_increments" .= qsEnablePositionIncrements
2369 , "fuzzy_max_expansions" .= qsFuzzyMaxExpansions
2370 , "fuzziness" .= qsFuzziness
2371 , "fuzzy_prefix_length" .= qsFuzzyPrefixLength
2372 , "phrase_slop" .= qsPhraseSlop
2373 , "boost" .= qsBoost
2374 , "analyze_wildcard" .= qsAnalyzeWildcard
2375 , "auto_generate_phrase_queries" .= qsGeneratePhraseQueries
2376 , "minimum_should_match" .= qsMinimumShouldMatch
2377 , "lenient" .= qsLenient
2378 , "locale" .= qsLocale ]
2380instance FromJSON QueryStringQuery where
2381 parseJSON = withObject "QueryStringQuery" parse
2382 where parse o = QueryStringQuery
2384 <*> o .:? "default_field"
2385 <*> o .:? "default_operator"
2386 <*> o .:? "analyzer"
2387 <*> o .:? "allow_leading_wildcard"
2388 <*> o .:? "lowercase_expanded_terms"
2389 <*> o .:? "enable_position_increments"
2390 <*> o .:? "fuzzy_max_expansions"
2391 <*> o .:? "fuzziness"
2392 <*> o .:? "fuzzy_prefix_length"
2393 <*> o .:? "phrase_slop"
2395 <*> o .:? "analyze_wildcard"
2396 <*> o .:? "auto_generate_phrase_queries"
2397 <*> o .:? "minimum_should_match"
2401instance ToJSON RangeQuery where
2402 toJSON (RangeQuery (FieldName fieldName) range boost) =
2403 object [ fieldName .= object conjoined ]
2404 where conjoined = [ "boost" .= boost ] ++ (rangeValueToPair range)
2406instance FromJSON RangeQuery where
2407 parseJSON = withObject "RangeQuery" parse
2408 where parse = fieldTagged $ \fn o ->
2410 <$> parseJSON (Object o)
2413instance FromJSON RangeValue where
2414 parseJSON = withObject "RangeValue" parse
2415 where parse o = parseDate o
2417 parseDate o = do lt <- o .:? "lt"
2421 case (lt, lte, gt, gte) of
2422 (Just a, _, Just b, _) -> return (RangeDateGtLt (GreaterThanD b) (LessThanD a))
2423 (Just a, _, _, Just b)-> return (RangeDateGteLt (GreaterThanEqD b) (LessThanD a))
2424 (_, Just a, Just b, _)-> return (RangeDateGtLte (GreaterThanD b) (LessThanEqD a))
2425 (_, Just a, _, Just b)-> return (RangeDateGteLte (GreaterThanEqD b) (LessThanEqD a))
2426 (_, _, Just a, _)-> return (RangeDateGt (GreaterThanD a))
2427 (Just a, _, _, _)-> return (RangeDateLt (LessThanD a))
2428 (_, _, _, Just a)-> return (RangeDateGte (GreaterThanEqD a))
2429 (_, Just a, _, _)-> return (RangeDateLte (LessThanEqD a))
2430 (Nothing, Nothing, Nothing, Nothing) -> mzero
2431 parseDouble o = do lt <- o .:? "lt"
2435 case (lt, lte, gt, gte) of
2436 (Just a, _, Just b, _) -> return (RangeDoubleGtLt (GreaterThan b) (LessThan a))
2437 (Just a, _, _, Just b)-> return (RangeDoubleGteLt (GreaterThanEq b) (LessThan a))
2438 (_, Just a, Just b, _)-> return (RangeDoubleGtLte (GreaterThan b) (LessThanEq a))
2439 (_, Just a, _, Just b)-> return (RangeDoubleGteLte (GreaterThanEq b) (LessThanEq a))
2440 (_, _, Just a, _)-> return (RangeDoubleGt (GreaterThan a))
2441 (Just a, _, _, _)-> return (RangeDoubleLt (LessThan a))
2442 (_, _, _, Just a)-> return (RangeDoubleGte (GreaterThanEq a))
2443 (_, Just a, _, _)-> return (RangeDoubleLte (LessThanEq a))
2444 (Nothing, Nothing, Nothing, Nothing) -> mzero
2446instance ToJSON PrefixQuery where
2447 toJSON (PrefixQuery (FieldName fieldName) queryValue boost) =
2448 object [ fieldName .= omitNulls base ]
2449 where base = [ "value" .= queryValue
2450 , "boost" .= boost ]
2452instance FromJSON PrefixQuery where
2453 parseJSON = withObject "PrefixQuery" parse
2454 where parse = fieldTagged $ \fn o ->
2459instance ToJSON NestedQuery where
2460 toJSON (NestedQuery nqPath nqScoreType nqQuery) =
2461 object [ "path" .= nqPath
2462 , "score_mode" .= nqScoreType
2463 , "query" .= nqQuery ]
2465instance FromJSON NestedQuery where
2466 parseJSON = withObject "NestedQuery" parse
2467 where parse o = NestedQuery
2469 <*> o .: "score_mode"
2472instance ToJSON MoreLikeThisFieldQuery where
2473 toJSON (MoreLikeThisFieldQuery text (FieldName fieldName)
2474 percent mtf mqt stopwords mindf maxdf
2475 minwl maxwl boostTerms boost analyzer) =
2476 object [ fieldName .= omitNulls base ]
2477 where base = [ "like_text" .= text
2478 , "percent_terms_to_match" .= percent
2479 , "min_term_freq" .= mtf
2480 , "max_query_terms" .= mqt
2481 , "stop_words" .= stopwords
2482 , "min_doc_freq" .= mindf
2483 , "max_doc_freq" .= maxdf
2484 , "min_word_length" .= minwl
2485 , "max_word_length" .= maxwl
2486 , "boost_terms" .= boostTerms
2488 , "analyzer" .= analyzer ]
2490instance FromJSON MoreLikeThisFieldQuery where
2491 parseJSON = withObject "MoreLikeThisFieldQuery" parse
2492 where parse = fieldTagged $ \fn o ->
2493 MoreLikeThisFieldQuery
2494 <$> o .: "like_text"
2496 <*> o .:? "percent_terms_to_match"
2497 <*> o .:? "min_term_freq"
2498 <*> o .:? "max_query_terms"
2499 -- <*> (optionalNE =<< o .:? "stop_words")
2500 <*> o .:? "stop_words"
2501 <*> o .:? "min_doc_freq"
2502 <*> o .:? "max_doc_freq"
2503 <*> o .:? "min_word_length"
2504 <*> o .:? "max_word_length"
2505 <*> o .:? "boost_terms"
2507 <*> o .:? "analyzer"
2508 -- optionalNE = maybe (pure Nothing) (fmap Just . parseNEJSON)
2510instance ToJSON MoreLikeThisQuery where
2511 toJSON (MoreLikeThisQuery text fields percent
2512 mtf mqt stopwords mindf maxdf
2513 minwl maxwl boostTerms boost analyzer) =
2515 where base = [ "like_text" .= text
2516 , "fields" .= fields
2517 , "percent_terms_to_match" .= percent
2518 , "min_term_freq" .= mtf
2519 , "max_query_terms" .= mqt
2520 , "stop_words" .= stopwords
2521 , "min_doc_freq" .= mindf
2522 , "max_doc_freq" .= maxdf
2523 , "min_word_length" .= minwl
2524 , "max_word_length" .= maxwl
2525 , "boost_terms" .= boostTerms
2527 , "analyzer" .= analyzer ]
2529instance FromJSON MoreLikeThisQuery where
2530 parseJSON = withObject "MoreLikeThisQuery" parse
2531 where parse o = MoreLikeThisQuery
2532 <$> o .: "like_text"
2533 -- <*> (optionalNE =<< o .:? "fields")
2535 <*> o .:? "percent_terms_to_match"
2536 <*> o .:? "min_term_freq"
2537 <*> o .:? "max_query_terms"
2538 -- <*> (optionalNE =<< o .:? "stop_words")
2539 <*> o .:? "stop_words"
2540 <*> o .:? "min_doc_freq"
2541 <*> o .:? "max_doc_freq"
2542 <*> o .:? "min_word_length"
2543 <*> o .:? "max_word_length"
2544 <*> o .:? "boost_terms"
2546 <*> o .:? "analyzer"
2547 -- optionalNE = maybe (pure Nothing) (fmap Just . parseNEJSON)
2549instance ToJSON IndicesQuery where
2550 toJSON (IndicesQuery indices query noMatch) =
2551 omitNulls [ "indices" .= indices
2552 , "no_match_query" .= noMatch
2553 , "query" .= query ]
2555instance FromJSON IndicesQuery where
2556 parseJSON = withObject "IndicesQuery" parse
2557 where parse o = IndicesQuery
2558 <$> o .:? "indices" .!= []
2560 <*> o .:? "no_match_query"
2562instance ToJSON HasParentQuery where
2563 toJSON (HasParentQuery queryType query scoreType) =
2564 omitNulls [ "parent_type" .= queryType
2565 , "score_type" .= scoreType
2566 , "query" .= query ]
2568instance FromJSON HasParentQuery where
2569 parseJSON = withObject "HasParentQuery" parse
2570 where parse o = HasParentQuery
2571 <$> o .: "parent_type"
2573 <*> o .:? "score_type"
2575instance ToJSON HasChildQuery where
2576 toJSON (HasChildQuery queryType query scoreType) =
2577 omitNulls [ "query" .= query
2578 , "score_type" .= scoreType
2579 , "type" .= queryType ]
2581instance FromJSON HasChildQuery where
2582 parseJSON = withObject "HasChildQuery" parse
2583 where parse o = HasChildQuery
2586 <*> o .:? "score_type"
2588instance ToJSON FuzzyQuery where
2589 toJSON (FuzzyQuery (FieldName fieldName) queryText
2590 prefixLength maxEx fuzziness boost) =
2591 object [ fieldName .= omitNulls base ]
2592 where base = [ "value" .= queryText
2593 , "fuzziness" .= fuzziness
2594 , "prefix_length" .= prefixLength
2596 , "max_expansions" .= maxEx ]
2598instance FromJSON FuzzyQuery where
2599 parseJSON = withObject "FuzzyQuery" parse
2600 where parse = fieldTagged $ \fn o ->
2603 <*> o .: "prefix_length"
2604 <*> o .: "max_expansions"
2605 <*> o .: "fuzziness"
2608instance ToJSON FuzzyLikeFieldQuery where
2609 toJSON (FuzzyLikeFieldQuery (FieldName fieldName)
2610 fieldText maxTerms ignoreFreq fuzziness prefixLength
2612 object [ fieldName .=
2613 omitNulls [ "like_text" .= fieldText
2614 , "max_query_terms" .= maxTerms
2615 , "ignore_tf" .= ignoreFreq
2616 , "fuzziness" .= fuzziness
2617 , "prefix_length" .= prefixLength
2618 , "analyzer" .= analyzer
2619 , "boost" .= boost ]]
2621instance FromJSON FuzzyLikeFieldQuery where
2622 parseJSON = withObject "FuzzyLikeFieldQuery" parse
2623 where parse = fieldTagged $ \fn o ->
2624 FuzzyLikeFieldQuery fn
2625 <$> o .: "like_text"
2626 <*> o .: "max_query_terms"
2627 <*> o .: "ignore_tf"
2628 <*> o .: "fuzziness"
2629 <*> o .: "prefix_length"
2631 <*> o .:? "analyzer"
2633instance ToJSON FuzzyLikeThisQuery where
2634 toJSON (FuzzyLikeThisQuery fields text maxTerms
2635 ignoreFreq fuzziness prefixLength boost analyzer) =
2637 where base = [ "fields" .= fields
2638 , "like_text" .= text
2639 , "max_query_terms" .= maxTerms
2640 , "ignore_tf" .= ignoreFreq
2641 , "fuzziness" .= fuzziness
2642 , "prefix_length" .= prefixLength
2643 , "analyzer" .= analyzer
2644 , "boost" .= boost ]
2646instance FromJSON FuzzyLikeThisQuery where
2647 parseJSON = withObject "FuzzyLikeThisQuery" parse
2648 where parse o = FuzzyLikeThisQuery
2649 <$> o .:? "fields" .!= []
2650 <*> o .: "like_text"
2651 <*> o .: "max_query_terms"
2652 <*> o .: "ignore_tf"
2653 <*> o .: "fuzziness"
2654 <*> o .: "prefix_length"
2656 <*> o .:? "analyzer"
2658instance ToJSON FilteredQuery where
2659 toJSON (FilteredQuery query fFilter) =
2660 object [ "query" .= query
2661 , "filter" .= fFilter ]
2663instance FromJSON FilteredQuery where
2664 parseJSON = withObject "FilteredQuery" parse
2665 where parse o = FilteredQuery
2669instance ToJSON DisMaxQuery where
2670 toJSON (DisMaxQuery queries tiebreaker boost) =
2672 where base = [ "queries" .= queries
2674 , "tie_breaker" .= tiebreaker ]
2676instance FromJSON DisMaxQuery where
2677 parseJSON = withObject "DisMaxQuery" parse
2678 where parse o = DisMaxQuery
2679 <$> o .:? "queries" .!= []
2680 <*> o .: "tie_breaker"
2683instance ToJSON CommonTermsQuery where
2684 toJSON (CommonTermsQuery (FieldName fieldName)
2685 (QueryString query) cf lfo hfo msm
2686 boost analyzer disableCoord) =
2687 object [fieldName .= omitNulls base ]
2688 where base = [ "query" .= query
2689 , "cutoff_frequency" .= cf
2690 , "low_freq_operator" .= lfo
2691 , "minimum_should_match" .= msm
2693 , "analyzer" .= analyzer
2694 , "disable_coord" .= disableCoord
2695 , "high_freq_operator" .= hfo ]
2697instance FromJSON CommonTermsQuery where
2698 parseJSON = withObject "CommonTermsQuery" parse
2699 where parse = fieldTagged $ \fn o ->
2702 <*> o .: "cutoff_frequency"
2703 <*> o .: "low_freq_operator"
2704 <*> o .: "high_freq_operator"
2705 <*> o .:? "minimum_should_match"
2707 <*> o .:? "analyzer"
2708 <*> o .:? "disable_coord"
2710instance ToJSON CommonMinimumMatch where
2711 toJSON (CommonMinimumMatch mm) = toJSON mm
2712 toJSON (CommonMinimumMatchHighLow (MinimumMatchHighLow lowF highF)) =
2713 object [ "low_freq" .= lowF
2714 , "high_freq" .= highF ]
2716instance FromJSON CommonMinimumMatch where
2717 parseJSON v = parseMinimum v
2718 <|> parseMinimumHighLow v
2719 where parseMinimum = fmap CommonMinimumMatch . parseJSON
2720 parseMinimumHighLow = fmap CommonMinimumMatchHighLow . withObject "CommonMinimumMatchHighLow" (\o ->
2723 <*> o .: "high_freq")
2726instance ToJSON BoostingQuery where
2727 toJSON (BoostingQuery bqPositiveQuery bqNegativeQuery bqNegativeBoost) =
2728 object [ "positive" .= bqPositiveQuery
2729 , "negative" .= bqNegativeQuery
2730 , "negative_boost" .= bqNegativeBoost ]
2732instance FromJSON BoostingQuery where
2733 parseJSON = withObject "BoostingQuery" parse
2734 where parse o = BoostingQuery
2737 <*> o .: "negative_boost"
2739instance ToJSON BoolQuery where
2740 toJSON (BoolQuery mustM notM shouldM bqMin boost disableCoord) =
2742 where base = [ "must" .= mustM
2743 , "must_not" .= notM
2744 , "should" .= shouldM
2745 , "minimum_should_match" .= bqMin
2747 , "disable_coord" .= disableCoord ]
2749instance FromJSON BoolQuery where
2750 parseJSON = withObject "BoolQuery" parse
2751 where parse o = BoolQuery
2752 <$> o .:? "must" .!= []
2753 <*> o .:? "must_not" .!= []
2754 <*> o .:? "should" .!= []
2755 <*> o .:? "minimum_should_match"
2757 <*> o .:? "disable_coord"
2759instance ToJSON MatchQuery where
2760 toJSON (MatchQuery (FieldName fieldName)
2761 (QueryString mqQueryString) booleanOperator
2762 zeroTermsQuery cutoffFrequency matchQueryType
2763 analyzer maxExpansions lenient boost) =
2764 object [ fieldName .= omitNulls base ]
2765 where base = [ "query" .= mqQueryString
2766 , "operator" .= booleanOperator
2767 , "zero_terms_query" .= zeroTermsQuery
2768 , "cutoff_frequency" .= cutoffFrequency
2769 , "type" .= matchQueryType
2770 , "analyzer" .= analyzer
2771 , "max_expansions" .= maxExpansions
2772 , "lenient" .= lenient
2773 , "boost" .= boost ]
2775instance FromJSON MatchQuery where
2776 parseJSON = withObject "MatchQuery" parse
2777 where parse = fieldTagged $ \fn o ->
2781 <*> o .: "zero_terms_query"
2782 <*> o .:? "cutoff_frequency"
2784 <*> o .:? "analyzer"
2785 <*> o .:? "max_expansions"
2789instance ToJSON MultiMatchQuery where
2790 toJSON (MultiMatchQuery fields (QueryString query) boolOp
2791 ztQ tb mmqt cf analyzer maxEx lenient) =
2792 object ["multi_match" .= omitNulls base]
2793 where base = [ "fields" .= fmap toJSON fields
2795 , "operator" .= boolOp
2796 , "zero_terms_query" .= ztQ
2797 , "tiebreaker" .= tb
2799 , "cutoff_frequency" .= cf
2800 , "analyzer" .= analyzer
2801 , "max_expansions" .= maxEx
2802 , "lenient" .= lenient ]
2804instance FromJSON MultiMatchQuery where
2805 parseJSON = withObject "MultiMatchQuery" parse
2806 where parse raw = do o <- raw .: "multi_match"
2808 <$> o .:? "fields" .!= []
2811 <*> o .: "zero_terms_query"
2812 <*> o .:? "tiebreaker"
2814 <*> o .:? "cutoff_frequency"
2815 <*> o .:? "analyzer"
2816 <*> o .:? "max_expansions"
2819instance ToJSON MultiMatchQueryType where
2820 toJSON MultiMatchBestFields = "best_fields"
2821 toJSON MultiMatchMostFields = "most_fields"
2822 toJSON MultiMatchCrossFields = "cross_fields"
2823 toJSON MultiMatchPhrase = "phrase"
2824 toJSON MultiMatchPhrasePrefix = "phrase_prefix"
2826instance FromJSON MultiMatchQueryType where
2827 parseJSON = withText "MultiMatchPhrasePrefix" parse
2828 where parse "best_fields" = pure MultiMatchBestFields
2829 parse "most_fields" = pure MultiMatchMostFields
2830 parse "cross_fields" = pure MultiMatchCrossFields
2831 parse "phrase" = pure MultiMatchPhrase
2832 parse "phrase_prefix" = pure MultiMatchPhrasePrefix
2833 parse t = fail ("Unexpected MultiMatchPhrasePrefix: " <> show t)
2835instance ToJSON BooleanOperator where
2836 toJSON And = String "and"
2837 toJSON Or = String "or"
2839instance FromJSON BooleanOperator where
2840 parseJSON = withText "BooleanOperator" parse
2841 where parse "and" = pure And
2842 parse "or" = pure Or
2843 parse o = fail ("Unexpected BooleanOperator: " <> show o)
2845instance ToJSON ZeroTermsQuery where
2846 toJSON ZeroTermsNone = String "none"
2847 toJSON ZeroTermsAll = String "all"
2849instance FromJSON ZeroTermsQuery where
2850 parseJSON = withText "ZeroTermsQuery" parse
2851 where parse "none" = pure ZeroTermsNone
2852 parse "all" = pure ZeroTermsAll
2853 parse q = fail ("Unexpected ZeroTermsQuery: " <> show q)
2855instance ToJSON MatchQueryType where
2856 toJSON MatchPhrase = "phrase"
2857 toJSON MatchPhrasePrefix = "phrase_prefix"
2859instance FromJSON MatchQueryType where
2860 parseJSON = withText "MatchQueryType" parse
2861 where parse "phrase" = pure MatchPhrase
2862 parse "phrase_prefix" = pure MatchPhrasePrefix
2863 parse t = fail ("Unexpected MatchQueryType: " <> show t)
2865instance FromJSON Status where
2866 parseJSON (Object v) = Status <$>
2875instance ToJSON IndexSettings where
2876 toJSON (IndexSettings s r) = object ["settings" .=
2878 object ["number_of_shards" .= s, "number_of_replicas" .= r]
2882instance FromJSON IndexSettings where
2883 parseJSON = withObject "IndexSettings" parse
2884 where parse o = do s <- o .: "settings"
2886 IndexSettings <$> i .: "number_of_shards"
2887 <*> i .: "number_of_replicas"
2889instance ToJSON UpdatableIndexSetting where
2890 toJSON (NumberOfReplicas x) = oPath ("index" :| ["number_of_replicas"]) x
2891 toJSON (AutoExpandReplicas x) = oPath ("index" :| ["auto_expand_replicas"]) x
2892 toJSON (RefreshInterval x) = oPath ("index" :| ["refresh_interval"]) (NominalDiffTimeJSON x)
2893 toJSON (IndexConcurrency x) = oPath ("index" :| ["concurrency"]) x
2894 toJSON (FailOnMergeFailure x) = oPath ("index" :| ["fail_on_merge_failure"]) x
2895 toJSON (TranslogFlushThresholdOps x) = oPath ("index" :| ["translog", "flush_threshold_ops"]) x
2896 toJSON (TranslogFlushThresholdSize x) = oPath ("index" :| ["translog", "flush_threshold_size"]) x
2897 toJSON (TranslogFlushThresholdPeriod x) = oPath ("index" :| ["translog", "flush_threshold_period"]) (NominalDiffTimeJSON x)
2898 toJSON (TranslogDisableFlush x) = oPath ("index" :| ["translog", "disable_flush"]) x
2899 toJSON (CacheFilterMaxSize x) = oPath ("index" :| ["cache", "filter", "max_size"]) x
2900 toJSON (CacheFilterExpire x) = oPath ("index" :| ["cache", "filter", "expire"]) (NominalDiffTimeJSON <$> x)
2901 toJSON (GatewaySnapshotInterval x) = oPath ("index" :| ["gateway", "snapshot_interval"]) (NominalDiffTimeJSON x)
2902 toJSON (RoutingAllocationInclude fs) = oPath ("index" :| ["routing", "allocation", "include"]) (attrFilterJSON fs)
2903 toJSON (RoutingAllocationExclude fs) = oPath ("index" :| ["routing", "allocation", "exclude"]) (attrFilterJSON fs)
2904 toJSON (RoutingAllocationRequire fs) = oPath ("index" :| ["routing", "allocation", "require"]) (attrFilterJSON fs)
2905 toJSON (RoutingAllocationEnable x) = oPath ("index" :| ["routing", "allocation", "enable"]) x
2906 toJSON (RoutingAllocationShardsPerNode x) = oPath ("index" :| ["routing", "allocation", "total_shards_per_node"]) x
2907 toJSON (RecoveryInitialShards x) = oPath ("index" :| ["recovery", "initial_shards"]) x
2908 toJSON (GCDeletes x) = oPath ("index" :| ["gc_deletes"]) (NominalDiffTimeJSON x)
2909 toJSON (TTLDisablePurge x) = oPath ("index" :| ["ttl", "disable_purge"]) x
2910 toJSON (TranslogFSType x) = oPath ("index" :| ["translog", "fs", "type"]) x
2911 toJSON (IndexCompoundFormat x) = oPath ("index" :| ["compound_format"]) x
2912 toJSON (IndexCompoundOnFlush x) = oPath ("index" :| ["compound_on_flush"]) x
2913 toJSON (WarmerEnabled x) = oPath ("index" :| ["warmer", "enabled"]) x
2914 toJSON (BlocksReadOnly x) = oPath ("blocks" :| ["read_only"]) x
2915 toJSON (BlocksRead x) = oPath ("blocks" :| ["read"]) x
2916 toJSON (BlocksWrite x) = oPath ("blocks" :| ["write"]) x
2917 toJSON (BlocksMetaData x) = oPath ("blocks" :| ["metadata"]) x
2919instance FromJSON UpdatableIndexSetting where
2920 parseJSON = withObject "UpdatableIndexSetting" parse
2921 where parse o = numberOfReplicas `taggedAt` ["index", "number_of_replicas"]
2922 <|> autoExpandReplicas `taggedAt` ["index", "auto_expand_replicas"]
2923 <|> refreshInterval `taggedAt` ["index", "refresh_interval"]
2924 <|> indexConcurrency `taggedAt` ["index", "concurrency"]
2925 <|> failOnMergeFailure `taggedAt` ["index", "fail_on_merge_failure"]
2926 <|> translogFlushThresholdOps `taggedAt` ["index", "translog", "flush_threshold_ops"]
2927 <|> translogFlushThresholdSize `taggedAt` ["index", "translog", "flush_threshold_size"]
2928 <|> translogFlushThresholdPeriod `taggedAt` ["index", "translog", "flush_threshold_period"]
2929 <|> translogDisableFlush `taggedAt` ["index", "translog", "disable_flush"]
2930 <|> cacheFilterMaxSize `taggedAt` ["index", "cache", "filter", "max_size"]
2931 <|> cacheFilterExpire `taggedAt` ["index", "cache", "filter", "expire"]
2932 <|> gatewaySnapshotInterval `taggedAt` ["index", "gateway", "snapshot_interval"]
2933 <|> routingAllocationInclude `taggedAt` ["index", "routing", "allocation", "include"]
2934 <|> routingAllocationExclude `taggedAt` ["index", "routing", "allocation", "exclude"]
2935 <|> routingAllocationRequire `taggedAt` ["index", "routing", "allocation", "require"]
2936 <|> routingAllocationEnable `taggedAt` ["index", "routing", "allocation", "enable"]
2937 <|> routingAllocationShardsPerNode `taggedAt` ["index", "routing", "allocation", "total_shards_per_node"]
2938 <|> recoveryInitialShards `taggedAt` ["index", "recovery", "initial_shards"]
2939 <|> gcDeletes `taggedAt` ["index", "gc_deletes"]
2940 <|> ttlDisablePurge `taggedAt` ["index", "ttl", "disable_purge"]
2941 <|> translogFSType `taggedAt` ["index", "translog", "fs", "type"]
2942 <|> compoundFormat `taggedAt` ["index", "compound_format"]
2943 <|> compoundOnFlush `taggedAt` ["index", "compound_on_flush"]
2944 <|> warmerEnabled `taggedAt` ["index", "warmer", "enabled"]
2945 <|> blocksReadOnly `taggedAt` ["blocks", "read_only"]
2946 <|> blocksRead `taggedAt` ["blocks", "read"]
2947 <|> blocksWrite `taggedAt` ["blocks", "write"]
2948 <|> blocksMetaData `taggedAt` ["blocks", "metadata"]
2949 where taggedAt f ks = taggedAt' f (Object o) ks
2950 taggedAt' f v [] = f =<< (parseJSON v <|> (parseJSON =<< unStringlyTypeJSON v))
2951 taggedAt' f v (k:ks) = withObject "Object" (\o -> do v' <- o .: k
2952 taggedAt' f v' ks) v
2953 numberOfReplicas = pure . NumberOfReplicas
2954 autoExpandReplicas = pure . AutoExpandReplicas
2955 refreshInterval = pure . RefreshInterval . ndtJSON
2956 indexConcurrency = pure . IndexConcurrency
2957 failOnMergeFailure = pure . FailOnMergeFailure
2958 translogFlushThresholdOps = pure . TranslogFlushThresholdOps
2959 translogFlushThresholdSize = pure . TranslogFlushThresholdSize
2960 translogFlushThresholdPeriod = pure . TranslogFlushThresholdPeriod . ndtJSON
2961 translogDisableFlush = pure . TranslogDisableFlush
2962 cacheFilterMaxSize = pure . CacheFilterMaxSize
2963 cacheFilterExpire = pure . CacheFilterExpire . fmap ndtJSON
2964 gatewaySnapshotInterval = pure . GatewaySnapshotInterval . ndtJSON
2965 routingAllocationInclude = fmap RoutingAllocationInclude . parseAttrFilter
2966 routingAllocationExclude = fmap RoutingAllocationExclude . parseAttrFilter
2967 routingAllocationRequire = fmap RoutingAllocationRequire . parseAttrFilter
2968 routingAllocationEnable = pure . RoutingAllocationEnable
2969 routingAllocationShardsPerNode = pure . RoutingAllocationShardsPerNode
2970 recoveryInitialShards = pure . RecoveryInitialShards
2971 gcDeletes = pure . GCDeletes . ndtJSON
2972 ttlDisablePurge = pure . TTLDisablePurge
2973 translogFSType = pure . TranslogFSType
2974 compoundFormat = pure . IndexCompoundFormat
2975 compoundOnFlush = pure . IndexCompoundOnFlush
2976 warmerEnabled = pure . WarmerEnabled
2977 blocksReadOnly = pure . BlocksReadOnly
2978 blocksRead = pure . BlocksRead
2979 blocksWrite = pure . BlocksWrite
2980 blocksMetaData = pure . BlocksMetaData
2982instance FromJSON IndexSettingsSummary where
2983 parseJSON = withObject "IndexSettingsSummary" parse
2984 where parse o = case HM.toList o of
2985 [(ixn, v@(Object o'))] -> IndexSettingsSummary (IndexName ixn)
2987 <*> (fmap (filter (not . redundant)) . parseSettings =<< o' .: "settings")
2988 _ -> fail "Expected single-key object with index name"
2989 redundant (NumberOfReplicas _) = True
2992-- | For some reason in the settings API, all leaf values get returned
2993-- as strings. This function attepmts to recover from this for all
2994-- non-recursive JSON types. If nothing can be done or the same value
2995-- would be return, it returns 'mzero'
2996unStringlyTypeJSON :: MonadPlus m => Value -> m Value
2997unStringlyTypeJSON (String "true") = return (Bool True)
2998unStringlyTypeJSON (String "false") = return (Bool False)
2999unStringlyTypeJSON (String "null") = return Null
3000unStringlyTypeJSON (String t) = case readMay (T.unpack t) of
3001 Just n -> return (Number n)
3003unStringlyTypeJSON _ = mzero
3006parseSettings :: Object -> Parser [UpdatableIndexSetting]
3009 -- slice the index object into singleton hashmaps and try to parse each
3010 parses <- forM (HM.toList o') $ \(k, v) -> do
3011 -- blocks are now nested into the "index" key, which is not how they're serialized
3012 let atRoot = Object (HM.singleton k v)
3013 let atIndex = Object (HM.singleton "index" atRoot)
3014 optional (parseJSON atRoot <|> parseJSON atIndex)
3015 return (catMaybes parses)
3017oPath :: ToJSON a => NonEmpty Text -> a -> Value
3018oPath (k :| []) v = object [k .= v]
3019oPath (k:| (h:t)) v = object [k .= oPath (h :| t) v]
3021attrFilterJSON :: NonEmpty NodeAttrFilter -> Value
3022attrFilterJSON fs = object [ n .= T.intercalate "," (toList vs)
3023 | NodeAttrFilter (NodeAttrName n) vs <- toList fs]
3025parseAttrFilter :: Value -> Parser (NonEmpty NodeAttrFilter)
3026parseAttrFilter = withObject "NonEmpty NodeAttrFilter" parse
3027 where parse o = case HM.toList o of
3028 [] -> fail "Expected non-empty list of NodeAttrFilters"
3029 x:xs -> DT.mapM (uncurry parse') (x :| xs)
3030 parse' n = withText "Text" $ \t ->
3031 case T.splitOn "," t of
3032 fv:fvs -> return (NodeAttrFilter (NodeAttrName n) (fv :| fvs))
3033 [] -> fail "Expected non-empty list of filter values"
3035instance ToJSON ReplicaBounds where
3036 toJSON (ReplicasBounded a b) = String (showText a <> "-" <> showText b)
3037 toJSON (ReplicasLowerBounded a) = String (showText a <> "-all")
3038 toJSON ReplicasUnbounded = Bool False
3040instance FromJSON ReplicaBounds where
3041 parseJSON v = withText "ReplicaBounds" parseText v
3042 <|> withBool "ReplicaBounds" parseBool v
3043 where parseText t = case T.splitOn "-" t of
3044 [a, "all"] -> ReplicasLowerBounded <$> parseReadText a
3045 [a, b] -> ReplicasBounded <$> parseReadText a
3047 _ -> fail ("Could not parse ReplicaBounds: " <> show t)
3048 parseBool False = pure ReplicasUnbounded
3049 parseBool _ = fail "ReplicasUnbounded cannot be represented with True"
3051instance ToJSON AllocationPolicy where
3052 toJSON AllocAll = String "all"
3053 toJSON AllocPrimaries = String "primaries"
3054 toJSON AllocNewPrimaries = String "new_primaries"
3055 toJSON AllocNone = String "none"
3057instance FromJSON AllocationPolicy where
3058 parseJSON = withText "AllocationPolicy" parse
3059 where parse "all" = pure AllocAll
3060 parse "primaries" = pure AllocPrimaries
3061 parse "new_primaries" = pure AllocNewPrimaries
3062 parse "none" = pure AllocNone
3063 parse t = fail ("Invlaid AllocationPolicy: " <> show t)
3065instance ToJSON InitialShardCount where
3066 toJSON QuorumShards = String "quorum"
3067 toJSON QuorumMinus1Shards = String "quorum-1"
3068 toJSON FullShards = String "full"
3069 toJSON FullMinus1Shards = String "full-1"
3070 toJSON (ExplicitShards x) = toJSON x
3072instance FromJSON InitialShardCount where
3073 parseJSON v = withText "InitialShardCount" parseText v
3074 <|> ExplicitShards <$> parseJSON v
3075 where parseText "quorum" = pure QuorumShards
3076 parseText "quorum-1" = pure QuorumMinus1Shards
3077 parseText "full" = pure FullShards
3078 parseText "full-1" = pure FullMinus1Shards
3081instance ToJSON FSType where
3082 toJSON FSSimple = "simple"
3083 toJSON FSBuffered = "buffered"
3085instance FromJSON FSType where
3086 parseJSON = withText "FSType" parse
3087 where parse "simple" = pure FSSimple
3088 parse "buffered" = pure FSBuffered
3089 parse t = fail ("Invalid FSType: " <> show t)
3091instance ToJSON CompoundFormat where
3092 toJSON (CompoundFileFormat x) = Bool x
3093 toJSON (MergeSegmentVsTotalIndex x) = toJSON x
3095instance FromJSON CompoundFormat where
3096 parseJSON v = CompoundFileFormat <$> parseJSON v
3097 <|> MergeSegmentVsTotalIndex <$> parseJSON v
3099instance ToJSON NominalDiffTimeJSON where
3100 toJSON (NominalDiffTimeJSON t) = String (showText (round t :: Integer) <> "s")
3102instance FromJSON NominalDiffTimeJSON where
3103 parseJSON = withText "NominalDiffTime" parse
3104 where parse t = case T.takeEnd 1 t of
3105 "s" -> NominalDiffTimeJSON . fromInteger <$> parseReadText (T.dropEnd 1 t)
3106 _ -> fail "Invalid or missing NominalDiffTime unit (expected s)"
3108instance ToJSON IndexTemplate where
3109 toJSON (IndexTemplate p s m) = merge
3110 (object [ "template" .= p
3111 , "mappings" .= foldl' merge (object []) m
3115 merge (Object o1) (Object o2) = toJSON $ HM.union o1 o2
3117 merge _ _ = undefined
3119instance (FromJSON a) => FromJSON (EsResult a) where
3120 parseJSON jsonVal@(Object v) = do
3121 found <- v .:? "found" .!= False
3123 then parseJSON jsonVal
3125 EsResult <$> v .: "_index" <*>
3131instance (FromJSON a) => FromJSON (EsResultFound a) where
3132 parseJSON (Object v) = EsResultFound <$>
3137instance FromJSON EsError where
3138 parseJSON (Object v) = EsError <$>
3143instance FromJSON IndexAliasesSummary where
3144 parseJSON = withObject "IndexAliasesSummary" parse
3145 where parse o = IndexAliasesSummary . mconcat <$> mapM (uncurry go) (HM.toList o)
3146 go ixn = withObject "index aliases" $ \ia -> do
3147 aliases <- ia .:? "aliases" .!= mempty
3148 forM (HM.toList aliases) $ \(aName, v) -> do
3149 let indexAlias = IndexAlias (IndexName ixn) (IndexAliasName (IndexName aName))
3150 IndexAliasSummary indexAlias <$> parseJSON v
3153instance ToJSON IndexAliasAction where
3154 toJSON (AddAlias ia opts) = object ["add" .= (iaObj <> optsObj)]
3155 where Object iaObj = toJSON ia
3156 Object optsObj = toJSON opts
3157 toJSON (RemoveAlias ia) = object ["remove" .= iaObj]
3158 where Object iaObj = toJSON ia
3160instance ToJSON IndexAlias where
3161 toJSON IndexAlias {..} = object ["index" .= srcIndex
3162 , "alias" .= indexAlias
3165instance ToJSON IndexAliasCreate where
3166 toJSON IndexAliasCreate {..} = Object (filterObj <> routingObj)
3167 where filterObj = maybe mempty (HM.singleton "filter" . toJSON) aliasCreateFilter
3168 Object routingObj = maybe (Object mempty) toJSON aliasCreateRouting
3170instance ToJSON AliasRouting where
3171 toJSON (AllAliasRouting v) = object ["routing" .= v]
3172 toJSON (GranularAliasRouting srch idx) = object (catMaybes prs)
3173 where prs = [("search_routing" .=) <$> srch
3174 ,("index_routing" .=) <$> idx]
3176instance FromJSON AliasRouting where
3177 parseJSON = withObject "AliasRouting" parse
3178 where parse o = parseAll o <|> parseGranular o
3179 parseAll o = AllAliasRouting <$> o .: "routing"
3180 parseGranular o = do
3181 sr <- o .:? "search_routing"
3182 ir <- o .:? "index_routing"
3183 if isNothing sr && isNothing ir
3184 then fail "Both search_routing and index_routing can't be blank"
3185 else return (GranularAliasRouting sr ir)
3187instance FromJSON IndexAliasCreate where
3188 parseJSON v = withObject "IndexAliasCreate" parse v
3189 where parse o = IndexAliasCreate <$> optional (parseJSON v)
3192instance ToJSON SearchAliasRouting where
3193 toJSON (SearchAliasRouting rvs) = toJSON (T.intercalate "," (routingValue <$> toList rvs))
3195instance FromJSON SearchAliasRouting where
3196 parseJSON = withText "SearchAliasRouting" parse
3197 where parse t = SearchAliasRouting <$> parseNEJSON (String <$> T.splitOn "," t)
3199instance ToJSON Search where
3200 toJSON (Search query sFilter sort searchAggs highlight sTrackSortScores sFrom sSize _ sFields sSource) =
3201 omitNulls [ "query" .= query
3202 , "filter" .= sFilter
3204 , "aggregations" .= searchAggs
3205 , "highlight" .= highlight
3208 , "track_scores" .= sTrackSortScores
3209 , "fields" .= sFields
3210 , "_source" .= sSource]
3213instance ToJSON Source where
3214 toJSON NoSource = toJSON False
3215 toJSON (SourcePatterns patterns) = toJSON patterns
3216 toJSON (SourceIncludeExclude incl excl) = object [ "include" .= incl, "exclude" .= excl ]
3218instance ToJSON PatternOrPatterns where
3219 toJSON (PopPattern pattern) = toJSON pattern
3220 toJSON (PopPatterns patterns) = toJSON patterns
3222instance ToJSON Include where
3223 toJSON (Include patterns) = toJSON patterns
3225instance ToJSON Exclude where
3226 toJSON (Exclude patterns) = toJSON patterns
3228instance ToJSON Pattern where
3229 toJSON (Pattern pattern) = toJSON pattern
3232instance ToJSON FieldHighlight where
3233 toJSON (FieldHighlight (FieldName fName) (Just fSettings)) =
3234 object [ fName .= fSettings ]
3235 toJSON (FieldHighlight (FieldName fName) Nothing) =
3236 object [ fName .= emptyObject ]
3238instance ToJSON Highlights where
3239 toJSON (Highlights global fields) =
3240 omitNulls (("fields" .= fields)
3241 : highlightSettingsPairs global)
3243instance ToJSON HighlightSettings where
3244 toJSON hs = omitNulls (highlightSettingsPairs (Just hs))
3246highlightSettingsPairs :: Maybe HighlightSettings -> [Pair]
3247highlightSettingsPairs Nothing = []
3248highlightSettingsPairs (Just (Plain plh)) = plainHighPairs (Just plh)
3249highlightSettingsPairs (Just (Postings ph)) = postHighPairs (Just ph)
3250highlightSettingsPairs (Just (FastVector fvh)) = fastVectorHighPairs (Just fvh)
3253plainHighPairs :: Maybe PlainHighlight -> [Pair]
3254plainHighPairs Nothing = []
3255plainHighPairs (Just (PlainHighlight plCom plNonPost)) =
3256 [ "type" .= String "plain"]
3257 ++ commonHighlightPairs plCom
3258 ++ nonPostingsToPairs plNonPost
3260postHighPairs :: Maybe PostingsHighlight -> [Pair]
3261postHighPairs Nothing = []
3262postHighPairs (Just (PostingsHighlight pCom)) =
3263 ("type" .= String "postings")
3264 : commonHighlightPairs pCom
3266fastVectorHighPairs :: Maybe FastVectorHighlight -> [Pair]
3267fastVectorHighPairs Nothing = []
3268fastVectorHighPairs (Just
3269 (FastVectorHighlight fvCom fvNonPostSettings fvBoundChars
3270 fvBoundMaxScan fvFragOff fvMatchedFields
3272 [ "type" .= String "fvh"
3273 , "boundary_chars" .= fvBoundChars
3274 , "boundary_max_scan" .= fvBoundMaxScan
3275 , "fragment_offset" .= fvFragOff
3276 , "matched_fields" .= fvMatchedFields
3277 , "phraseLimit" .= fvPhraseLim]
3278 ++ commonHighlightPairs fvCom
3279 ++ nonPostingsToPairs fvNonPostSettings
3281deleteSeveral :: (Eq k, Hashable k) => [k] -> HM.HashMap k v -> HM.HashMap k v
3282deleteSeveral ks hm = foldr HM.delete hm ks
3284commonHighlightPairs :: Maybe CommonHighlight -> [Pair]
3285commonHighlightPairs Nothing = []
3286commonHighlightPairs (Just (CommonHighlight chScore chForceSource chTag chEncoder
3287 chNoMatchSize chHighlightQuery
3288 chRequireFieldMatch)) =
3289 [ "order" .= chScore
3290 , "force_source" .= chForceSource
3291 , "encoder" .= chEncoder
3292 , "no_match_size" .= chNoMatchSize
3293 , "highlight_query" .= chHighlightQuery
3294 , "require_fieldMatch" .= chRequireFieldMatch]
3295 ++ highlightTagToPairs chTag
3298nonPostingsToPairs :: Maybe NonPostings -> [Pair]
3299nonPostingsToPairs Nothing = []
3300nonPostingsToPairs (Just (NonPostings npFragSize npNumOfFrags)) =
3301 [ "fragment_size" .= npFragSize
3302 , "number_of_fragments" .= npNumOfFrags]
3304parseNEJSON :: (FromJSON a) => [Value] -> Parser (NonEmpty a)
3305parseNEJSON [] = fail "Expected non-empty list"
3306parseNEJSON (x:xs) = DT.mapM parseJSON (x :| xs)
3309instance ToJSON HighlightEncoder where
3310 toJSON DefaultEncoder = String "default"
3311 toJSON HTMLEncoder = String "html"
3313highlightTagToPairs :: Maybe HighlightTag -> [Pair]
3314highlightTagToPairs (Just (TagSchema _)) = [ "scheme" .= String "default"]
3315highlightTagToPairs (Just (CustomTags (pre, post))) = [ "pre_tags" .= pre
3316 , "post_tags" .= post]
3317highlightTagToPairs Nothing = []
3319instance ToJSON SortSpec where
3320 toJSON (DefaultSortSpec
3321 (DefaultSort (FieldName dsSortFieldName) dsSortOrder dsIgnoreUnmapped
3322 dsSortMode dsMissingSort dsNestedFilter)) =
3323 object [dsSortFieldName .= omitNulls base] where
3324 base = [ "order" .= dsSortOrder
3325 , "ignore_unmapped" .= dsIgnoreUnmapped
3326 , "mode" .= dsSortMode
3327 , "missing" .= dsMissingSort
3328 , "nested_filter" .= dsNestedFilter ]
3330 toJSON (GeoDistanceSortSpec gdsSortOrder (GeoPoint (FieldName field) gdsLatLon) units) =
3331 object [ "unit" .= units
3332 , field .= gdsLatLon
3333 , "order" .= gdsSortOrder ]
3336instance ToJSON SortOrder where
3337 toJSON Ascending = String "asc"
3338 toJSON Descending = String "desc"
3341instance ToJSON SortMode where
3342 toJSON SortMin = String "min"
3343 toJSON SortMax = String "max"
3344 toJSON SortSum = String "sum"
3345 toJSON SortAvg = String "avg"
3348instance ToJSON Missing where
3349 toJSON LastMissing = String "_last"
3350 toJSON FirstMissing = String "_first"
3351 toJSON (CustomMissing txt) = String txt
3354instance ToJSON ScoreType where
3355 toJSON ScoreTypeMax = "max"
3356 toJSON ScoreTypeAvg = "avg"
3357 toJSON ScoreTypeSum = "sum"
3358 toJSON ScoreTypeNone = "none"
3360instance FromJSON ScoreType where
3361 parseJSON = withText "ScoreType" parse
3362 where parse "max" = pure ScoreTypeMax
3363 parse "avg" = pure ScoreTypeAvg
3364 parse "sum" = pure ScoreTypeSum
3365 parse "none" = pure ScoreTypeNone
3366 parse t = fail ("Unexpected ScoreType: " <> show t)
3368instance ToJSON Distance where
3369 toJSON (Distance dCoefficient dUnit) =
3370 String boltedTogether where
3371 coefText = showText dCoefficient
3372 (String unitText) = toJSON dUnit
3373 boltedTogether = mappend coefText unitText
3375instance FromJSON Distance where
3376 parseJSON = withText "Distance" parse
3377 where parse t = Distance <$> parseCoeff nT
3378 <*> parseJSON (String unitT)
3379 where (nT, unitT) = T.span validForNumber t
3380 -- may be a better way to do this
3381 validForNumber '-' = True
3382 validForNumber '.' = True
3383 validForNumber 'e' = True
3384 validForNumber c = isNumber c
3385 parseCoeff "" = fail "Empty string cannot be parsed as number"
3386 parseCoeff s = return (read (T.unpack s))
3388instance ToJSON DistanceUnit where
3389 toJSON Miles = String "mi"
3390 toJSON Yards = String "yd"
3391 toJSON Feet = String "ft"
3392 toJSON Inches = String "in"
3393 toJSON Kilometers = String "km"
3394 toJSON Meters = String "m"
3395 toJSON Centimeters = String "cm"
3396 toJSON Millimeters = String "mm"
3397 toJSON NauticalMiles = String "nmi"
3400instance FromJSON DistanceUnit where
3401 parseJSON = withText "DistanceUnit" parse
3402 where parse "mi" = pure Miles
3403 parse "yd" = pure Yards
3404 parse "ft" = pure Feet
3405 parse "in" = pure Inches
3406 parse "km" = pure Kilometers
3407 parse "m" = pure Meters
3408 parse "cm" = pure Centimeters
3409 parse "mm" = pure Millimeters
3410 parse "nmi" = pure NauticalMiles
3411 parse u = fail ("Unrecognized DistanceUnit: " <> show u)
3413instance ToJSON DistanceType where
3414 toJSON Arc = String "arc"
3415 toJSON SloppyArc = String "sloppy_arc"
3416 toJSON Plane = String "plane"
3418instance FromJSON DistanceType where
3419 parseJSON = withText "DistanceType" parse
3420 where parse "arc" = pure Arc
3421 parse "sloppy_arc" = pure SloppyArc
3422 parse "plane" = pure Plane
3423 parse t = fail ("Unrecognized DistanceType: " <> show t)
3426instance ToJSON OptimizeBbox where
3427 toJSON NoOptimizeBbox = String "none"
3428 toJSON (OptimizeGeoFilterType gft) = toJSON gft
3430instance FromJSON OptimizeBbox where
3431 parseJSON v = withText "NoOptimizeBbox" parseNoOptimize v
3433 where parseNoOptimize "none" = pure NoOptimizeBbox
3434 parseNoOptimize _ = mzero
3435 parseOptimize = fmap OptimizeGeoFilterType . parseJSON
3437instance ToJSON GeoBoundingBoxConstraint where
3438 toJSON (GeoBoundingBoxConstraint
3439 (FieldName gbbcGeoBBField) gbbcConstraintBox cache type') =
3440 object [gbbcGeoBBField .= gbbcConstraintBox
3444instance FromJSON GeoBoundingBoxConstraint where
3445 parseJSON = withObject "GeoBoundingBoxConstraint" parse
3446 where parse o = case HM.toList (deleteSeveral ["type", "_cache"] o) of
3447 [(fn, v)] -> GeoBoundingBoxConstraint (FieldName fn)
3449 <*> o .:? "_cache" .!= defaultCache
3451 _ -> fail "Could not find field name for GeoBoundingBoxConstraint"
3453instance ToJSON GeoFilterType where
3454 toJSON GeoFilterMemory = String "memory"
3455 toJSON GeoFilterIndexed = String "indexed"
3457instance FromJSON GeoFilterType where
3458 parseJSON = withText "GeoFilterType" parse
3459 where parse "memory" = pure GeoFilterMemory
3460 parse "indexed" = pure GeoFilterIndexed
3461 parse t = fail ("Unrecognized GeoFilterType: " <> show t)
3463instance ToJSON GeoBoundingBox where
3464 toJSON (GeoBoundingBox gbbTopLeft gbbBottomRight) =
3465 object ["top_left" .= gbbTopLeft
3466 , "bottom_right" .= gbbBottomRight]
3468instance FromJSON GeoBoundingBox where
3469 parseJSON = withObject "GeoBoundingBox" parse
3470 where parse o = GeoBoundingBox
3472 <*> o .: "bottom_right"
3474instance ToJSON LatLon where
3475 toJSON (LatLon lLat lLon) =
3476 object ["lat" .= lLat
3479instance FromJSON LatLon where
3480 parseJSON = withObject "LatLon" parse
3481 where parse o = LatLon <$> o .: "lat"
3484-- index for smaller ranges, fielddata for longer ranges
3485instance ToJSON RangeExecution where
3486 toJSON RangeExecutionIndex = "index"
3487 toJSON RangeExecutionFielddata = "fielddata"
3490instance FromJSON RangeExecution where
3491 parseJSON = withText "RangeExecution" parse
3492 where parse "index" = pure RangeExecutionIndex
3493 parse "fielddata" = pure RangeExecutionFielddata
3494 parse t = error ("Unrecognized RangeExecution " <> show t)
3496instance ToJSON RegexpFlags where
3497 toJSON AllRegexpFlags = String "ALL"
3498 toJSON NoRegexpFlags = String "NONE"
3499 toJSON (SomeRegexpFlags (h :| fs)) = String $ T.intercalate "|" flagStrs
3500 where flagStrs = map flagStr . nub $ h:fs
3501 flagStr AnyString = "ANYSTRING"
3502 flagStr Automaton = "AUTOMATON"
3503 flagStr Complement = "COMPLEMENT"
3504 flagStr Empty = "EMPTY"
3505 flagStr Intersection = "INTERSECTION"
3506 flagStr Interval = "INTERVAL"
3508instance FromJSON RegexpFlags where
3509 parseJSON = withText "RegexpFlags" parse
3510 where parse "ALL" = pure AllRegexpFlags
3511 parse "NONE" = pure NoRegexpFlags
3512 parse t = SomeRegexpFlags <$> parseNEJSON (String <$> T.splitOn "|" t)
3514instance FromJSON RegexpFlag where
3515 parseJSON = withText "RegexpFlag" parse
3516 where parse "ANYSTRING" = pure AnyString
3517 parse "AUTOMATON" = pure Automaton
3518 parse "COMPLEMENT" = pure Complement
3519 parse "EMPTY" = pure Empty
3520 parse "INTERSECTION" = pure Intersection
3521 parse "INTERVAL" = pure Interval
3522 parse f = fail ("Unknown RegexpFlag: " <> show f)
3524instance ToJSON Term where
3525 toJSON (Term field value) = object ["term" .= object
3528instance FromJSON Term where
3529 parseJSON = withObject "Term" parse
3530 where parse o = do termObj <- o .: "term"
3531 case HM.toList termObj of
3532 [(fn, v)] -> Term fn <$> parseJSON v
3533 _ -> fail "Expected object with 1 field-named key"
3535instance ToJSON BoolMatch where
3536 toJSON (MustMatch term cache) = object ["must" .= term,
3538 toJSON (MustNotMatch term cache) = object ["must_not" .= term,
3540 toJSON (ShouldMatch terms cache) = object ["should" .= fmap toJSON terms,
3543instance FromJSON BoolMatch where
3544 parseJSON = withObject "BoolMatch" parse
3545 where parse o = mustMatch `taggedWith` "must"
3546 <|> mustNotMatch `taggedWith` "must_not"
3547 <|> shouldMatch `taggedWith` "should"
3548 where taggedWith parser k = parser =<< o .: k
3549 mustMatch t = MustMatch t <$> o .:? "_cache" .!= defaultCache
3550 mustNotMatch t = MustNotMatch t <$> o .:? "_cache" .!= defaultCache
3551 shouldMatch t = ShouldMatch t <$> o .:? "_cache" .!= defaultCache
3553instance (FromJSON a) => FromJSON (SearchResult a) where
3554 parseJSON (Object v) = SearchResult <$>
3556 v .: "timed_out" <*>
3559 v .:? "aggregations" <*>
3563instance (FromJSON a) => FromJSON (SearchHits a) where
3564 parseJSON (Object v) = SearchHits <$>
3566 v .: "max_score" <*>
3570instance (FromJSON a) => FromJSON (Hit a) where
3571 parseJSON (Object v) = Hit <$>
3580instance FromJSON ShardResult where
3581 parseJSON (Object v) = ShardResult <$>
3583 v .: "successful" <*>
3588instance FromJSON DocVersion where
3591 maybe (fail "DocVersion out of range") return $ mkDocVersion i
3593-- This insanity is because ES *sometimes* returns Replica/Shard counts as strings
3594instance FromJSON ReplicaCount where
3595 parseJSON v = parseAsInt v
3597 where parseAsInt = fmap ReplicaCount . parseJSON
3598 parseAsString = withText "ReplicaCount" (fmap ReplicaCount . parseReadText)
3600instance FromJSON ShardCount where
3601 parseJSON v = parseAsInt v
3603 where parseAsInt = fmap ShardCount . parseJSON
3604 parseAsString = withText "ShardCount" (fmap ShardCount . parseReadText)
3606instance Bounded DocVersion where
3607 minBound = DocVersion 1
3608 maxBound = DocVersion 9200000000000000000 -- 9.2e+18
3610instance Enum DocVersion where
3612 | x /= maxBound = DocVersion (succ $ docVersionNumber x)
3613 | otherwise = succError "DocVersion"
3615 | x /= minBound = DocVersion (pred $ docVersionNumber x)
3616 | otherwise = predError "DocVersion"
3618 fromMaybe (error $ show i ++ " out of DocVersion range") $ mkDocVersion i
3619 fromEnum = docVersionNumber
3620 enumFrom = boundedEnumFrom
3621 enumFromThen = boundedEnumFromThen
3623-- | Username type used for HTTP Basic authentication. See 'basicAuthHook'.
3624newtype EsUsername = EsUsername { esUsername :: Text } deriving (Read, Show, Eq)
3626-- | Password type used for HTTP Basic authentication. See 'basicAuthHook'.
3627newtype EsPassword = EsPassword { esPassword :: Text } deriving (Read, Show, Eq)
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