@@ -1,8 +1,8 @@
1+{-# LANGUAGE DeriveGeneric #-}
1{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleInstances #-}
3{-# LANGUAGE FlexibleInstances #-}
3{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4{-# LANGUAGE MultiParamTypeClasses #-}
5{-# LANGUAGE MultiParamTypeClasses #-}
5−{-# LANGUAGE NamedFieldPuns #-}
6{-# LANGUAGE OverloadedStrings #-}
6{-# LANGUAGE OverloadedStrings #-}
7{-# LANGUAGE RecordWildCards #-}
7{-# LANGUAGE RecordWildCards #-}
8{-# LANGUAGE UndecidableInstances #-}
8{-# LANGUAGE UndecidableInstances #-}
@@ -10,11 +10,11 @@
10-------------------------------------------------------------------------------
10-------------------------------------------------------------------------------
12-- Module : Database.Bloodhound.Types
12-- Module : Database.Bloodhound.Types
13−-- Copyright : (C) 2014, 2018 Chris Allen
13+-- Copyright : (C) 2014 Chris Allen
14-- License : BSD-style (see the file LICENSE)
14-- License : BSD-style (see the file LICENSE)
15-- Maintainer : Chris Allen <cma@bitemyapp.com
15-- Maintainer : Chris Allen <cma@bitemyapp.com
16-- Stability : provisional
16-- Stability : provisional
17−-- Portability : RecordWildCards
17+-- Portability : DeriveGeneric, RecordWildCards
19-- Data types for describing actions and data structures performed to interact
19-- Data types for describing actions and data structures performed to interact
20-- with Elasticsearch. The two main buckets your queries against Elasticsearch
20-- with Elasticsearch. The two main buckets your queries against Elasticsearch
@@ -42,63 +42,26 @@ module Database.Bloodhound.Types
42 , mkTermsAggregation
42 , mkTermsAggregation
43 , mkTermsScriptAggregation
43 , mkTermsScriptAggregation
44 , mkDateHistogram
44 , mkDateHistogram
45− , mkCardinalityAggregation
46 , mkDocVersion
45 , mkDocVersion
48− , mkExtendedStatsAggregation
49 , docVersionNumber
46 , docVersionNumber
52 , toDateHistogram
48 , toDateHistogram
54 , omitNulls
49 , omitNulls
57− , BHEnv
52+ , BHEnv(..)
62 , MonadBH(..)
53 , MonadBH(..)
63 , Version(..)
54 , Version(..)
67 , Status(..)
55 , Status(..)
68 , Existence(..)
56 , Existence(..)
69 , NullValue(..)
57 , NullValue(..)
70 , IndexSettings(..)
58 , IndexSettings(..)
71− , UpdatableIndexSetting(..)
72− , IndexSettingsSummary(..)
73− , AllocationPolicy(..)
81− , InitialShardCount(..)
85 , IndexTemplate(..)
59 , IndexTemplate(..)
86 , Server(..)
60 , Server(..)
88 , EsResult(..)
62 , EsResult(..)
89 , EsResultFound(..)
63 , EsResultFound(..)
90 , EsError(..)
64 , EsError(..)
91− , EsProtocolException(..)
94− , IndexAliasAction(..)
95− , IndexAliasCreate(..)
96− , IndexAliasSummary(..)
97− , IndexAliasesSummary(..)
99− , SearchAliasRouting(..)
100− , IndexAliasRouting(..)
102 , DocVersion
65 , DocVersion
103 , ExternalDocVersion(..)
66 , ExternalDocVersion(..)
104 , VersionControl(..)
67 , VersionControl(..)
@@ -108,7 +71,7 @@ module Database.Bloodhound.Types
108 , Search(..)
71 , Search(..)
109 , SearchType(..)
72 , SearchType(..)
110 , SearchResult(..)
73 , SearchResult(..)
111− , ScrollId(..)
74+ , ScrollId
112 , SearchHits(..)
75 , SearchHits(..)
113 , TrackSortScores
76 , TrackSortScores
114 , From(..)
77 , From(..)
@@ -120,8 +83,8 @@ module Database.Bloodhound.Types
120 , Pattern(..)
83 , Pattern(..)
121 , ShardResult(..)
84 , ShardResult(..)
122 , Hit(..)
85 , Hit(..)
124 , Filter(..)
86 , Filter(..)
125 , BoolMatch(..)
88 , BoolMatch(..)
126 , Term(..)
89 , Term(..)
127 , GeoPoint(..)
90 , GeoPoint(..)
@@ -148,22 +111,8 @@ module Database.Bloodhound.Types
148 , RegexpFlags(..)
111 , RegexpFlags(..)
149 , RegexpFlag(..)
112 , RegexpFlag(..)
150 , FieldName(..)
113 , FieldName(..)
154 , Script(..)
114 , Script(..)
155− , ScriptLanguage(..)
161 , IndexName(..)
115 , IndexName(..)
162− , IndexSelection(..)
165− , ForceMergeIndexSettings(..)
166− , defaultForceMergeIndexSettings
167 , TemplateName(..)
116 , TemplateName(..)
168 , TemplatePattern(..)
117 , TemplatePattern(..)
169 , MappingName(..)
118 , MappingName(..)
@@ -187,19 +136,8 @@ module Database.Bloodhound.Types
187 , BoolQuery(..)
136 , BoolQuery(..)
188 , BoostingQuery(..)
137 , BoostingQuery(..)
189 , CommonTermsQuery(..)
138 , CommonTermsQuery(..)
190− , FunctionScoreQuery(..)
193− , FunctionScoreFunctions(..)
194− , ComponentFunctionScoreFunction(..)
195− , FunctionScoreFunction(..)
198− , FieldValueFactor(..)
200− , FactorModifier(..)
201− , FactorMissingFieldValue(..)
202 , DisMaxQuery(..)
139 , DisMaxQuery(..)
203 , FuzzyLikeThisQuery(..)
141 , FuzzyLikeThisQuery(..)
204 , FuzzyLikeFieldQuery(..)
142 , FuzzyLikeFieldQuery(..)
205 , FuzzyQuery(..)
143 , FuzzyQuery(..)
@@ -215,16 +153,10 @@ module Database.Bloodhound.Types
215 , RangeQuery(..)
153 , RangeQuery(..)
216 , RegexpQuery(..)
154 , RegexpQuery(..)
217 , QueryString(..)
155 , QueryString(..)
218− , TemplateQueryInline(..)
219− , TemplateQueryKeyValuePairs(..)
221 , BooleanOperator(..)
156 , BooleanOperator(..)
222 , ZeroTermsQuery(..)
157 , ZeroTermsQuery(..)
223 , CutoffFrequency(..)
158 , CutoffFrequency(..)
224 , Analyzer(..)
159 , Analyzer(..)
228 , MaxExpansions(..)
160 , MaxExpansions(..)
229 , Lenient(..)
161 , Lenient(..)
230 , MatchQueryType(..)
162 , MatchQueryType(..)
@@ -271,118 +203,16 @@ module Database.Bloodhound.Types
271 , CollectionMode(..)
203 , CollectionMode(..)
272 , TermOrder(..)
204 , TermOrder(..)
273 , TermInclusion(..)
205 , TermInclusion(..)
274− , SnapshotRepoSelection(..)
275− , GenericSnapshotRepo(..)
277− , SnapshotRepoConversionError(..)
278− , SnapshotRepoType(..)
279− , GenericSnapshotRepoSettings(..)
280− , SnapshotRepoUpdateSettings(..)
281− , defaultSnapshotRepoUpdateSettings
282− , SnapshotRepoName(..)
283− , SnapshotRepoPattern(..)
284− , SnapshotVerification(..)
285− , SnapshotNodeVerification(..)
292− , NodeBreakersStats(..)
293− , NodeBreakerStats(..)
295− , NodeTransportStats(..)
297− , NodeDataPathStats(..)
298− , NodeFSTotalStats(..)
299− , NodeNetworkStats(..)
300− , NodeThreadPoolsStats(..)
301− , NodeThreadPoolStats(..)
303− , JVMBufferPoolStats(..)
306− , NodeProcessStats(..)
309− , NodeIndicesStats(..)
313− , NodePluginInfo(..)
315− , NodeTransportInfo(..)
316− , BoundTransportAddress(..)
317− , NodeNetworkInfo(..)
319− , NetworkInterfaceName(..)
320− , NodeNetworkInterface(..)
321− , NodeThreadPoolsInfo(..)
322− , NodeThreadPoolInfo(..)
323− , ThreadPoolSize(..)
324− , ThreadPoolType(..)
327− , JVMGCCollector(..)
332− , NodeProcessInfo(..)
333− , FsSnapshotRepo(..)
334− , SnapshotCreateSettings(..)
335− , defaultSnapshotCreateSettings
336− , SnapshotSelection(..)
337− , SnapshotPattern(..)
339− , SnapshotShardFailure(..)
343− , SnapshotRestoreSettings(..)
344− , defaultSnapshotRestoreSettings
345− , RestoreRenamePattern(..)
346− , RestoreRenameToken(..)
350− , RestoreIndexSettings(..)
353− , PhraseSuggester(..)
354− , PhraseSuggesterHighlighter(..)
355− , PhraseSuggesterCollate(..)
357− , SuggestOptions(..)
358− , SuggestResponse(..)
359− , NamedSuggestionResponse(..)
360− , DirectGenerators(..)
361− , mkDirectGenerators
362− , DirectGeneratorSuggestModeTypes (..)
364 , Aggregation(..)
207 , Aggregation(..)
365 , Aggregations
208 , Aggregations
366 , AggregationResults
209 , AggregationResults
368 , Bucket(..)
210 , Bucket(..)
369 , BucketAggregation(..)
211 , BucketAggregation(..)
370 , TermsAggregation(..)
212 , TermsAggregation(..)
371− , MissingAggregation(..)
372 , ValueCountAggregation(..)
213 , ValueCountAggregation(..)
373 , FilterAggregation(..)
214 , FilterAggregation(..)
374− , CardinalityAggregation(..)
375− , MaxAggregation(..)
376 , DateHistogramAggregation(..)
215 , DateHistogramAggregation(..)
377− , DateRangeAggregation(..)
378− , DateRangeAggRange(..)
380− , DateMathAnchor(..)
381− , DateMathModifier(..)
383− , TopHitsAggregation(..)
384− , StatisticsAggregation(..)
387 , Highlights(..)
217 , Highlights(..)
388 , FieldHighlight(..)
218 , FieldHighlight(..)
@@ -396,36 +226,510 @@ module Database.Bloodhound.Types
396 , HighlightTag(..)
226 , HighlightTag(..)
397 , HitHighlight
227 , HitHighlight
400 , TermsResult(..)
229 , TermsResult(..)
401 , DateHistogramResult(..)
230 , DateHistogramResult(..)
402− , DateRangeResult(..)
231+ ) where
403− , TopHitResult(..)
232+
404−
233+import Control.Applicative
405− , EsUsername(..)
234+import Control.Monad.Catch
406− , EsPassword(..)
235+import Control.Monad.Except
407−
236+import Control.Monad.Reader
408− , Analysis(..)
237+import Control.Monad.State
409− , AnalyzerDefinition(..)
238+import Control.Monad.Writer
410− , TokenizerDefinition(..)
239+import Data.Aeson
411− , TokenFilterDefinition(..)
240+import Data.Aeson.Types (Pair, emptyObject, parseMaybe)
412− , CharFilterDefinition(..)
241+import qualified Data.ByteString.Lazy.Char8 as L
413− , Ngram(..)
242+import qualified Data.HashMap.Strict as HM (union)
414− , TokenChar(..)
243+import Data.List (foldl', nub)
415− , Shingle(..)
244+import Data.List.NonEmpty (NonEmpty (..), toList)
416− , Language(..)
245+import qualified Data.Map.Strict as M
417− ) where
246+import Data.Maybe
418−
247+import Data.Text (Text)
419−import Bloodhound.Import
248+import qualified Data.Text as T
420−
249+import Data.Time.Clock (UTCTime)
421−import Database.Bloodhound.Internal.Aggregation
250+import qualified Data.Vector as V
422−import Database.Bloodhound.Internal.Analysis
251+import GHC.Enum
423−import Database.Bloodhound.Internal.Client
252+import GHC.Generics (Generic)
424−import Database.Bloodhound.Internal.Highlight
253+import Network.HTTP.Client
425−import Database.Bloodhound.Internal.Newtypes
254+import qualified Network.HTTP.Types.Method as NHTM
426−import Database.Bloodhound.Internal.Query
255+
427−import Database.Bloodhound.Internal.Sort
256+import Database.Bloodhound.Types.Class
428−import Database.Bloodhound.Internal.Suggest
257+
259+-- >>> :set -XOverloadedStrings
260+-- >>> import Database.Bloodhound
261+-- >>> let testServer = (Server "http://localhost:9200")
262+-- >>> let testIndex = IndexName "twitter"
263+-- >>> let testMapping = MappingName "tweet"
264+-- >>> let defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
266+-- defaultIndexSettings is exported by Database.Bloodhound as well
267+-- no trailing slashes in servers, library handles building the path.
269+{-| Common environment for Elasticsearch calls. Connections will be
270+ pipelined according to the provided HTTP connection manager.
272+data BHEnv = BHEnv { bhServer :: Server
273+ , bhManager :: Manager
276+{-| All API calls to Elasticsearch operate within
277+ MonadBH. The idea is that it can be easily embedded in your
278+ own monad transformer stack. A default instance for a ReaderT and
279+ alias 'BH' is provided for the simple case.
281+class (Functor m, Applicative m, MonadIO m) => MonadBH m where
284+newtype BH m a = BH {
285+ unBH :: ReaderT BHEnv m a
286+ } deriving ( Functor
300+instance MonadTrans BH where
303+instance (MonadReader r m) => MonadReader r (BH m) where
305+ local f (BH (ReaderT m)) = BH $ ReaderT $ \r ->
308+instance (Functor m, Applicative m, MonadIO m) => MonadBH (BH m) where
309+ getBHEnv = BH getBHEnv
312+instance (Functor m, Applicative m, MonadIO m) => MonadBH (ReaderT BHEnv m) where
315+runBH :: BHEnv -> BH m a -> m a
316+runBH e f = runReaderT (unBH f) e
318+{-| 'Version' is embedded in 'Status' -}
319+data Version = Version { number :: Text
320+ , build_hash :: Text
321+ , build_timestamp :: UTCTime
322+ , build_snapshot :: Bool
323+ , lucene_version :: Text } deriving (Eq, Show, Generic)
325+{-| 'Status' is a data type for describing the JSON body returned by
326+ Elasticsearch when you query its status. This was deprecated in 1.2.0.
328+ <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-status.html#indices-status>
331+data Status = Status { ok :: Maybe Bool
334+ , version :: Version
335+ , tagline :: Text } deriving (Eq, Show)
337+{-| 'IndexSettings' is used to configure the shards and replicas when you create
338+ an Elasticsearch Index.
340+ <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html>
344+ IndexSettings { indexShards :: ShardCount
345+ , indexReplicas :: ReplicaCount } deriving (Eq, Show)
347+{-| 'defaultIndexSettings' is an 'IndexSettings' with 3 shards and 2 replicas. -}
348+defaultIndexSettings :: IndexSettings
349+defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
351+{-| 'Reply' and 'Method' are type synonyms from 'Network.HTTP.Types.Method.Method' -}
352+type Reply = Network.HTTP.Client.Response L.ByteString
353+type Method = NHTM.Method
355+{-| 'OpenCloseIndex' is a sum type for opening and closing indices.
357+ <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-open-close.html>
359+data OpenCloseIndex = OpenIndex | CloseIndex deriving (Eq, Show)
361+data FieldType = GeoPointType
367+ | ByteType deriving (Eq, Show)
369+data FieldDefinition =
370+ FieldDefinition { fieldType :: FieldType } deriving (Eq, Show)
372+{-| An 'IndexTemplate' defines a template that will automatically be
373+ applied to new indices created. The templates include both
374+ 'IndexSettings' and mappings, and a simple 'TemplatePattern' that
375+ controls if the template will be applied to the index created.
376+ Specify mappings as follows: @[toJSON TweetMapping, ...]@
378+ https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-templates.html
381+ IndexTemplate { templatePattern :: TemplatePattern
382+ , templateSettings :: Maybe IndexSettings
383+ , templateMappings :: [Value]
387+ MappingField { mappingFieldName :: FieldName
388+ , fieldDefinition :: FieldDefinition } deriving (Eq, Show)
390+{-| Support for type reification of 'Mapping's is currently incomplete, for
391+ now the mapping API verbiage expects a 'ToJSON'able blob.
393+ Indexes have mappings, mappings are schemas for the documents contained in the
394+ index. I'd recommend having only one mapping per index, always having a mapping,
395+ and keeping different kinds of documents separated if possible.
397+data Mapping = Mapping { typeName :: TypeName
398+ , mappingFields :: [MappingField] } deriving (Eq, Show)
400+{-| 'BulkOperation' is a sum type for expressing the four kinds of bulk
401+ operation index, create, delete, and update. 'BulkIndex' behaves like an
402+ "upsert", 'BulkCreate' will fail if a document already exists at the DocId.
404+ <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-bulk.html#docs-bulk>
407+ BulkIndex IndexName MappingName DocId Value
408+ | BulkCreate IndexName MappingName DocId Value
409+ | BulkDelete IndexName MappingName DocId
410+ | BulkUpdate IndexName MappingName DocId Value deriving (Eq, Show)
412+{-| 'EsResult' describes the standard wrapper JSON document that you see in
413+ successful Elasticsearch lookups or lookups that couldn't find the document.
415+data EsResult a = EsResult { _index :: Text
418+ , foundResult :: Maybe (EsResultFound a)} deriving (Eq, Show)
420+{-| 'EsResultFound' contains the document and its metadata inside of an
421+ 'EsResult' when the document was successfully found.
423+data EsResultFound a = EsResultFound { _version :: DocVersion
424+ , _source :: a } deriving (Eq, Show)
426+{-| 'EsError' is the generic type that will be returned when there was a
427+ problem. If you can't parse the expected response, its a good idea to
430+data EsError = EsError { errorStatus :: Int
431+ , errorMessage :: Text } deriving (Eq, Show)
434+{-| 'DocVersion' is an integer version number for a document between 1
435+and 9.2e+18 used for <<https://www.elastic.co/guide/en/elasticsearch/guide/current/optimistic-concurrency-control.html optimistic concurrency control>>.
437+newtype DocVersion = DocVersion {
438+ docVersionNumber :: Int
439+ } deriving (Eq, Show, Ord, ToJSON)
441+-- | Smart constructor for in-range doc version
442+mkDocVersion :: Int -> Maybe DocVersion
444+ | i >= (docVersionNumber minBound) && i <= (docVersionNumber maxBound) =
446+ | otherwise = Nothing
449+{-| 'ExternalDocVersion' is a convenience wrapper if your code uses its
450+own version numbers instead of ones from ES.
452+newtype ExternalDocVersion = ExternalDocVersion DocVersion
453+ deriving (Eq, Show, Ord, Bounded, Enum, ToJSON)
455+{-| 'VersionControl' is specified when indexing documents as a
456+optimistic concurrency control.
458+data VersionControl = NoVersionControl
459+ -- ^ Don't send a version. This is a pure overwrite.
460+ | InternalVersion DocVersion
461+ -- ^ Use the default ES versioning scheme. Only
462+ -- index the document if the version is the same
463+ -- as the one specified. Only applicable to
464+ -- updates, as you should be getting Version from
466+ | ExternalGT ExternalDocVersion
467+ -- ^ Use your own version numbering. Only index
468+ -- the document if the version is strictly higher
469+ -- OR the document doesn't exist. The given
470+ -- version will be used as the new version number
471+ -- for the stored document. N.B. All updates must
472+ -- increment this number, meaning there is some
473+ -- global, external ordering of updates.
474+ | ExternalGTE ExternalDocVersion
475+ -- ^ Use your own version numbering. Only index
476+ -- the document if the version is equal or higher
477+ -- than the stored version. Will succeed if there
478+ -- is no existing document. The given version will
479+ -- be used as the new version number for the
480+ -- stored document. Use with care, as this could
481+ -- result in data loss.
482+ | ForceVersion ExternalDocVersion
483+ -- ^ The document will always be indexed and the
484+ -- given version will be the new version. This is
485+ -- typically used for correcting errors. Use with
486+ -- care, as this could result in data loss.
487+ deriving (Show, Eq, Ord)
489+{-| 'DocumentParent' is used to specify a parent document.
491+newtype DocumentParent = DocumentParent DocId
494+{-| 'IndexDocumentSettings' are special settings supplied when indexing
495+a document. For the best backwards compatiblity when new fields are
496+added, you should probably prefer to start with 'defaultIndexDocumentSettings'
498+data IndexDocumentSettings =
499+ IndexDocumentSettings { idsVersionControl :: VersionControl
500+ , idsParent :: Maybe DocumentParent
501+ } deriving (Eq, Show)
503+{-| Reasonable default settings. Chooses no version control and no parent.
505+defaultIndexDocumentSettings :: IndexDocumentSettings
506+defaultIndexDocumentSettings = IndexDocumentSettings NoVersionControl Nothing
508+{-| 'Sort' is a synonym for a list of 'SortSpec's. Sort behavior is order
509+ dependent with later sorts acting as tie-breakers for earlier sorts.
511+type Sort = [SortSpec]
513+{-| The two main kinds of 'SortSpec' are 'DefaultSortSpec' and
514+ 'GeoDistanceSortSpec'. The latter takes a 'SortOrder', 'GeoPoint', and
515+ 'DistanceUnit' to express "nearness" to a single geographical point as a
518+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
520+data SortSpec = DefaultSortSpec DefaultSort
521+ | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit deriving (Eq, Show)
523+{-| 'DefaultSort' is usually the kind of 'SortSpec' you'll want. There's a
524+ 'mkSort' convenience function for when you want to specify only the most
527+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
530+ DefaultSort { sortFieldName :: FieldName
531+ , sortOrder :: SortOrder
533+ , ignoreUnmapped :: Bool
534+ , sortMode :: Maybe SortMode
535+ , missingSort :: Maybe Missing
536+ , nestedFilter :: Maybe Filter } deriving (Eq, Show)
538+{-| 'SortOrder' is 'Ascending' or 'Descending', as you might expect. These get
539+ encoded into "asc" or "desc" when turned into JSON.
541+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
543+data SortOrder = Ascending
544+ | Descending deriving (Eq, Show)
546+{-| 'Missing' prescribes how to handle missing fields. A missing field can be
547+ sorted last, first, or using a custom value as a substitute.
549+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_missing_values>
551+data Missing = LastMissing
553+ | CustomMissing Text deriving (Eq, Show)
555+{-| 'SortMode' prescribes how to handle sorting array/multi-valued fields.
557+http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_sort_mode_option
559+data SortMode = SortMin
562+ | SortAvg deriving (Eq, Show)
564+{-| 'mkSort' defaults everything but the 'FieldName' and the 'SortOrder' so
565+ that you can concisely describe the usual kind of 'SortSpec's you want.
567+mkSort :: FieldName -> SortOrder -> DefaultSort
568+mkSort fieldName sOrder = DefaultSort fieldName sOrder False Nothing Nothing Nothing
570+{-| 'Cache' is for telling ES whether it should cache a 'Filter' not.
571+ 'Query's cannot be cached.
573+type Cache = Bool -- caching on/off
574+defaultCache :: Cache
577+{-| 'PrefixValue' is used in 'PrefixQuery' as the main query component.
579+type PrefixValue = Text
581+{-| 'BooleanOperator' is the usual And/Or operators with an ES compatible
582+ JSON encoding baked in. Used all over the place.
584+data BooleanOperator = And | Or deriving (Eq, Show)
586+{-| 'ShardCount' is part of 'IndexSettings'
588+newtype ShardCount = ShardCount Int deriving (Eq, Show, Generic)
590+{-| 'ReplicaCount' is part of 'IndexSettings'
592+newtype ReplicaCount = ReplicaCount Int deriving (Eq, Show, Generic)
594+{-| 'Server' is used with the client functions to point at the ES instance
596+newtype Server = Server Text deriving (Eq, Show)
598+{-| 'IndexName' is used to describe which index to query/create/delete
600+newtype IndexName = IndexName Text deriving (Eq, Generic, Show)
602+{-| 'TemplateName' is used to describe which template to query/create/delete
604+newtype TemplateName = TemplateName Text deriving (Eq, Show, Generic)
606+{-| 'TemplatePattern' represents a pattern which is matched against index names
608+newtype TemplatePattern = TemplatePattern Text deriving (Eq, Show, Generic)
610+{-| 'MappingName' is part of mappings which are how ES describes and schematizes
611+ the data in the indices.
613+newtype MappingName = MappingName Text deriving (Eq, Generic, Show)
615+{-| 'DocId' is a generic wrapper value for expressing unique Document IDs.
616+ Can be set by the user or created by ES itself. Often used in client
617+ functions for poking at specific documents.
619+newtype DocId = DocId Text deriving (Eq, Generic, Show)
621+{-| 'QueryString' is used to wrap query text bodies, be they human written or not.
623+newtype QueryString = QueryString Text deriving (Eq, Generic, Show)
625+{-| 'FieldName' is used all over the place wherever a specific field within
626+ a document needs to be specified, usually in 'Query's or 'Filter's.
628+newtype FieldName = FieldName Text deriving (Eq, Show)
631+{-| 'Script' is often used in place of 'FieldName' to specify more
632+complex ways of extracting a value from a document.
634+newtype Script = Script { scriptText :: Text } deriving (Eq, Show)
636+{-| 'CacheName' is used in 'RegexpFilter' for describing the
637+ 'CacheKey' keyed caching behavior.
639+newtype CacheName = CacheName Text deriving (Eq, Show)
641+{-| 'CacheKey' is used in 'RegexpFilter' to key regex caching.
644+ CacheKey Text deriving (Eq, Show)
646+ Existence Bool deriving (Eq, Show)
648+ NullValue Bool deriving (Eq, Show)
649+newtype CutoffFrequency =
650+ CutoffFrequency Double deriving (Eq, Show, Generic)
652+ Analyzer Text deriving (Eq, Show, Generic)
653+newtype MaxExpansions =
654+ MaxExpansions Int deriving (Eq, Show, Generic)
656+{-| 'Lenient', if set to true, will cause format based failures to be
657+ ignored. I don't know what the bloody default is, Elasticsearch
658+ documentation didn't say what it was. Let me know if you figure it out.
661+ Lenient Bool deriving (Eq, Show, Generic)
663+ Tiebreaker Double deriving (Eq, Show, Generic)
665+ Boost Double deriving (Eq, Show, Generic)
667+ BoostTerms Double deriving (Eq, Show, Generic)
669+{-| 'MinimumMatch' controls how many should clauses in the bool query should
670+ match. Can be an absolute value (2) or a percentage (30%) or a
671+ combination of both.
673+newtype MinimumMatch =
674+ MinimumMatch Int deriving (Eq, Show, Generic)
675+newtype MinimumMatchText =
676+ MinimumMatchText Text deriving (Eq, Show)
677+newtype DisableCoord =
678+ DisableCoord Bool deriving (Eq, Show, Generic)
679+newtype IgnoreTermFrequency =
680+ IgnoreTermFrequency Bool deriving (Eq, Show, Generic)
681+newtype MinimumTermFrequency =
682+ MinimumTermFrequency Int deriving (Eq, Show, Generic)
683+newtype MaxQueryTerms =
684+ MaxQueryTerms Int deriving (Eq, Show, Generic)
686+ Fuzziness Double deriving (Eq, Show, Generic)
688+{-| 'PrefixLength' is the prefix length used in queries, defaults to 0. -}
689+newtype PrefixLength =
690+ PrefixLength Int deriving (Eq, Show, Generic)
692+ TypeName Text deriving (Eq, Show, Generic)
693+newtype PercentMatch =
694+ PercentMatch Double deriving (Eq, Show, Generic)
696+ StopWord Text deriving (Eq, Show, Generic)
698+ QueryPath Text deriving (Eq, Show, Generic)
700+{-| Allowing a wildcard at the beginning of a word (eg "*ing") is particularly
701+ heavy, because all terms in the index need to be examined, just in case
702+ they match. Leading wildcards can be disabled by setting
703+ 'AllowLeadingWildcard' to false. -}
704+newtype AllowLeadingWildcard =
705+ AllowLeadingWildcard Bool deriving (Eq, Show, Generic)
706+newtype LowercaseExpanded =
707+ LowercaseExpanded Bool deriving (Eq, Show, Generic)
708+newtype EnablePositionIncrements =
709+ EnablePositionIncrements Bool deriving (Eq, Show, Generic)
711+{-| By default, wildcard terms in a query are not analyzed.
712+ Setting 'AnalyzeWildcard' to true enables best-effort analysis.
714+newtype AnalyzeWildcard = AnalyzeWildcard Bool deriving (Eq, Show, Generic)
716+{-| 'GeneratePhraseQueries' defaults to false.
718+newtype GeneratePhraseQueries =
719+ GeneratePhraseQueries Bool deriving (Eq, Show, Generic)
721+{-| 'Locale' is used for string conversions - defaults to ROOT.
723+newtype Locale = Locale Text deriving (Eq, Show, Generic)
724+newtype MaxWordLength = MaxWordLength Int deriving (Eq, Show, Generic)
725+newtype MinWordLength = MinWordLength Int deriving (Eq, Show, Generic)
727+{-| 'PhraseSlop' sets the default slop for phrases, 0 means exact
728+ phrase matches. Default is 0.
730+newtype PhraseSlop = PhraseSlop Int deriving (Eq, Show, Generic)
731+newtype MinDocFrequency = MinDocFrequency Int deriving (Eq, Show, Generic)
732+newtype MaxDocFrequency = MaxDocFrequency Int deriving (Eq, Show, Generic)
430{-| 'unpackId' is a silly convenience function that gets used once.
734{-| 'unpackId' is a silly convenience function that gets used once.
@@ -433,6 +737,8 @@ unpackId :: DocId -> Text
433unpackId (DocId docId) = docId
737unpackId (DocId docId) = docId
435type TrackSortScores = Bool
739type TrackSortScores = Bool
740+newtype From = From Int deriving (Eq, Show, ToJSON)
741+newtype Size = Size Int deriving (Eq, Show, ToJSON)
437data Search = Search { queryBody :: Maybe Query
743data Search = Search { queryBody :: Maybe Query
438 , filterBody :: Maybe Filter
744 , filterBody :: Maybe Filter
@@ -444,87 +750,1644 @@ data Search = Search { queryBody :: Maybe Query
444 , from :: From
750 , from :: From
445 , size :: Size
751 , size :: Size
446 , searchType :: SearchType
752 , searchType :: SearchType
447− , searchAfterKey :: Maybe SearchAfterKey
448 , fields :: Maybe [FieldName]
753 , fields :: Maybe [FieldName]
449− , scriptFields :: Maybe ScriptFields
450− , source :: Maybe Source
754+ , source :: Maybe Source } deriving (Eq, Show)
451− , suggestBody :: Maybe Suggest -- ^ Only one Suggestion request / response per Search is supported.
452− } deriving (Eq, Show)
455−instance ToJSON Search where
456− toJSON (Search mquery sFilter sort searchAggs
457− highlight sTrackSortScores sFrom sSize _ sAfter sFields
458− sScriptFields sSource sSuggest) =
459− omitNulls [ "query" .= query'
461− , "aggregations" .= searchAggs
462− , "highlight" .= highlight
465− , "track_scores" .= sTrackSortScores
466− , "search_after" .= sAfter
467− , "fields" .= sFields
468− , "script_fields" .= sScriptFields
469− , "_source" .= sSource
470− , "suggest" .= sSuggest]
472− where query' = case sFilter of
477− $ mkBoolQuery (maybeToList mquery)
480data SearchType = SearchTypeQueryThenFetch
756data SearchType = SearchTypeQueryThenFetch
481 | SearchTypeDfsQueryThenFetch
757 | SearchTypeDfsQueryThenFetch
760+ | SearchTypeQueryAndFetch
761+ | SearchTypeDfsQueryAndFetch
482 deriving (Eq, Show)
762 deriving (Eq, Show)
484data Source =
764data Source =
486 | SourcePatterns PatternOrPatterns
766 | SourcePatterns PatternOrPatterns
487 | SourceIncludeExclude Include Exclude
767 | SourceIncludeExclude Include Exclude
488− deriving (Eq, Show)
768+ deriving (Show, Eq)
770+data PatternOrPatterns = PopPattern Pattern
771+ | PopPatterns [Pattern] deriving (Eq, Show)
773+data Include = Include [Pattern] deriving (Eq, Show)
774+data Exclude = Exclude [Pattern] deriving (Eq, Show)
776+newtype Pattern = Pattern Text deriving (Eq, Show)
778+data Highlights = Highlights { globalsettings :: Maybe HighlightSettings
779+ , highlightFields :: [FieldHighlight]
780+ } deriving (Show, Eq)
782+data FieldHighlight = FieldHighlight FieldName (Maybe HighlightSettings)
786+data HighlightSettings = Plain PlainHighlight
787+ | Postings PostingsHighlight
788+ | FastVector FastVectorHighlight
790+data PlainHighlight =
791+ PlainHighlight { plainCommon :: Maybe CommonHighlight
792+ , plainNonPost :: Maybe NonPostings } deriving (Show, Eq)
794+ -- This requires that index_options are set to 'offset' in the mapping.
795+data PostingsHighlight = PostingsHighlight (Maybe CommonHighlight) deriving (Show, Eq)
797+-- This requires that term_vector is set to 'with_positions_offsets' in the mapping.
798+data FastVectorHighlight =
799+ FastVectorHighlight { fvCommon :: Maybe CommonHighlight
800+ , fvNonPostSettings :: Maybe NonPostings
801+ , boundaryChars :: Maybe Text
802+ , boundaryMaxScan :: Maybe Int
803+ , fragmentOffset :: Maybe Int
804+ , matchedFields :: [Text]
805+ , phraseLimit :: Maybe Int
806+ } deriving (Show, Eq)
808+data CommonHighlight =
809+ CommonHighlight { order :: Maybe Text
810+ , forceSource :: Maybe Bool
811+ , tag :: Maybe HighlightTag
812+ , encoder :: Maybe HighlightEncoder
813+ , noMatchSize :: Maybe Int
814+ , highlightQuery :: Maybe Query
815+ , requireFieldMatch :: Maybe Bool
816+ } deriving (Show, Eq)
818+-- Settings that are only applicable to FastVector and Plain highlighters.
820+ NonPostings { fragmentSize :: Maybe Int
821+ , numberOfFragments :: Maybe Int} deriving (Show, Eq)
823+data HighlightEncoder = DefaultEncoder
827+-- NOTE: Should the tags use some kind of HTML type, rather than Text?
828+data HighlightTag = TagSchema Text
829+ | CustomTags ([Text], [Text]) -- Only uses more than the first value in the lists if fvh
834+ TermQuery Term (Maybe Boost)
835+ | TermsQuery (NonEmpty Term)
836+ | QueryMatchQuery MatchQuery
837+ | QueryMultiMatchQuery MultiMatchQuery
838+ | QueryBoolQuery BoolQuery
839+ | QueryBoostingQuery BoostingQuery
840+ | QueryCommonTermsQuery CommonTermsQuery
841+ | ConstantScoreFilter Filter Boost
842+ | ConstantScoreQuery Query Boost
843+ | QueryDisMaxQuery DisMaxQuery
844+ | QueryFilteredQuery FilteredQuery
845+ | QueryFuzzyLikeThisQuery FuzzyLikeThisQuery
846+ | QueryFuzzyLikeFieldQuery FuzzyLikeFieldQuery
847+ | QueryFuzzyQuery FuzzyQuery
848+ | QueryHasChildQuery HasChildQuery
849+ | QueryHasParentQuery HasParentQuery
850+ | IdsQuery MappingName [DocId]
851+ | QueryIndicesQuery IndicesQuery
852+ | MatchAllQuery (Maybe Boost)
853+ | QueryMoreLikeThisQuery MoreLikeThisQuery
854+ | QueryMoreLikeThisFieldQuery MoreLikeThisFieldQuery
855+ | QueryNestedQuery NestedQuery
856+ | QueryPrefixQuery PrefixQuery
857+ | QueryQueryStringQuery QueryStringQuery
858+ | QuerySimpleQueryStringQuery SimpleQueryStringQuery
859+ | QueryRangeQuery RangeQuery
860+ | QueryRegexpQuery RegexpQuery
864+ RegexpQuery { regexpQueryField :: FieldName
865+ , regexpQuery :: Regexp
866+ , regexpQueryFlags :: RegexpFlags
867+ , regexpQueryBoost :: Maybe Boost
868+ } deriving (Eq, Show)
871+ RangeQuery { rangeQueryField :: FieldName
872+ , rangeQueryRange :: RangeValue
873+ , rangeQueryBoost :: Boost } deriving (Eq, Show)
875+mkRangeQuery :: FieldName -> RangeValue -> RangeQuery
876+mkRangeQuery f r = RangeQuery f r (Boost 1.0)
878+data SimpleQueryStringQuery =
879+ SimpleQueryStringQuery
880+ { simpleQueryStringQuery :: QueryString
881+ , simpleQueryStringField :: Maybe FieldOrFields
882+ , simpleQueryStringOperator :: Maybe BooleanOperator
883+ , simpleQueryStringAnalyzer :: Maybe Analyzer
884+ , simpleQueryStringFlags :: Maybe [SimpleQueryFlag]
885+ , simpleQueryStringLowercaseExpanded :: Maybe LowercaseExpanded
886+ , simpleQueryStringLocale :: Maybe Locale
887+ } deriving (Eq, Show)
889+data SimpleQueryFlag =
896+ | SimpleQueryPrecedence
898+ | SimpleQueryWhitespace
901+ | SimpleQuerySlop deriving (Eq, Show)
903+-- use_dis_max and tie_breaker when fields are plural?
904+data QueryStringQuery =
906+ { queryStringQuery :: QueryString
907+ , queryStringDefaultField :: Maybe FieldName
908+ , queryStringOperator :: Maybe BooleanOperator
909+ , queryStringAnalyzer :: Maybe Analyzer
910+ , queryStringAllowLeadingWildcard :: Maybe AllowLeadingWildcard
911+ , queryStringLowercaseExpanded :: Maybe LowercaseExpanded
912+ , queryStringEnablePositionIncrements :: Maybe EnablePositionIncrements
913+ , queryStringFuzzyMaxExpansions :: Maybe MaxExpansions
914+ , queryStringFuzziness :: Maybe Fuzziness
915+ , queryStringFuzzyPrefixLength :: Maybe PrefixLength
916+ , queryStringPhraseSlop :: Maybe PhraseSlop
917+ , queryStringBoost :: Maybe Boost
918+ , queryStringAnalyzeWildcard :: Maybe AnalyzeWildcard
919+ , queryStringGeneratePhraseQueries :: Maybe GeneratePhraseQueries
920+ , queryStringMinimumShouldMatch :: Maybe MinimumMatch
921+ , queryStringLenient :: Maybe Lenient
922+ , queryStringLocale :: Maybe Locale
923+ } deriving (Eq, Show)
925+mkQueryStringQuery :: QueryString -> QueryStringQuery
926+mkQueryStringQuery qs =
927+ QueryStringQuery qs Nothing Nothing
928+ Nothing Nothing Nothing Nothing
929+ Nothing Nothing Nothing Nothing
930+ Nothing Nothing Nothing Nothing
933+data FieldOrFields = FofField FieldName
934+ | FofFields [FieldName] deriving (Eq, Show)
938+ { prefixQueryField :: FieldName
939+ , prefixQueryPrefixValue :: Text
940+ , prefixQueryBoost :: Maybe Boost } deriving (Eq, Show)
944+ { nestedQueryPath :: QueryPath
945+ , nestedQueryScoreType :: ScoreType
946+ , nestedQuery :: Query } deriving (Eq, Show)
948+data MoreLikeThisFieldQuery =
949+ MoreLikeThisFieldQuery
950+ { moreLikeThisFieldText :: Text
951+ , moreLikeThisFieldFields :: FieldName
952+ -- default 0.3 (30%)
953+ , moreLikeThisFieldPercentMatch :: Maybe PercentMatch
954+ , moreLikeThisFieldMinimumTermFreq :: Maybe MinimumTermFrequency
955+ , moreLikeThisFieldMaxQueryTerms :: Maybe MaxQueryTerms
956+ , moreLikeThisFieldStopWords :: Maybe [StopWord]
957+ , moreLikeThisFieldMinDocFrequency :: Maybe MinDocFrequency
958+ , moreLikeThisFieldMaxDocFrequency :: Maybe MaxDocFrequency
959+ , moreLikeThisFieldMinWordLength :: Maybe MinWordLength
960+ , moreLikeThisFieldMaxWordLength :: Maybe MaxWordLength
961+ , moreLikeThisFieldBoostTerms :: Maybe BoostTerms
962+ , moreLikeThisFieldBoost :: Maybe Boost
963+ , moreLikeThisFieldAnalyzer :: Maybe Analyzer
964+ } deriving (Eq, Show)
966+data MoreLikeThisQuery =
968+ { moreLikeThisText :: Text
969+ , moreLikeThisFields :: Maybe [FieldName]
970+ -- default 0.3 (30%)
971+ , moreLikeThisPercentMatch :: Maybe PercentMatch
972+ , moreLikeThisMinimumTermFreq :: Maybe MinimumTermFrequency
973+ , moreLikeThisMaxQueryTerms :: Maybe MaxQueryTerms
974+ , moreLikeThisStopWords :: Maybe [StopWord]
975+ , moreLikeThisMinDocFrequency :: Maybe MinDocFrequency
976+ , moreLikeThisMaxDocFrequency :: Maybe MaxDocFrequency
977+ , moreLikeThisMinWordLength :: Maybe MinWordLength
978+ , moreLikeThisMaxWordLength :: Maybe MaxWordLength
979+ , moreLikeThisBoostTerms :: Maybe BoostTerms
980+ , moreLikeThisBoost :: Maybe Boost
981+ , moreLikeThisAnalyzer :: Maybe Analyzer
982+ } deriving (Eq, Show)
986+ { indicesQueryIndices :: [IndexName]
987+ , indicesQuery :: Query
989+ , indicesQueryNoMatch :: Maybe Query } deriving (Eq, Show)
991+data HasParentQuery =
993+ { hasParentQueryType :: TypeName
994+ , hasParentQuery :: Query
995+ , hasParentQueryScoreType :: Maybe ScoreType } deriving (Eq, Show)
999+ { hasChildQueryType :: TypeName
1000+ , hasChildQuery :: Query
1001+ , hasChildQueryScoreType :: Maybe ScoreType } deriving (Eq, Show)
1007+ | ScoreTypeNone deriving (Eq, Show)
1010+ FuzzyQuery { fuzzyQueryField :: FieldName
1011+ , fuzzyQueryValue :: Text
1012+ , fuzzyQueryPrefixLength :: PrefixLength
1013+ , fuzzyQueryMaxExpansions :: MaxExpansions
1014+ , fuzzyQueryFuzziness :: Fuzziness
1015+ , fuzzyQueryBoost :: Maybe Boost
1016+ } deriving (Eq, Show)
1018+data FuzzyLikeFieldQuery =
1019+ FuzzyLikeFieldQuery
1020+ { fuzzyLikeField :: FieldName
1021+ -- anaphora is good for the soul.
1022+ , fuzzyLikeFieldText :: Text
1023+ , fuzzyLikeFieldMaxQueryTerms :: MaxQueryTerms
1024+ , fuzzyLikeFieldIgnoreTermFrequency :: IgnoreTermFrequency
1025+ , fuzzyLikeFieldFuzziness :: Fuzziness
1026+ , fuzzyLikeFieldPrefixLength :: PrefixLength
1027+ , fuzzyLikeFieldBoost :: Boost
1028+ , fuzzyLikeFieldAnalyzer :: Maybe Analyzer
1029+ } deriving (Eq, Show)
1031+data FuzzyLikeThisQuery =
1033+ { fuzzyLikeFields :: [FieldName]
1034+ , fuzzyLikeText :: Text
1035+ , fuzzyLikeMaxQueryTerms :: MaxQueryTerms
1036+ , fuzzyLikeIgnoreTermFrequency :: IgnoreTermFrequency
1037+ , fuzzyLikeFuzziness :: Fuzziness
1038+ , fuzzyLikePrefixLength :: PrefixLength
1039+ , fuzzyLikeBoost :: Boost
1040+ , fuzzyLikeAnalyzer :: Maybe Analyzer
1041+ } deriving (Eq, Show)
1043+data FilteredQuery =
1045+ { filteredQuery :: Query
1046+ , filteredFilter :: Filter } deriving (Eq, Show)
1049+ DisMaxQuery { disMaxQueries :: [Query]
1051+ , disMaxTiebreaker :: Tiebreaker
1052+ , disMaxBoost :: Maybe Boost
1053+ } deriving (Eq, Show)
1056+ MatchQuery { matchQueryField :: FieldName
1057+ , matchQueryQueryString :: QueryString
1058+ , matchQueryOperator :: BooleanOperator
1059+ , matchQueryZeroTerms :: ZeroTermsQuery
1060+ , matchQueryCutoffFrequency :: Maybe CutoffFrequency
1061+ , matchQueryMatchType :: Maybe MatchQueryType
1062+ , matchQueryAnalyzer :: Maybe Analyzer
1063+ , matchQueryMaxExpansions :: Maybe MaxExpansions
1064+ , matchQueryLenient :: Maybe Lenient
1065+ , matchQueryBoost :: Maybe Boost } deriving (Eq, Show)
1067+{-| 'mkMatchQuery' is a convenience function that defaults the less common parameters,
1068+ enabling you to provide only the 'FieldName' and 'QueryString' to make a 'MatchQuery'
1070+mkMatchQuery :: FieldName -> QueryString -> MatchQuery
1071+mkMatchQuery field query = MatchQuery field query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1073+data MatchQueryType =
1075+ | MatchPhrasePrefix deriving (Eq, Show)
1077+data MultiMatchQuery =
1078+ MultiMatchQuery { multiMatchQueryFields :: [FieldName]
1079+ , multiMatchQueryString :: QueryString
1080+ , multiMatchQueryOperator :: BooleanOperator
1081+ , multiMatchQueryZeroTerms :: ZeroTermsQuery
1082+ , multiMatchQueryTiebreaker :: Maybe Tiebreaker
1083+ , multiMatchQueryType :: Maybe MultiMatchQueryType
1084+ , multiMatchQueryCutoffFrequency :: Maybe CutoffFrequency
1085+ , multiMatchQueryAnalyzer :: Maybe Analyzer
1086+ , multiMatchQueryMaxExpansions :: Maybe MaxExpansions
1087+ , multiMatchQueryLenient :: Maybe Lenient } deriving (Eq, Show)
1089+{-| 'mkMultiMatchQuery' is a convenience function that defaults the less common parameters,
1090+ enabling you to provide only the list of 'FieldName's and 'QueryString' to
1091+ make a 'MultiMatchQuery'.
1094+mkMultiMatchQuery :: [FieldName] -> QueryString -> MultiMatchQuery
1095+mkMultiMatchQuery matchFields query =
1096+ MultiMatchQuery matchFields query
1097+ Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1099+data MultiMatchQueryType =
1100+ MultiMatchBestFields
1101+ | MultiMatchMostFields
1102+ | MultiMatchCrossFields
1104+ | MultiMatchPhrasePrefix deriving (Eq, Show)
1107+ BoolQuery { boolQueryMustMatch :: [Query]
1108+ , boolQueryMustNotMatch :: [Query]
1109+ , boolQueryShouldMatch :: [Query]
1110+ , boolQueryMinimumShouldMatch :: Maybe MinimumMatch
1111+ , boolQueryBoost :: Maybe Boost
1112+ , boolQueryDisableCoord :: Maybe DisableCoord
1113+ } deriving (Eq, Show)
1115+mkBoolQuery :: [Query] -> [Query] -> [Query] -> BoolQuery
1116+mkBoolQuery must mustNot should =
1117+ BoolQuery must mustNot should Nothing Nothing Nothing
1119+data BoostingQuery =
1120+ BoostingQuery { positiveQuery :: Query
1121+ , negativeQuery :: Query
1122+ , negativeBoost :: Boost } deriving (Eq, Show)
1124+data CommonTermsQuery =
1125+ CommonTermsQuery { commonField :: FieldName
1126+ , commonQuery :: QueryString
1127+ , commonCutoffFrequency :: CutoffFrequency
1128+ , commonLowFreqOperator :: BooleanOperator
1129+ , commonHighFreqOperator :: BooleanOperator
1130+ , commonMinimumShouldMatch :: Maybe CommonMinimumMatch
1131+ , commonBoost :: Maybe Boost
1132+ , commonAnalyzer :: Maybe Analyzer
1133+ , commonDisableCoord :: Maybe DisableCoord
1134+ } deriving (Eq, Show)
1136+data CommonMinimumMatch =
1137+ CommonMinimumMatchHighLow MinimumMatchHighLow
1138+ | CommonMinimumMatch MinimumMatch
1139+ deriving (Eq, Show)
1141+data MinimumMatchHighLow =
1142+ MinimumMatchHighLow { lowFreq :: MinimumMatch
1143+ , highFreq :: MinimumMatch } deriving (Eq, Show)
1145+data Filter = AndFilter [Filter] Cache
1146+ | OrFilter [Filter] Cache
1147+ | NotFilter Filter Cache
1149+ | BoolFilter BoolMatch
1150+ | ExistsFilter FieldName -- always cached
1151+ | GeoBoundingBoxFilter GeoBoundingBoxConstraint
1152+ | GeoDistanceFilter GeoPoint Distance DistanceType OptimizeBbox Cache
1153+ | GeoDistanceRangeFilter GeoPoint DistanceRange
1154+ | GeoPolygonFilter FieldName [LatLon]
1155+ | IdsFilter MappingName [DocId]
1157+ | MissingFilter FieldName Existence NullValue
1158+ | PrefixFilter FieldName PrefixValue Cache
1159+ | QueryFilter Query Cache
1160+ | RangeFilter FieldName RangeValue RangeExecution Cache
1161+ | RegexpFilter FieldName Regexp RegexpFlags CacheName Cache CacheKey
1162+ | TermFilter Term Cache
1163+ deriving (Eq, Show)
1165+data ZeroTermsQuery = ZeroTermsNone
1166+ | ZeroTermsAll deriving (Eq, Show)
1168+data RangeExecution = RangeExecutionIndex
1169+ | RangeExecutionFielddata deriving (Eq, Show)
1171+newtype Regexp = Regexp Text deriving (Eq, Show)
1173+data RegexpFlags = AllRegexpFlags
1175+ | SomeRegexpFlags (NonEmpty RegexpFlag) deriving (Eq, Show)
1177+data RegexpFlag = AnyString
1182+ | Interval deriving (Eq, Show)
1184+newtype LessThan = LessThan Double deriving (Eq, Show)
1185+newtype LessThanEq = LessThanEq Double deriving (Eq, Show)
1186+newtype GreaterThan = GreaterThan Double deriving (Eq, Show)
1187+newtype GreaterThanEq = GreaterThanEq Double deriving (Eq, Show)
1189+newtype LessThanD = LessThanD UTCTime deriving (Eq, Show)
1190+newtype LessThanEqD = LessThanEqD UTCTime deriving (Eq, Show)
1191+newtype GreaterThanD = GreaterThanD UTCTime deriving (Eq, Show)
1192+newtype GreaterThanEqD = GreaterThanEqD UTCTime deriving (Eq, Show)
1194+data RangeValue = RangeDateLte LessThanEqD
1195+ | RangeDateLt LessThanD
1196+ | RangeDateGte GreaterThanEqD
1197+ | RangeDateGt GreaterThanD
1198+ | RangeDateGtLt GreaterThanD LessThanD
1199+ | RangeDateGteLte GreaterThanEqD LessThanEqD
1200+ | RangeDateGteLt GreaterThanEqD LessThanD
1201+ | RangeDateGtLte GreaterThanD LessThanEqD
1202+ | RangeDoubleLte LessThanEq
1203+ | RangeDoubleLt LessThan
1204+ | RangeDoubleGte GreaterThanEq
1205+ | RangeDoubleGt GreaterThan
1206+ | RangeDoubleGtLt GreaterThan LessThan
1207+ | RangeDoubleGteLte GreaterThanEq LessThanEq
1208+ | RangeDoubleGteLt GreaterThanEq LessThan
1209+ | RangeDoubleGtLte GreaterThan LessThanEq
1210+ deriving (Eq, Show)
1212+rangeValueToPair :: RangeValue -> [Pair]
1213+rangeValueToPair rv = case rv of
1214+ RangeDateLte (LessThanEqD t) -> ["lte" .= t]
1215+ RangeDateGte (GreaterThanEqD t) -> ["gte" .= t]
1216+ RangeDateLt (LessThanD t) -> ["lt" .= t]
1217+ RangeDateGt (GreaterThanD t) -> ["gt" .= t]
1218+ RangeDateGteLte (GreaterThanEqD l) (LessThanEqD g) -> ["gte" .= l, "lte" .= g]
1219+ RangeDateGtLte (GreaterThanD l) (LessThanEqD g) -> ["gt" .= l, "lte" .= g]
1220+ RangeDateGteLt (GreaterThanEqD l) (LessThanD g) -> ["gte" .= l, "lt" .= g]
1221+ RangeDateGtLt (GreaterThanD l) (LessThanD g) -> ["gt" .= l, "lt" .= g]
1222+ RangeDoubleLte (LessThanEq t) -> ["lte" .= t]
1223+ RangeDoubleGte (GreaterThanEq t) -> ["gte" .= t]
1224+ RangeDoubleLt (LessThan t) -> ["lt" .= t]
1225+ RangeDoubleGt (GreaterThan t) -> ["gt" .= t]
1226+ RangeDoubleGteLte (GreaterThanEq l) (LessThanEq g) -> ["gte" .= l, "lte" .= g]
1227+ RangeDoubleGtLte (GreaterThan l) (LessThanEq g) -> ["gt" .= l, "lte" .= g]
1228+ RangeDoubleGteLt (GreaterThanEq l) (LessThan g) -> ["gte" .= l, "lt" .= g]
1229+ RangeDoubleGtLt (GreaterThan l) (LessThan g) -> ["gt" .= l, "lt" .= g]
1231+data Term = Term { termField :: Text
1232+ , termValue :: Text } deriving (Eq, Show)
1234+data BoolMatch = MustMatch Term Cache
1235+ | MustNotMatch Term Cache
1236+ | ShouldMatch [Term] Cache deriving (Eq, Show)
1238+-- "memory" or "indexed"
1239+data GeoFilterType = GeoFilterMemory
1240+ | GeoFilterIndexed deriving (Eq, Show)
1242+data LatLon = LatLon { lat :: Double
1243+ , lon :: Double } deriving (Eq, Show)
1245+data GeoBoundingBox =
1246+ GeoBoundingBox { topLeft :: LatLon
1247+ , bottomRight :: LatLon } deriving (Eq, Show)
1249+data GeoBoundingBoxConstraint =
1250+ GeoBoundingBoxConstraint { geoBBField :: FieldName
1251+ , constraintBox :: GeoBoundingBox
1252+ , bbConstraintcache :: Cache
1253+ , geoType :: GeoFilterType
1254+ } deriving (Eq, Show)
1257+ GeoPoint { geoField :: FieldName
1258+ , latLon :: LatLon} deriving (Eq, Show)
1260+data DistanceUnit = Miles
1268+ | NauticalMiles deriving (Eq, Show)
1270+data DistanceType = Arc
1271+ | SloppyArc -- doesn't exist <1.0
1272+ | Plane deriving (Eq, Show)
1274+data OptimizeBbox = OptimizeGeoFilterType GeoFilterType
1275+ | NoOptimizeBbox deriving (Eq, Show)
1278+ Distance { coefficient :: Double
1279+ , unit :: DistanceUnit } deriving (Eq, Show)
1281+data DistanceRange =
1282+ DistanceRange { distanceFrom :: Distance
1283+ , distanceTo :: Distance } deriving (Eq, Show)
1285+data SearchResult a =
1286+ SearchResult { took :: Int
1288+ , shards :: ShardResult
1289+ , searchHits :: SearchHits a
1290+ , aggregations :: Maybe AggregationResults
1291+ , scrollId :: Maybe ScrollId } deriving (Eq, Show)
1293+type ScrollId = Text -- Fixme: Newtype
1295+type Score = Maybe Double
1298+ SearchHits { hitsTotal :: Int
1299+ , maxScore :: Score
1300+ , hits :: [Hit a] } deriving (Eq, Show)
1303+instance Monoid (SearchHits a) where
1304+ mempty = SearchHits 0 Nothing mempty
1305+ mappend (SearchHits ta ma ha) (SearchHits tb mb hb) =
1306+ SearchHits (ta + tb) (max ma mb) (ha <> hb)
1310+ Hit { hitIndex :: IndexName
1311+ , hitType :: MappingName
1312+ , hitDocId :: DocId
1313+ , hitScore :: Score
1314+ , hitSource :: Maybe a
1315+ , hitHighlight :: Maybe HitHighlight } deriving (Eq, Show)
1318+ ShardResult { shardTotal :: Int
1319+ , shardsSuccessful :: Int
1320+ , shardsFailed :: Int } deriving (Eq, Show, Generic)
1322+type HitHighlight = M.Map Text [Text]
1324+showText :: Show a => a -> Text
1325+showText = T.pack . show
1327+type Aggregations = M.Map Text Aggregation
1329+emptyAggregations :: Aggregations
1330+emptyAggregations = M.empty
1332+mkAggregations :: Text -> Aggregation -> Aggregations
1333+mkAggregations name aggregation = M.insert name aggregation emptyAggregations
1335+data TermOrder = TermOrder{ termSortField :: Text
1336+ , termSortOrder :: SortOrder } deriving (Eq, Show)
1338+data TermInclusion = TermInclusion Text
1339+ | TermPattern Text Text deriving (Eq, Show)
1341+data CollectionMode = BreadthFirst
1342+ | DepthFirst deriving (Eq, Show)
1344+data ExecutionHint = Ordinals
1346+ | GlobalOrdinalsHash
1347+ | GlobalOrdinalsLowCardinality
1348+ | Map deriving (Eq, Show)
1350+data TimeInterval = Weeks
1354+ | Seconds deriving (Eq)
1356+data Interval = Year
1364+ | FractionalInterval Float TimeInterval deriving (Eq, Show)
1366+data Aggregation = TermsAgg TermsAggregation
1367+ | DateHistogramAgg DateHistogramAggregation
1368+ | ValueCountAgg ValueCountAggregation
1369+ | FilterAgg FilterAggregation deriving (Eq, Show)
1372+data TermsAggregation = TermsAggregation { term :: Either Text Text
1373+ , termInclude :: Maybe TermInclusion
1374+ , termExclude :: Maybe TermInclusion
1375+ , termOrder :: Maybe TermOrder
1376+ , termMinDocCount :: Maybe Int
1377+ , termSize :: Maybe Int
1378+ , termShardSize :: Maybe Int
1379+ , termCollectMode :: Maybe CollectionMode
1380+ , termExecutionHint :: Maybe ExecutionHint
1381+ , termAggs :: Maybe Aggregations
1382+ } deriving (Eq, Show)
1384+data DateHistogramAggregation = DateHistogramAggregation { dateField :: FieldName
1385+ , dateInterval :: Interval
1386+ , dateFormat :: Maybe Text
1387+ -- pre and post deprecated in 1.5
1388+ , datePreZone :: Maybe Text
1389+ , datePostZone :: Maybe Text
1390+ , datePreOffset :: Maybe Text
1391+ , datePostOffset :: Maybe Text
1392+ , dateAggs :: Maybe Aggregations
1393+ } deriving (Eq, Show)
1395+-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html> for more information.
1396+data ValueCountAggregation = FieldValueCount FieldName
1397+ | ScriptValueCount Script deriving (Eq, Show)
1399+-- | 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.
1400+data FilterAggregation = FilterAggregation { faFilter :: Filter
1401+ , faAggs :: Maybe Aggregations} deriving (Eq, Show)
1403+mkTermsAggregation :: Text -> TermsAggregation
1404+mkTermsAggregation t = TermsAggregation (Left t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1406+mkTermsScriptAggregation :: Text -> TermsAggregation
1407+mkTermsScriptAggregation t = TermsAggregation (Right t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1409+mkDateHistogram :: FieldName -> Interval -> DateHistogramAggregation
1410+mkDateHistogram t i = DateHistogramAggregation t i Nothing Nothing Nothing Nothing Nothing Nothing
1412+instance ToJSON TermOrder where
1413+ toJSON (TermOrder termSortField termSortOrder) = object [termSortField .= termSortOrder]
1415+instance ToJSON TermInclusion where
1416+ toJSON (TermInclusion x) = toJSON x
1417+ toJSON (TermPattern pattern flags) = omitNulls [ "pattern" .= pattern,
1420+instance ToJSON CollectionMode where
1421+ toJSON BreadthFirst = "breadth_first"
1422+ toJSON DepthFirst = "depth_first"
1424+instance ToJSON ExecutionHint where
1425+ toJSON Ordinals = "ordinals"
1426+ toJSON GlobalOrdinals = "global_ordinals"
1427+ toJSON GlobalOrdinalsHash = "global_ordinals_hash"
1428+ toJSON GlobalOrdinalsLowCardinality = "global_ordinals_low_cardinality"
1431+instance ToJSON Interval where
1432+ toJSON Year = "year"
1433+ toJSON Quarter = "quarter"
1434+ toJSON Month = "month"
1435+ toJSON Week = "week"
1437+ toJSON Hour = "hour"
1438+ toJSON Minute = "minute"
1439+ toJSON Second = "second"
1440+ toJSON (FractionalInterval fraction interval) = toJSON $ show fraction ++ show interval
1442+instance Show TimeInterval where
1449+instance ToJSON Aggregation where
1450+ toJSON (TermsAgg (TermsAggregation term include exclude order minDocCount size shardSize collectMode executionHint termAggs)) =
1451+ omitNulls ["terms" .= omitNulls [ toJSON' term,
1452+ "include" .= include,
1453+ "exclude" .= exclude,
1455+ "min_doc_count" .= minDocCount,
1457+ "shard_size" .= shardSize,
1458+ "collect_mode" .= collectMode,
1459+ "execution_hint" .= executionHint
1461+ "aggs" .= termAggs ]
1463+ toJSON' x = case x of { Left y -> "field" .= y; Right y -> "script" .= y }
1465+ toJSON (DateHistogramAgg (DateHistogramAggregation field interval format preZone postZone preOffset postOffset dateHistoAggs)) =
1466+ omitNulls ["date_histogram" .= omitNulls [ "field" .= field,
1467+ "interval" .= interval,
1468+ "format" .= format,
1469+ "pre_zone" .= preZone,
1470+ "post_zone" .= postZone,
1471+ "pre_offset" .= preOffset,
1472+ "post_offset" .= postOffset
1474+ "aggs" .= dateHistoAggs ]
1475+ toJSON (ValueCountAgg a) = object ["value_count" .= v]
1476+ where v = case a of
1477+ (FieldValueCount (FieldName n)) -> object ["field" .= n]
1478+ (ScriptValueCount (Script s)) -> object ["script" .= s]
1479+ toJSON (FilterAgg (FilterAggregation filt ags)) =
1480+ omitNulls [ "filter" .= filt
1483+type AggregationResults = M.Map Text Value
1485+class BucketAggregation a where
1487+ docCount :: a -> Int
1488+ aggs :: a -> Maybe AggregationResults
1491+data Bucket a = Bucket { buckets :: [a]} deriving (Show)
1493+data TermsResult = TermsResult { termKey :: Text
1494+ , termsDocCount :: Int
1495+ , termsAggs :: Maybe AggregationResults } deriving (Show)
1497+data DateHistogramResult = DateHistogramResult { dateKey :: Int
1498+ , dateKeyStr :: Maybe Text
1499+ , dateDocCount :: Int
1500+ , dateHistogramAggs :: Maybe AggregationResults } deriving (Show)
1502+toTerms :: Text -> AggregationResults -> Maybe (Bucket TermsResult)
1503+toTerms t a = M.lookup t a >>= deserialize
1504+ where deserialize = parseMaybe parseJSON
1506+toDateHistogram :: Text -> AggregationResults -> Maybe (Bucket DateHistogramResult)
1507+toDateHistogram t a = M.lookup t a >>= deserialize
1508+ where deserialize = parseMaybe parseJSON
1510+instance BucketAggregation TermsResult where
1512+ docCount = termsDocCount
1515+instance BucketAggregation DateHistogramResult where
1516+ key = showText . dateKey
1517+ docCount = dateDocCount
1518+ aggs = dateHistogramAggs
1520+instance (FromJSON a, BucketAggregation a) => FromJSON (Bucket a) where
1521+ parseJSON (Object v) = Bucket <$>
1523+ parseJSON _ = mempty
1525+instance FromJSON TermsResult where
1526+ parseJSON (Object v) = TermsResult <$>
1528+ v .: "doc_count" <*>
1529+ v .:? "aggregations"
1530+ parseJSON _ = mempty
1532+instance FromJSON DateHistogramResult where
1533+ parseJSON (Object v) = DateHistogramResult <$>
1535+ v .:? "key_as_string" <*>
1536+ v .: "doc_count" <*>
1537+ v .:? "aggregations"
1538+ parseJSON _ = mempty
1540+instance Monoid Filter where
1541+ mempty = IdentityFilter
1542+ mappend a b = AndFilter [a, b] defaultCache
1544+instance Seminearring Filter where
1545+ a <||> b = OrFilter [a, b] defaultCache
1547+instance ToJSON Filter where
1548+ toJSON (AndFilter filters cache) =
1550+ object [ "filters" .= fmap toJSON filters
1551+ , "_cache" .= cache]]
1553+ toJSON (OrFilter filters cache) =
1555+ object [ "filters" .= fmap toJSON filters
1556+ , "_cache" .= cache]]
1558+ toJSON (NotFilter notFilter cache) =
1560+ object ["filter" .= notFilter
1561+ , "_cache" .= cache]]
1563+ toJSON (IdentityFilter) =
1564+ object ["match_all" .= object []]
1566+ toJSON (TermFilter (Term termFilterField termFilterValue) cache) =
1567+ object ["term" .= object base]
1568+ where base = [termFilterField .= termFilterValue,
1571+ toJSON (ExistsFilter (FieldName fieldName)) =
1572+ object ["exists" .= object
1573+ ["field" .= fieldName]]
1575+ toJSON (BoolFilter boolMatch) =
1576+ object ["bool" .= boolMatch]
1578+ toJSON (GeoBoundingBoxFilter bbConstraint) =
1579+ object ["geo_bounding_box" .= bbConstraint]
1581+ toJSON (GeoDistanceFilter (GeoPoint (FieldName distanceGeoField) geoDistLatLon)
1582+ distance distanceType optimizeBbox cache) =
1583+ object ["geo_distance" .=
1584+ object ["distance" .= distance
1585+ , "distance_type" .= distanceType
1586+ , "optimize_bbox" .= optimizeBbox
1587+ , distanceGeoField .= geoDistLatLon
1588+ , "_cache" .= cache]]
1590+ toJSON (GeoDistanceRangeFilter (GeoPoint (FieldName gddrField) drLatLon)
1591+ (DistanceRange geoDistRangeDistFrom drDistanceTo)) =
1592+ object ["geo_distance_range" .=
1593+ object ["from" .= geoDistRangeDistFrom
1594+ , "to" .= drDistanceTo
1595+ , gddrField .= drLatLon]]
1597+ toJSON (GeoPolygonFilter (FieldName geoPolygonFilterField) latLons) =
1598+ object ["geo_polygon" .=
1599+ object [geoPolygonFilterField .=
1600+ object ["points" .= fmap toJSON latLons]]]
1602+ toJSON (IdsFilter (MappingName mappingName) values) =
1604+ object ["type" .= mappingName
1605+ , "values" .= fmap unpackId values]]
1607+ toJSON (LimitFilter limit) =
1608+ object ["limit" .= object ["value" .= limit]]
1610+ toJSON (MissingFilter (FieldName fieldName) (Existence existence) (NullValue nullValue)) =
1611+ object ["missing" .=
1612+ object ["field" .= fieldName
1613+ , "existence" .= existence
1614+ , "null_value" .= nullValue]]
1616+ toJSON (PrefixFilter (FieldName fieldName) fieldValue cache) =
1617+ object ["prefix" .=
1618+ object [fieldName .= fieldValue
1619+ , "_cache" .= cache]]
1621+ toJSON (QueryFilter query False) =
1622+ object ["query" .= toJSON query ]
1623+ toJSON (QueryFilter query True) =
1624+ object ["fquery" .=
1625+ object [ "query" .= toJSON query
1626+ , "_cache" .= True ]]
1628+ toJSON (RangeFilter (FieldName fieldName) rangeValue rangeExecution cache) =
1630+ object [ fieldName .= object (rangeValueToPair rangeValue)
1631+ , "execution" .= rangeExecution
1632+ , "_cache" .= cache]]
1634+ toJSON (RegexpFilter (FieldName fieldName)
1635+ (Regexp regexText) flags (CacheName cacheName) cache (CacheKey cacheKey)) =
1636+ object ["regexp" .=
1637+ object [fieldName .=
1638+ object ["value" .= regexText
1639+ , "flags" .= flags]
1640+ , "_name" .= cacheName
1641+ , "_cache" .= cache
1642+ , "_cache_key" .= cacheKey]]
1644+instance ToJSON GeoPoint where
1645+ toJSON (GeoPoint (FieldName geoPointField) geoPointLatLon) =
1646+ object [ geoPointField .= geoPointLatLon ]
1649+instance ToJSON Query where
1650+ toJSON (TermQuery (Term termQueryField termQueryValue) boost) =
1652+ object [termQueryField .= object merged]]
1654+ base = [ "value" .= termQueryValue ]
1655+ boosted = maybe [] (return . ("boost" .=)) boost
1656+ merged = mappend base boosted
1658+ toJSON (TermsQuery terms) =
1659+ object [ "terms" .= object conjoined ]
1660+ where conjoined = [ getTermsField terms .=
1661+ fmap (toJSON . getTermValue) (toList terms)]
1662+ getTermsField ((Term f _ ) :| _) = f
1663+ getTermValue (Term _ v) = v
1664+ toJSON (IdsQuery idsQueryMappingName docIds) =
1665+ object [ "ids" .= object conjoined ]
1666+ where conjoined = [ "type" .= idsQueryMappingName
1667+ , "values" .= fmap toJSON docIds ]
1669+ toJSON (QueryQueryStringQuery qQueryStringQuery) =
1670+ object [ "query_string" .= qQueryStringQuery ]
1672+ toJSON (QueryMatchQuery matchQuery) =
1673+ object [ "match" .= matchQuery ]
1675+ toJSON (QueryMultiMatchQuery multiMatchQuery) =
1676+ toJSON multiMatchQuery
1678+ toJSON (QueryBoolQuery boolQuery) =
1679+ object [ "bool" .= boolQuery ]
1681+ toJSON (QueryBoostingQuery boostingQuery) =
1682+ object [ "boosting" .= boostingQuery ]
1684+ toJSON (QueryCommonTermsQuery commonTermsQuery) =
1685+ object [ "common" .= commonTermsQuery ]
1687+ toJSON (ConstantScoreFilter csFilter boost) =
1688+ object [ "constant_score" .= csFilter
1689+ , "boost" .= boost]
1691+ toJSON (ConstantScoreQuery query boost) =
1692+ object [ "constant_score" .= query
1693+ , "boost" .= boost]
1695+ toJSON (QueryDisMaxQuery disMaxQuery) =
1696+ object [ "dis_max" .= disMaxQuery ]
1698+ toJSON (QueryFilteredQuery qFilteredQuery) =
1699+ object [ "filtered" .= qFilteredQuery ]
1701+ toJSON (QueryFuzzyLikeThisQuery fuzzyQuery) =
1702+ object [ "fuzzy_like_this" .= fuzzyQuery ]
1704+ toJSON (QueryFuzzyLikeFieldQuery fuzzyFieldQuery) =
1705+ object [ "fuzzy_like_this_field" .= fuzzyFieldQuery ]
1707+ toJSON (QueryFuzzyQuery fuzzyQuery) =
1708+ object [ "fuzzy" .= fuzzyQuery ]
1710+ toJSON (QueryHasChildQuery childQuery) =
1711+ object [ "has_child" .= childQuery ]
1713+ toJSON (QueryHasParentQuery parentQuery) =
1714+ object [ "has_parent" .= parentQuery ]
1716+ toJSON (QueryIndicesQuery qIndicesQuery) =
1717+ object [ "indices" .= qIndicesQuery ]
1719+ toJSON (MatchAllQuery boost) =
1720+ object [ "match_all" .= omitNulls [ "boost" .= boost ] ]
1722+ toJSON (QueryMoreLikeThisQuery query) =
1723+ object [ "more_like_this" .= query ]
1725+ toJSON (QueryMoreLikeThisFieldQuery query) =
1726+ object [ "more_like_this_field" .= query ]
1728+ toJSON (QueryNestedQuery query) =
1729+ object [ "nested" .= query ]
1731+ toJSON (QueryPrefixQuery query) =
1732+ object [ "prefix" .= query ]
1734+ toJSON (QueryRangeQuery query) =
1735+ object [ "range" .= query ]
1737+ toJSON (QueryRegexpQuery query) =
1738+ object [ "regexp" .= query ]
1740+ toJSON (QuerySimpleQueryStringQuery query) =
1741+ object [ "simple_query_string" .= query ]
1744+omitNulls :: [(Text, Value)] -> Value
1745+omitNulls = object . filter notNull where
1746+ notNull (_, Null) = False
1747+ notNull (_, Array a) = (not . V.null) a
1751+instance ToJSON SimpleQueryStringQuery where
1752+ toJSON SimpleQueryStringQuery {..} =
1753+ omitNulls (base ++ maybeAdd)
1754+ where base = [ "query" .= simpleQueryStringQuery ]
1755+ maybeAdd = [ "fields" .= simpleQueryStringField
1756+ , "default_operator" .= simpleQueryStringOperator
1757+ , "analyzer" .= simpleQueryStringAnalyzer
1758+ , "flags" .= simpleQueryStringFlags
1759+ , "lowercase_expanded_terms" .= simpleQueryStringLowercaseExpanded
1760+ , "locale" .= simpleQueryStringLocale ]
1763+instance ToJSON FieldOrFields where
1764+ toJSON (FofField fieldName) =
1766+ toJSON (FofFields fieldNames) =
1769+instance ToJSON SimpleQueryFlag where
1770+ toJSON SimpleQueryAll = "ALL"
1771+ toJSON SimpleQueryNone = "NONE"
1772+ toJSON SimpleQueryAnd = "AND"
1773+ toJSON SimpleQueryOr = "OR"
1774+ toJSON SimpleQueryPrefix = "PREFIX"
1775+ toJSON SimpleQueryPhrase = "PHRASE"
1776+ toJSON SimpleQueryPrecedence = "PRECEDENCE"
1777+ toJSON SimpleQueryEscape = "ESCAPE"
1778+ toJSON SimpleQueryWhitespace = "WHITESPACE"
1779+ toJSON SimpleQueryFuzzy = "FUZZY"
1780+ toJSON SimpleQueryNear = "NEAR"
1781+ toJSON SimpleQuerySlop = "SLOP"
1784+instance ToJSON RegexpQuery where
1785+ toJSON (RegexpQuery (FieldName rqQueryField)
1786+ (Regexp regexpQueryQuery) rqQueryFlags
1788+ object [ rqQueryField .= omitNulls base ]
1789+ where base = [ "value" .= regexpQueryQuery
1790+ , "flags" .= rqQueryFlags
1791+ , "boost" .= rqQueryBoost ]
1794+instance ToJSON QueryStringQuery where
1795+ toJSON (QueryStringQuery qsQueryString
1796+ qsDefaultField qsOperator
1797+ qsAnalyzer qsAllowWildcard
1798+ qsLowercaseExpanded qsEnablePositionIncrements
1799+ qsFuzzyMaxExpansions qsFuzziness
1800+ qsFuzzyPrefixLength qsPhraseSlop
1801+ qsBoost qsAnalyzeWildcard
1802+ qsGeneratePhraseQueries qsMinimumShouldMatch
1803+ qsLenient qsLocale) =
1806+ base = [ "query" .= qsQueryString
1807+ , "default_field" .= qsDefaultField
1808+ , "default_operator" .= qsOperator
1809+ , "analyzer" .= qsAnalyzer
1810+ , "allow_leading_wildcard" .= qsAllowWildcard
1811+ , "lowercase_expanded_terms" .= qsLowercaseExpanded
1812+ , "enable_position_increments" .= qsEnablePositionIncrements
1813+ , "fuzzy_max_expansions" .= qsFuzzyMaxExpansions
1814+ , "fuzziness" .= qsFuzziness
1815+ , "fuzzy_prefix_length" .= qsFuzzyPrefixLength
1816+ , "phrase_slop" .= qsPhraseSlop
1817+ , "boost" .= qsBoost
1818+ , "analyze_wildcard" .= qsAnalyzeWildcard
1819+ , "auto_generate_phrase_queries" .= qsGeneratePhraseQueries
1820+ , "minimum_should_match" .= qsMinimumShouldMatch
1821+ , "lenient" .= qsLenient
1822+ , "locale" .= qsLocale ]
1825+instance ToJSON RangeQuery where
1826+ toJSON (RangeQuery (FieldName fieldName) range boost) =
1827+ object [ fieldName .= conjoined ]
1828+ where conjoined = [ "boost" .= boost ] ++ (rangeValueToPair range)
1831+instance ToJSON PrefixQuery where
1832+ toJSON (PrefixQuery (FieldName fieldName) queryValue boost) =
1833+ object [ fieldName .= omitNulls base ]
1834+ where base = [ "value" .= queryValue
1835+ , "boost" .= boost ]
1838+instance ToJSON NestedQuery where
1839+ toJSON (NestedQuery nqPath nqScoreType nqQuery) =
1840+ object [ "path" .= nqPath
1841+ , "score_mode" .= nqScoreType
1842+ , "query" .= nqQuery ]
1845+instance ToJSON MoreLikeThisFieldQuery where
1846+ toJSON (MoreLikeThisFieldQuery text (FieldName fieldName)
1847+ percent mtf mqt stopwords mindf maxdf
1848+ minwl maxwl boostTerms boost analyzer) =
1849+ object [ fieldName .= omitNulls base ]
1850+ where base = [ "like_text" .= text
1851+ , "percent_terms_to_match" .= percent
1852+ , "min_term_freq" .= mtf
1853+ , "max_query_terms" .= mqt
1854+ , "stop_words" .= stopwords
1855+ , "min_doc_freq" .= mindf
1856+ , "max_doc_freq" .= maxdf
1857+ , "min_word_length" .= minwl
1858+ , "max_word_length" .= maxwl
1859+ , "boost_terms" .= boostTerms
1861+ , "analyzer" .= analyzer ]
1864+instance ToJSON MoreLikeThisQuery where
1865+ toJSON (MoreLikeThisQuery text fields percent
1866+ mtf mqt stopwords mindf maxdf
1867+ minwl maxwl boostTerms boost analyzer) =
1869+ where base = [ "like_text" .= text
1870+ , "fields" .= fields
1871+ , "percent_terms_to_match" .= percent
1872+ , "min_term_freq" .= mtf
1873+ , "max_query_terms" .= mqt
1874+ , "stop_words" .= stopwords
1875+ , "min_doc_freq" .= mindf
1876+ , "max_doc_freq" .= maxdf
1877+ , "min_word_length" .= minwl
1878+ , "max_word_length" .= maxwl
1879+ , "boost_terms" .= boostTerms
1881+ , "analyzer" .= analyzer ]
1884+instance ToJSON IndicesQuery where
1885+ toJSON (IndicesQuery indices query noMatch) =
1886+ omitNulls [ "indices" .= indices
1887+ , "no_match_query" .= noMatch
1888+ , "query" .= query ]
1891+instance ToJSON HasParentQuery where
1892+ toJSON (HasParentQuery queryType query scoreType) =
1893+ omitNulls [ "parent_type" .= queryType
1894+ , "score_type" .= scoreType
1895+ , "query" .= query ]
1898+instance ToJSON HasChildQuery where
1899+ toJSON (HasChildQuery queryType query scoreType) =
1900+ omitNulls [ "query" .= query
1901+ , "score_type" .= scoreType
1902+ , "type" .= queryType ]
1905+instance ToJSON FuzzyQuery where
1906+ toJSON (FuzzyQuery (FieldName fieldName) queryText
1907+ prefixLength maxEx fuzziness boost) =
1908+ object [ fieldName .= omitNulls base ]
1909+ where base = [ "value" .= queryText
1910+ , "fuzziness" .= fuzziness
1911+ , "prefix_length" .= prefixLength
1913+ , "max_expansions" .= maxEx ]
1916+instance ToJSON FuzzyLikeFieldQuery where
1917+ toJSON (FuzzyLikeFieldQuery (FieldName fieldName)
1918+ fieldText maxTerms ignoreFreq fuzziness prefixLength
1920+ object [ fieldName .=
1921+ omitNulls [ "like_text" .= fieldText
1922+ , "max_query_terms" .= maxTerms
1923+ , "ignore_tf" .= ignoreFreq
1924+ , "fuzziness" .= fuzziness
1925+ , "prefix_length" .= prefixLength
1926+ , "analyzer" .= analyzer
1927+ , "boost" .= boost ]]
1930+instance ToJSON FuzzyLikeThisQuery where
1931+ toJSON (FuzzyLikeThisQuery fields text maxTerms
1932+ ignoreFreq fuzziness prefixLength boost analyzer) =
1934+ where base = [ "fields" .= fields
1935+ , "like_text" .= text
1936+ , "max_query_terms" .= maxTerms
1937+ , "ignore_tf" .= ignoreFreq
1938+ , "fuzziness" .= fuzziness
1939+ , "prefix_length" .= prefixLength
1940+ , "analyzer" .= analyzer
1941+ , "boost" .= boost ]
1944+instance ToJSON FilteredQuery where
1945+ toJSON (FilteredQuery query fFilter) =
1946+ object [ "query" .= query
1947+ , "filter" .= fFilter ]
1950+instance ToJSON DisMaxQuery where
1951+ toJSON (DisMaxQuery queries tiebreaker boost) =
1953+ where base = [ "queries" .= queries
1955+ , "tie_breaker" .= tiebreaker ]
1958+instance ToJSON CommonTermsQuery where
1959+ toJSON (CommonTermsQuery (FieldName fieldName)
1960+ (QueryString query) cf lfo hfo msm
1961+ boost analyzer disableCoord) =
1962+ object [fieldName .= omitNulls base ]
1963+ where base = [ "query" .= query
1964+ , "cutoff_frequency" .= cf
1965+ , "low_freq_operator" .= lfo
1966+ , "minimum_should_match" .= msm
1968+ , "analyzer" .= analyzer
1969+ , "disable_coord" .= disableCoord
1970+ , "high_freq_operator" .= hfo ]
1973+instance ToJSON CommonMinimumMatch where
1974+ toJSON (CommonMinimumMatch mm) = toJSON mm
1975+ toJSON (CommonMinimumMatchHighLow (MinimumMatchHighLow lowF highF)) =
1976+ object [ "low_freq" .= lowF
1977+ , "high_freq" .= highF ]
1979+instance ToJSON BoostingQuery where
1980+ toJSON (BoostingQuery bqPositiveQuery bqNegativeQuery bqNegativeBoost) =
1981+ object [ "positive" .= bqPositiveQuery
1982+ , "negative" .= bqNegativeQuery
1983+ , "negative_boost" .= bqNegativeBoost ]
1986+instance ToJSON BoolQuery where
1987+ toJSON (BoolQuery mustM notM shouldM bqMin boost disableCoord) =
1989+ where base = [ "must" .= mustM
1990+ , "must_not" .= notM
1991+ , "should" .= shouldM
1992+ , "minimum_should_match" .= bqMin
1994+ , "disable_coord" .= disableCoord ]
1997+instance ToJSON MatchQuery where
1998+ toJSON (MatchQuery (FieldName fieldName)
1999+ (QueryString mqQueryString) booleanOperator
2000+ zeroTermsQuery cutoffFrequency matchQueryType
2001+ analyzer maxExpansions lenient boost) =
2002+ object [ fieldName .= omitNulls base ]
2003+ where base = [ "query" .= mqQueryString
2004+ , "operator" .= booleanOperator
2005+ , "zero_terms_query" .= zeroTermsQuery
2006+ , "cutoff_frequency" .= cutoffFrequency
2007+ , "type" .= matchQueryType
2008+ , "analyzer" .= analyzer
2009+ , "max_expansions" .= maxExpansions
2010+ , "lenient" .= lenient
2011+ , "boost" .= boost ]
2014+instance ToJSON MultiMatchQuery where
2015+ toJSON (MultiMatchQuery fields (QueryString query) boolOp
2016+ ztQ tb mmqt cf analyzer maxEx lenient) =
2017+ object ["multi_match" .= omitNulls base]
2018+ where base = [ "fields" .= fmap toJSON fields
2020+ , "operator" .= boolOp
2021+ , "zero_terms_query" .= ztQ
2022+ , "tiebreaker" .= tb
2024+ , "cutoff_frequency" .= cf
2025+ , "analyzer" .= analyzer
2026+ , "max_expansions" .= maxEx
2027+ , "lenient" .= lenient ]
2030+instance ToJSON MultiMatchQueryType where
2031+ toJSON MultiMatchBestFields = "best_fields"
2032+ toJSON MultiMatchMostFields = "most_fields"
2033+ toJSON MultiMatchCrossFields = "cross_fields"
2034+ toJSON MultiMatchPhrase = "phrase"
2035+ toJSON MultiMatchPhrasePrefix = "phrase_prefix"
2037+instance ToJSON BooleanOperator where
2038+ toJSON And = String "and"
2039+ toJSON Or = String "or"
2041+instance ToJSON ZeroTermsQuery where
2042+ toJSON ZeroTermsNone = String "none"
2043+ toJSON ZeroTermsAll = String "all"
2045+instance ToJSON MatchQueryType where
2046+ toJSON MatchPhrase = "phrase"
2047+ toJSON MatchPhrasePrefix = "phrase_prefix"
2049+instance ToJSON FieldName where
2050+ toJSON (FieldName fieldName) = String fieldName
2052+instance ToJSON ReplicaCount
2053+instance ToJSON ShardCount
2054+instance ToJSON CutoffFrequency
2055+instance ToJSON Analyzer
2056+instance ToJSON MaxExpansions
2057+instance ToJSON Lenient
2058+instance ToJSON Boost
2059+instance ToJSON Version
2060+instance ToJSON Tiebreaker
2061+instance ToJSON MinimumMatch
2062+instance ToJSON DisableCoord
2063+instance ToJSON PrefixLength
2064+instance ToJSON Fuzziness
2065+instance ToJSON IgnoreTermFrequency
2066+instance ToJSON MaxQueryTerms
2067+instance ToJSON TypeName
2068+instance ToJSON IndexName
2069+instance ToJSON TemplateName
2070+instance ToJSON TemplatePattern
2071+instance ToJSON BoostTerms
2072+instance ToJSON MaxWordLength
2073+instance ToJSON MinWordLength
2074+instance ToJSON MaxDocFrequency
2075+instance ToJSON MinDocFrequency
2076+instance ToJSON PhraseSlop
2077+instance ToJSON StopWord
2078+instance ToJSON QueryPath
2079+instance ToJSON MinimumTermFrequency
2080+instance ToJSON PercentMatch
2081+instance ToJSON MappingName
2082+instance ToJSON DocId
2083+instance ToJSON QueryString
2084+instance ToJSON AllowLeadingWildcard
2085+instance ToJSON LowercaseExpanded
2086+instance ToJSON AnalyzeWildcard
2087+instance ToJSON GeneratePhraseQueries
2088+instance ToJSON Locale
2089+instance ToJSON EnablePositionIncrements
2090+instance FromJSON Version
2091+instance FromJSON IndexName
2092+instance FromJSON MappingName
2093+instance FromJSON DocId
2096+instance FromJSON Status where
2097+ parseJSON (Object v) = Status <$>
2103+ parseJSON _ = empty
2106+instance ToJSON IndexSettings where
2107+ toJSON (IndexSettings s r) = object ["settings" .=
2109+ object ["number_of_shards" .= s, "number_of_replicas" .= r]
2113+instance ToJSON IndexTemplate where
2114+ toJSON (IndexTemplate p s m) = merge
2115+ (object [ "template" .= p
2116+ , "mappings" .= foldl' merge (object []) m
2120+ merge (Object o1) (Object o2) = toJSON $ HM.union o1 o2
2122+ merge _ _ = undefined
2124+instance (FromJSON a) => FromJSON (EsResult a) where
2125+ parseJSON jsonVal@(Object v) = do
2126+ found <- v .:? "found" .!= False
2128+ then parseJSON jsonVal
2129+ else return Nothing
2130+ EsResult <$> v .: "_index" <*>
2134+ parseJSON _ = empty
2136+instance (FromJSON a) => FromJSON (EsResultFound a) where
2137+ parseJSON (Object v) = EsResultFound <$>
2138+ v .: "_version" <*>
2140+ parseJSON _ = empty
2142+instance FromJSON EsError where
2143+ parseJSON (Object v) = EsError <$>
2146+ parseJSON _ = empty
2148+instance ToJSON Search where
2149+ toJSON (Search query sFilter sort searchAggs highlight sTrackSortScores sFrom sSize _ sFields sSource) =
2150+ omitNulls [ "query" .= query
2151+ , "filter" .= sFilter
2153+ , "aggregations" .= searchAggs
2154+ , "highlight" .= highlight
2157+ , "track_scores" .= sTrackSortScores
2158+ , "fields" .= sFields
2159+ , "_source" .= sSource]
490instance ToJSON Source where
2162instance ToJSON Source where
491 toJSON NoSource = toJSON False
2163 toJSON NoSource = toJSON False
492 toJSON (SourcePatterns patterns) = toJSON patterns
2164 toJSON (SourcePatterns patterns) = toJSON patterns
493− toJSON (SourceIncludeExclude incl excl) = object [ "includes" .= incl, "excludes" .= excl ]
2165+ toJSON (SourceIncludeExclude incl excl) = object [ "include" .= incl, "exclude" .= excl ]
495−data PatternOrPatterns = PopPattern Pattern
496− | PopPatterns [Pattern] deriving (Eq, Read, Show)
498instance ToJSON PatternOrPatterns where
2167instance ToJSON PatternOrPatterns where
499 toJSON (PopPattern pattern) = toJSON pattern
2168 toJSON (PopPattern pattern) = toJSON pattern
500 toJSON (PopPatterns patterns) = toJSON patterns
2169 toJSON (PopPatterns patterns) = toJSON patterns
502−data Include = Include [Pattern] deriving (Eq, Read, Show)
503−data Exclude = Exclude [Pattern] deriving (Eq, Read, Show)
505instance ToJSON Include where
2171instance ToJSON Include where
506 toJSON (Include patterns) = toJSON patterns
2172 toJSON (Include patterns) = toJSON patterns
508instance ToJSON Exclude where
2174instance ToJSON Exclude where
509 toJSON (Exclude patterns) = toJSON patterns
2175 toJSON (Exclude patterns) = toJSON patterns
511−newtype Pattern = Pattern Text deriving (Eq, Read, Show)
513instance ToJSON Pattern where
2177instance ToJSON Pattern where
514 toJSON (Pattern pattern) = toJSON pattern
2178 toJSON (Pattern pattern) = toJSON pattern
516−data SearchResult a =
2180+
517− SearchResult { took :: Int
2181+instance ToJSON FieldHighlight where
518− , timedOut :: Bool
2182+ toJSON (FieldHighlight (FieldName fName) (Just fSettings)) =
519− , shards :: ShardResult
2183+ object [ fName .= fSettings ]
520− , searchHits :: SearchHits a
2184+ toJSON (FieldHighlight (FieldName fName) Nothing) =
521− , aggregations :: Maybe AggregationResults
2185+ object [ fName .= emptyObject ]
522− , scrollId :: Maybe ScrollId
2186+
523− -- ^ Only one Suggestion request / response per
2187+instance ToJSON Highlights where
524− -- Search is supported.
2188+ toJSON (Highlights global fields) =
525− , suggest :: Maybe NamedSuggestionResponse
2189+ omitNulls (("fields" .= fields)
526− }
2190+ : highlightSettingsPairs global)
527− deriving (Eq, Show)
2191+
2192+instance ToJSON HighlightSettings where
2193+ toJSON hs = omitNulls (highlightSettingsPairs (Just hs))
2195+highlightSettingsPairs :: Maybe HighlightSettings -> [Pair]
2196+highlightSettingsPairs Nothing = []
2197+highlightSettingsPairs (Just (Plain plh)) = plainHighPairs (Just plh)
2198+highlightSettingsPairs (Just (Postings ph)) = postHighPairs (Just ph)
2199+highlightSettingsPairs (Just (FastVector fvh)) = fastVectorHighPairs (Just fvh)
2202+plainHighPairs :: Maybe PlainHighlight -> [Pair]
2203+plainHighPairs Nothing = []
2204+plainHighPairs (Just (PlainHighlight plCom plNonPost)) =
2205+ [ "type" .= String "plain"]
2206+ ++ commonHighlightPairs plCom
2207+ ++ nonPostingsToPairs plNonPost
2209+postHighPairs :: Maybe PostingsHighlight -> [Pair]
2210+postHighPairs Nothing = []
2211+postHighPairs (Just (PostingsHighlight pCom)) =
2212+ ("type" .= String "postings")
2213+ : commonHighlightPairs pCom
2215+fastVectorHighPairs :: Maybe FastVectorHighlight -> [Pair]
2216+fastVectorHighPairs Nothing = []
2217+fastVectorHighPairs (Just
2218+ (FastVectorHighlight fvCom fvNonPostSettings fvBoundChars
2219+ fvBoundMaxScan fvFragOff fvMatchedFields
2221+ [ "type" .= String "fvh"
2222+ , "boundary_chars" .= fvBoundChars
2223+ , "boundary_max_scan" .= fvBoundMaxScan
2224+ , "fragment_offset" .= fvFragOff
2225+ , "matched_fields" .= fvMatchedFields
2226+ , "phraseLimit" .= fvPhraseLim]
2227+ ++ commonHighlightPairs fvCom
2228+ ++ nonPostingsToPairs fvNonPostSettings
2230+commonHighlightPairs :: Maybe CommonHighlight -> [Pair]
2231+commonHighlightPairs Nothing = []
2232+commonHighlightPairs (Just (CommonHighlight chScore chForceSource chTag chEncoder
2233+ chNoMatchSize chHighlightQuery
2234+ chRequireFieldMatch)) =
2235+ [ "order" .= chScore
2236+ , "force_source" .= chForceSource
2237+ , "encoder" .= chEncoder
2238+ , "no_match_size" .= chNoMatchSize
2239+ , "highlight_query" .= chHighlightQuery
2240+ , "require_fieldMatch" .= chRequireFieldMatch]
2241+ ++ highlightTagToPairs chTag
2244+nonPostingsToPairs :: Maybe NonPostings -> [Pair]
2245+nonPostingsToPairs Nothing = []
2246+nonPostingsToPairs (Just (NonPostings npFragSize npNumOfFrags)) =
2247+ [ "fragment_size" .= npFragSize
2248+ , "number_of_fragments" .= npNumOfFrags]
2252+instance ToJSON HighlightEncoder where
2253+ toJSON DefaultEncoder = String "default"
2254+ toJSON HTMLEncoder = String "html"
2256+highlightTagToPairs :: Maybe HighlightTag -> [Pair]
2257+highlightTagToPairs (Just (TagSchema _)) = [ "scheme" .= String "default"]
2258+highlightTagToPairs (Just (CustomTags (pre, post))) = [ "pre_tags" .= pre
2259+ , "post_tags" .= post]
2260+highlightTagToPairs Nothing = []
2262+instance ToJSON SortSpec where
2263+ toJSON (DefaultSortSpec
2264+ (DefaultSort (FieldName dsSortFieldName) dsSortOrder dsIgnoreUnmapped
2265+ dsSortMode dsMissingSort dsNestedFilter)) =
2266+ object [dsSortFieldName .= omitNulls base] where
2267+ base = [ "order" .= dsSortOrder
2268+ , "ignore_unmapped" .= dsIgnoreUnmapped
2269+ , "mode" .= dsSortMode
2270+ , "missing" .= dsMissingSort
2271+ , "nested_filter" .= dsNestedFilter ]
2273+ toJSON (GeoDistanceSortSpec gdsSortOrder (GeoPoint (FieldName field) gdsLatLon) units) =
2274+ object [ "unit" .= units
2275+ , field .= gdsLatLon
2276+ , "order" .= gdsSortOrder ]
2279+instance ToJSON SortOrder where
2280+ toJSON Ascending = String "asc"
2281+ toJSON Descending = String "desc"
2284+instance ToJSON SortMode where
2285+ toJSON SortMin = String "min"
2286+ toJSON SortMax = String "max"
2287+ toJSON SortSum = String "sum"
2288+ toJSON SortAvg = String "avg"
2291+instance ToJSON Missing where
2292+ toJSON LastMissing = String "_last"
2293+ toJSON FirstMissing = String "_first"
2294+ toJSON (CustomMissing txt) = String txt
2297+instance ToJSON ScoreType where
2298+ toJSON ScoreTypeMax = "max"
2299+ toJSON ScoreTypeAvg = "avg"
2300+ toJSON ScoreTypeSum = "sum"
2301+ toJSON ScoreTypeNone = "none"
2304+instance ToJSON Distance where
2305+ toJSON (Distance dCoefficient dUnit) =
2306+ String boltedTogether where
2307+ coefText = showText dCoefficient
2308+ (String unitText) = toJSON dUnit
2309+ boltedTogether = mappend coefText unitText
2312+instance ToJSON DistanceUnit where
2313+ toJSON Miles = String "mi"
2314+ toJSON Yards = String "yd"
2315+ toJSON Feet = String "ft"
2316+ toJSON Inches = String "in"
2317+ toJSON Kilometers = String "km"
2318+ toJSON Meters = String "m"
2319+ toJSON Centimeters = String "cm"
2320+ toJSON Millimeters = String "mm"
2321+ toJSON NauticalMiles = String "nmi"
2324+instance ToJSON DistanceType where
2325+ toJSON Arc = String "arc"
2326+ toJSON SloppyArc = String "sloppy_arc"
2327+ toJSON Plane = String "plane"
2330+instance ToJSON OptimizeBbox where
2331+ toJSON NoOptimizeBbox = String "none"
2332+ toJSON (OptimizeGeoFilterType gft) = toJSON gft
2335+instance ToJSON GeoBoundingBoxConstraint where
2336+ toJSON (GeoBoundingBoxConstraint
2337+ (FieldName gbbcGeoBBField) gbbcConstraintBox cache type') =
2338+ object [gbbcGeoBBField .= gbbcConstraintBox
2339+ , "_cache" .= cache
2343+instance ToJSON GeoFilterType where
2344+ toJSON GeoFilterMemory = String "memory"
2345+ toJSON GeoFilterIndexed = String "indexed"
2348+instance ToJSON GeoBoundingBox where
2349+ toJSON (GeoBoundingBox gbbTopLeft gbbBottomRight) =
2350+ object ["top_left" .= gbbTopLeft
2351+ , "bottom_right" .= gbbBottomRight]
2354+instance ToJSON LatLon where
2355+ toJSON (LatLon lLat lLon) =
2356+ object ["lat" .= lLat
2360+-- index for smaller ranges, fielddata for longer ranges
2361+instance ToJSON RangeExecution where
2362+ toJSON RangeExecutionIndex = "index"
2363+ toJSON RangeExecutionFielddata = "fielddata"
2366+instance ToJSON RegexpFlags where
2367+ toJSON AllRegexpFlags = String "ALL"
2368+ toJSON NoRegexpFlags = String "NONE"
2369+ toJSON (SomeRegexpFlags (h :| fs)) = String $ T.intercalate "|" flagStrs
2370+ where flagStrs = map flagStr . nub $ h:fs
2371+ flagStr AnyString = "ANYSTRING"
2372+ flagStr Automaton = "AUTOMATON"
2373+ flagStr Complement = "COMPLEMENT"
2374+ flagStr Empty = "EMPTY"
2375+ flagStr Intersection = "INTERSECTION"
2376+ flagStr Interval = "INTERVAL"
2378+instance ToJSON Term where
2379+ toJSON (Term field value) = object ["term" .= object
2383+instance ToJSON BoolMatch where
2384+ toJSON (MustMatch term cache) = object ["must" .= term,
2386+ toJSON (MustNotMatch term cache) = object ["must_not" .= term,
2388+ toJSON (ShouldMatch terms cache) = object ["should" .= fmap toJSON terms,
529instance (FromJSON a) => FromJSON (SearchResult a) where
2392instance (FromJSON a) => FromJSON (SearchResult a) where
530 parseJSON (Object v) = SearchResult <$>
2393 parseJSON (Object v) = SearchResult <$>
@@ -533,10 +2396,52 @@ instance (FromJSON a) => FromJSON (SearchResult a) where
533 v .: "_shards" <*>
2396 v .: "_shards" <*>
534 v .: "hits" <*>
2397 v .: "hits" <*>
535 v .:? "aggregations" <*>
2398 v .:? "aggregations" <*>
536− v .:? "_scroll_id" <*>
2399+ v .:? "_scroll_id"
537− v .:? "suggest"
2400+ parseJSON _ = empty
2402+instance (FromJSON a) => FromJSON (SearchHits a) where
2403+ parseJSON (Object v) = SearchHits <$>
2405+ v .: "max_score" <*>
538 parseJSON _ = empty
2407 parseJSON _ = empty
540−newtype ScrollId =
2409+instance (FromJSON a) => FromJSON (Hit a) where
541− ScrollId Text
2410+ parseJSON (Object v) = Hit <$>
542− deriving (Eq, Show, Ord, ToJSON, FromJSON)
2411+ v .: "_index" <*>
2415+ v .:? "_source" <*>
2417+ parseJSON _ = empty
2419+instance FromJSON ShardResult where
2420+ parseJSON (Object v) = ShardResult <$>
2422+ v .: "successful" <*>
2424+ parseJSON _ = empty
2427+instance FromJSON DocVersion where
2430+ maybe (fail "DocVersion out of range") return $ mkDocVersion i
2432+instance Bounded DocVersion where
2433+ minBound = DocVersion 1
2434+ maxBound = DocVersion 9200000000000000000 -- 9.2e+18
2436+instance Enum DocVersion where
2438+ | x /= maxBound = DocVersion (succ $ docVersionNumber x)
2439+ | otherwise = succError "DocVersion"
2441+ | x /= minBound = DocVersion (pred $ docVersionNumber x)
2442+ | otherwise = predError "DocVersion"
2444+ fromMaybe (error $ show i ++ " out of DocVersion range") $ mkDocVersion i
2445+ fromEnum = docVersionNumber
2446+ enumFrom = boundedEnumFrom
2447+ enumFromThen = boundedEnumFromThen