@@ -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,25 @@ 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(..)
91− , EsProtocolException(..)
94− , IndexAliasAction(..)
95− , IndexAliasCreate(..)
96− , IndexAliasSummary(..)
97− , IndexAliasesSummary(..)
99− , SearchAliasRouting(..)
100− , IndexAliasRouting(..)
102 , DocVersion
64 , DocVersion
103 , ExternalDocVersion(..)
65 , ExternalDocVersion(..)
104 , VersionControl(..)
66 , VersionControl(..)
@@ -108,20 +70,15 @@ module Database.Bloodhound.Types
108 , Search(..)
70 , Search(..)
109 , SearchType(..)
71 , SearchType(..)
110 , SearchResult(..)
72 , SearchResult(..)
111− , ScrollId(..)
73+ , ScrollId
112 , SearchHits(..)
74 , SearchHits(..)
113 , TrackSortScores
75 , TrackSortScores
114 , From(..)
76 , From(..)
115 , Size(..)
77 , Size(..)
117− , PatternOrPatterns(..)
121 , ShardResult(..)
78 , ShardResult(..)
122 , Hit(..)
79 , Hit(..)
124 , Filter(..)
80 , Filter(..)
125 , BoolMatch(..)
82 , BoolMatch(..)
126 , Term(..)
83 , Term(..)
127 , GeoPoint(..)
84 , GeoPoint(..)
@@ -148,22 +105,8 @@ module Database.Bloodhound.Types
148 , RegexpFlags(..)
105 , RegexpFlags(..)
149 , RegexpFlag(..)
106 , RegexpFlag(..)
150 , FieldName(..)
107 , FieldName(..)
154 , Script(..)
108 , Script(..)
155− , ScriptLanguage(..)
161 , IndexName(..)
109 , IndexName(..)
162− , IndexSelection(..)
165− , ForceMergeIndexSettings(..)
166− , defaultForceMergeIndexSettings
167 , TemplateName(..)
110 , TemplateName(..)
168 , TemplatePattern(..)
111 , TemplatePattern(..)
169 , MappingName(..)
112 , MappingName(..)
@@ -187,19 +130,8 @@ module Database.Bloodhound.Types
187 , BoolQuery(..)
130 , BoolQuery(..)
188 , BoostingQuery(..)
131 , BoostingQuery(..)
189 , CommonTermsQuery(..)
132 , CommonTermsQuery(..)
190− , FunctionScoreQuery(..)
193− , FunctionScoreFunctions(..)
194− , ComponentFunctionScoreFunction(..)
195− , FunctionScoreFunction(..)
198− , FieldValueFactor(..)
200− , FactorModifier(..)
201− , FactorMissingFieldValue(..)
202 , DisMaxQuery(..)
133 , DisMaxQuery(..)
203 , FuzzyLikeThisQuery(..)
135 , FuzzyLikeThisQuery(..)
204 , FuzzyLikeFieldQuery(..)
136 , FuzzyLikeFieldQuery(..)
205 , FuzzyQuery(..)
137 , FuzzyQuery(..)
@@ -215,16 +147,10 @@ module Database.Bloodhound.Types
215 , RangeQuery(..)
147 , RangeQuery(..)
216 , RegexpQuery(..)
148 , RegexpQuery(..)
217 , QueryString(..)
149 , QueryString(..)
218− , TemplateQueryInline(..)
219− , TemplateQueryKeyValuePairs(..)
221 , BooleanOperator(..)
150 , BooleanOperator(..)
222 , ZeroTermsQuery(..)
151 , ZeroTermsQuery(..)
223 , CutoffFrequency(..)
152 , CutoffFrequency(..)
224 , Analyzer(..)
153 , Analyzer(..)
228 , MaxExpansions(..)
154 , MaxExpansions(..)
229 , Lenient(..)
155 , Lenient(..)
230 , MatchQueryType(..)
156 , MatchQueryType(..)
@@ -271,118 +197,16 @@ module Database.Bloodhound.Types
271 , CollectionMode(..)
197 , CollectionMode(..)
272 , TermOrder(..)
198 , TermOrder(..)
273 , TermInclusion(..)
199 , 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(..)
201 , Aggregation(..)
365 , Aggregations
202 , Aggregations
366 , AggregationResults
203 , AggregationResults
368 , Bucket(..)
204 , Bucket(..)
369 , BucketAggregation(..)
205 , BucketAggregation(..)
370 , TermsAggregation(..)
206 , TermsAggregation(..)
371− , MissingAggregation(..)
372 , ValueCountAggregation(..)
207 , ValueCountAggregation(..)
373 , FilterAggregation(..)
208 , FilterAggregation(..)
374− , CardinalityAggregation(..)
375− , MaxAggregation(..)
376 , DateHistogramAggregation(..)
209 , DateHistogramAggregation(..)
377− , DateRangeAggregation(..)
378− , DateRangeAggRange(..)
380− , DateMathAnchor(..)
381− , DateMathModifier(..)
383− , TopHitsAggregation(..)
384− , StatisticsAggregation(..)
387 , Highlights(..)
211 , Highlights(..)
388 , FieldHighlight(..)
212 , FieldHighlight(..)
@@ -396,36 +220,501 @@ module Database.Bloodhound.Types
396 , HighlightTag(..)
220 , HighlightTag(..)
397 , HitHighlight
221 , HitHighlight
400 , TermsResult(..)
223 , TermsResult(..)
401 , DateHistogramResult(..)
224 , DateHistogramResult(..)
402− , DateRangeResult(..)
225+ ) where
403− , TopHitResult(..)
226+
404−
227+import Control.Applicative
405− , EsUsername(..)
228+import Control.Monad.Error
406− , EsPassword(..)
229+import Control.Monad.Reader
407−
230+import Control.Monad.State
408− , Analysis(..)
231+import Control.Monad.Writer
409− , AnalyzerDefinition(..)
232+import Data.Aeson
410− , TokenizerDefinition(..)
233+import Data.Aeson.Types (Pair, emptyObject, parseMaybe)
411− , TokenFilterDefinition(..)
234+import qualified Data.ByteString.Lazy.Char8 as L
412− , CharFilterDefinition(..)
235+import Data.List (nub, foldl')
413− , Ngram(..)
236+import Data.List.NonEmpty (NonEmpty (..), toList)
414− , TokenChar(..)
237+import qualified Data.HashMap.Strict as HM (union)
415− , Shingle(..)
238+import qualified Data.Map.Strict as M
416− , Language(..)
239+import Data.Maybe
417− ) where
240+import Data.Text (Text)
418−
241+import qualified Data.Text as T
419−import Bloodhound.Import
242+import Data.Time.Clock (UTCTime)
420−
243+import qualified Data.Vector as V
421−import Database.Bloodhound.Internal.Aggregation
244+import GHC.Enum
422−import Database.Bloodhound.Internal.Analysis
245+import GHC.Generics (Generic)
423−import Database.Bloodhound.Internal.Client
246+import Network.HTTP.Client
424−import Database.Bloodhound.Internal.Highlight
247+import qualified Network.HTTP.Types.Method as NHTM
425−import Database.Bloodhound.Internal.Newtypes
248+
426−import Database.Bloodhound.Internal.Query
249+import Database.Bloodhound.Types.Class
427−import Database.Bloodhound.Internal.Sort
250+
428−import Database.Bloodhound.Internal.Suggest
251+-- $setup
252+-- >>> :set -XOverloadedStrings
253+-- >>> import Database.Bloodhound
254+-- >>> let testServer = (Server "http://localhost:9200")
255+-- >>> let testIndex = IndexName "twitter"
256+-- >>> let testMapping = MappingName "tweet"
257+-- >>> let defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
259+-- defaultIndexSettings is exported by Database.Bloodhound as well
260+-- no trailing slashes in servers, library handles building the path.
262+{-| Common environment for Elasticsearch calls. Connections will be
263+ pipelined according to the provided HTTP connection manager.
265+data BHEnv = BHEnv { bhServer :: Server
266+ , bhManager :: Manager
269+{-| All API calls to Elasticsearch operate within
270+ MonadBH. The idea is that it can be easily embedded in your
271+ own monad transformer stack. A default instance for a ReaderT and
272+ alias 'BH' is provided for the simple case.
274+class (Functor m, Applicative m, MonadIO m) => MonadBH m where
277+newtype BH m a = BH {
278+ unBH :: ReaderT BHEnv m a
279+ } deriving ( Functor
290+instance MonadTrans BH where
293+instance (MonadReader r m) => MonadReader r (BH m) where
295+ local f (BH (ReaderT m)) = BH $ ReaderT $ \r ->
298+instance (Functor m, Applicative m, MonadIO m) => MonadBH (BH m) where
299+ getBHEnv = BH getBHEnv
302+instance (Functor m, Applicative m, MonadIO m) => MonadBH (ReaderT BHEnv m) where
305+runBH :: BHEnv -> BH m a -> m a
306+runBH e f = runReaderT (unBH f) e
308+{-| 'Version' is embedded in 'Status' -}
309+data Version = Version { number :: Text
310+ , build_hash :: Text
311+ , build_timestamp :: UTCTime
312+ , build_snapshot :: Bool
313+ , lucene_version :: Text } deriving (Eq, Show, Generic)
315+{-| 'Status' is a data type for describing the JSON body returned by
316+ Elasticsearch when you query its status. This was deprecated in 1.2.0.
318+ <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-status.html#indices-status>
321+data Status = Status { ok :: Maybe Bool
324+ , version :: Version
325+ , tagline :: Text } deriving (Eq, Show)
327+{-| 'IndexSettings' is used to configure the shards and replicas when you create
328+ an Elasticsearch Index.
330+ <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html>
334+ IndexSettings { indexShards :: ShardCount
335+ , indexReplicas :: ReplicaCount } deriving (Eq, Show)
337+{-| 'defaultIndexSettings' is an 'IndexSettings' with 3 shards and 2 replicas. -}
338+defaultIndexSettings :: IndexSettings
339+defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
341+{-| 'Reply' and 'Method' are type synonyms from 'Network.HTTP.Types.Method.Method' -}
342+type Reply = Network.HTTP.Client.Response L.ByteString
343+type Method = NHTM.Method
345+{-| 'OpenCloseIndex' is a sum type for opening and closing indices.
347+ <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-open-close.html>
349+data OpenCloseIndex = OpenIndex | CloseIndex deriving (Eq, Show)
351+data FieldType = GeoPointType
357+ | ByteType deriving (Eq, Show)
359+data FieldDefinition =
360+ FieldDefinition { fieldType :: FieldType } deriving (Eq, Show)
362+{-| An 'IndexTemplate' defines a template that will automatically be
363+ applied to new indices created. The templates include both
364+ 'IndexSettings' and mappings, and a simple 'TemplatePattern' that
365+ controls if the template will be applied to the index created.
366+ Specify mappings as follows: @[toJSON TweetMapping, ...]@
368+ https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-templates.html
371+ IndexTemplate { templatePattern :: TemplatePattern
372+ , templateSettings :: Maybe IndexSettings
373+ , templateMappings :: [Value]
377+ MappingField { mappingFieldName :: FieldName
378+ , fieldDefinition :: FieldDefinition } deriving (Eq, Show)
380+{-| Support for type reification of 'Mapping's is currently incomplete, for
381+ now the mapping API verbiage expects a 'ToJSON'able blob.
383+ Indexes have mappings, mappings are schemas for the documents contained in the
384+ index. I'd recommend having only one mapping per index, always having a mapping,
385+ and keeping different kinds of documents separated if possible.
387+data Mapping = Mapping { typeName :: TypeName
388+ , mappingFields :: [MappingField] } deriving (Eq, Show)
390+{-| 'BulkOperation' is a sum type for expressing the four kinds of bulk
391+ operation index, create, delete, and update. 'BulkIndex' behaves like an
392+ "upsert", 'BulkCreate' will fail if a document already exists at the DocId.
394+ <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-bulk.html#docs-bulk>
397+ BulkIndex IndexName MappingName DocId Value
398+ | BulkCreate IndexName MappingName DocId Value
399+ | BulkDelete IndexName MappingName DocId
400+ | BulkUpdate IndexName MappingName DocId Value deriving (Eq, Show)
402+{-| 'EsResult' describes the standard wrapper JSON document that you see in
403+ successful Elasticsearch lookups or lookups that couldn't find the document.
405+data EsResult a = EsResult { _index :: Text
408+ , foundResult :: Maybe (EsResultFound a)} deriving (Eq, Show)
411+{-| 'EsResultFound' contains the document and its metadata inside of an
412+ 'EsResult' when the document was successfully found.
414+data EsResultFound a = EsResultFound { _version :: DocVersion
415+ , _source :: a } deriving (Eq, Show)
419+{-| 'DocVersion' is an integer version number for a document between 1
420+and 9.2e+18 used for <<https://www.elastic.co/guide/en/elasticsearch/guide/current/optimistic-concurrency-control.html optimistic concurrency control>>.
422+newtype DocVersion = DocVersion {
423+ docVersionNumber :: Int
424+ } deriving (Eq, Show, Ord, ToJSON)
426+-- | Smart constructor for in-range doc version
427+mkDocVersion :: Int -> Maybe DocVersion
429+ | i >= (docVersionNumber minBound) && i <= (docVersionNumber maxBound) =
431+ | otherwise = Nothing
434+{-| 'ExternalDocVersion' is a convenience wrapper if your code uses its
435+own version numbers instead of ones from ES.
437+newtype ExternalDocVersion = ExternalDocVersion DocVersion
438+ deriving (Eq, Show, Ord, Bounded, Enum, ToJSON)
440+{-| 'VersionControl' is specified when indexing documents as a
441+optimistic concurrency control.
443+data VersionControl = NoVersionControl
444+ -- ^ Don't send a version. This is a pure overwrite.
445+ | InternalVersion DocVersion
446+ -- ^ Use the default ES versioning scheme. Only
447+ -- index the document if the version is the same
448+ -- as the one specified. Only applicable to
449+ -- updates, as you should be getting Version from
451+ | ExternalGT ExternalDocVersion
452+ -- ^ Use your own version numbering. Only index
453+ -- the document if the version is strictly higher
454+ -- OR the document doesn't exist. The given
455+ -- version will be used as the new version number
456+ -- for the stored document. N.B. All updates must
457+ -- increment this number, meaning there is some
458+ -- global, external ordering of updates.
459+ | ExternalGTE ExternalDocVersion
460+ -- ^ Use your own version numbering. Only index
461+ -- the document if the version is equal or higher
462+ -- than the stored version. Will succeed if there
463+ -- is no existing document. The given version will
464+ -- be used as the new version number for the
465+ -- stored document. Use with care, as this could
466+ -- result in data loss.
467+ | ForceVersion ExternalDocVersion
468+ -- ^ The document will always be indexed and the
469+ -- given version will be the new version. This is
470+ -- typically used for correcting errors. Use with
471+ -- care, as this could result in data loss.
472+ deriving (Show, Eq, Ord)
474+{-| 'DocumentParent' is used to specify a parent document.
476+newtype DocumentParent = DocumentParent DocId
479+{-| 'IndexDocumentSettings' are special settings supplied when indexing
480+a document. For the best backwards compatiblity when new fields are
481+added, you should probably prefer to start with 'defaultIndexDocumentSettings'
483+data IndexDocumentSettings =
484+ IndexDocumentSettings { idsVersionControl :: VersionControl
485+ , idsParent :: Maybe DocumentParent
486+ } deriving (Eq, Show)
488+{-| Reasonable default settings. Chooses no version control and no parent.
490+defaultIndexDocumentSettings :: IndexDocumentSettings
491+defaultIndexDocumentSettings = IndexDocumentSettings NoVersionControl Nothing
493+{-| 'Sort' is a synonym for a list of 'SortSpec's. Sort behavior is order
494+ dependent with later sorts acting as tie-breakers for earlier sorts.
496+type Sort = [SortSpec]
498+{-| The two main kinds of 'SortSpec' are 'DefaultSortSpec' and
499+ 'GeoDistanceSortSpec'. The latter takes a 'SortOrder', 'GeoPoint', and
500+ 'DistanceUnit' to express "nearness" to a single geographical point as a
503+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
505+data SortSpec = DefaultSortSpec DefaultSort
506+ | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit deriving (Eq, Show)
508+{-| 'DefaultSort' is usually the kind of 'SortSpec' you'll want. There's a
509+ 'mkSort' convenience function for when you want to specify only the most
512+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
515+ DefaultSort { sortFieldName :: FieldName
516+ , sortOrder :: SortOrder
518+ , ignoreUnmapped :: Bool
519+ , sortMode :: Maybe SortMode
520+ , missingSort :: Maybe Missing
521+ , nestedFilter :: Maybe Filter } deriving (Eq, Show)
523+{-| 'SortOrder' is 'Ascending' or 'Descending', as you might expect. These get
524+ encoded into "asc" or "desc" when turned into JSON.
526+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
528+data SortOrder = Ascending
529+ | Descending deriving (Eq, Show)
531+{-| 'Missing' prescribes how to handle missing fields. A missing field can be
532+ sorted last, first, or using a custom value as a substitute.
534+<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_missing_values>
536+data Missing = LastMissing
538+ | CustomMissing Text deriving (Eq, Show)
540+{-| 'SortMode' prescribes how to handle sorting array/multi-valued fields.
542+http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_sort_mode_option
544+data SortMode = SortMin
547+ | SortAvg deriving (Eq, Show)
549+{-| 'mkSort' defaults everything but the 'FieldName' and the 'SortOrder' so
550+ that you can concisely describe the usual kind of 'SortSpec's you want.
552+mkSort :: FieldName -> SortOrder -> DefaultSort
553+mkSort fieldName sOrder = DefaultSort fieldName sOrder False Nothing Nothing Nothing
555+{-| 'Cache' is for telling ES whether it should cache a 'Filter' not.
556+ 'Query's cannot be cached.
558+type Cache = Bool -- caching on/off
559+defaultCache :: Cache
562+{-| 'PrefixValue' is used in 'PrefixQuery' as the main query component.
564+type PrefixValue = Text
566+{-| 'BooleanOperator' is the usual And/Or operators with an ES compatible
567+ JSON encoding baked in. Used all over the place.
569+data BooleanOperator = And | Or deriving (Eq, Show)
571+{-| 'ShardCount' is part of 'IndexSettings'
573+newtype ShardCount = ShardCount Int deriving (Eq, Show, Generic)
575+{-| 'ReplicaCount' is part of 'IndexSettings'
577+newtype ReplicaCount = ReplicaCount Int deriving (Eq, Show, Generic)
579+{-| 'Server' is used with the client functions to point at the ES instance
581+newtype Server = Server Text deriving (Eq, Show)
583+{-| 'IndexName' is used to describe which index to query/create/delete
585+newtype IndexName = IndexName Text deriving (Eq, Generic, Show)
587+{-| 'TemplateName' is used to describe which template to query/create/delete
589+newtype TemplateName = TemplateName Text deriving (Eq, Show, Generic)
591+{-| 'TemplatePattern' represents a pattern which is matched against index names
593+newtype TemplatePattern = TemplatePattern Text deriving (Eq, Show, Generic)
595+{-| 'MappingName' is part of mappings which are how ES describes and schematizes
596+ the data in the indices.
598+newtype MappingName = MappingName Text deriving (Eq, Generic, Show)
600+{-| 'DocId' is a generic wrapper value for expressing unique Document IDs.
601+ Can be set by the user or created by ES itself. Often used in client
602+ functions for poking at specific documents.
604+newtype DocId = DocId Text deriving (Eq, Generic, Show)
606+{-| 'QueryString' is used to wrap query text bodies, be they human written or not.
608+newtype QueryString = QueryString Text deriving (Eq, Generic, Show)
610+{-| 'FieldName' is used all over the place wherever a specific field within
611+ a document needs to be specified, usually in 'Query's or 'Filter's.
613+newtype FieldName = FieldName Text deriving (Eq, Show)
616+{-| 'Script' is often used in place of 'FieldName' to specify more
617+complex ways of extracting a value from a document.
619+newtype Script = Script { scriptText :: Text } deriving (Eq, Show)
621+{-| 'CacheName' is used in 'RegexpFilter' for describing the
622+ 'CacheKey' keyed caching behavior.
624+newtype CacheName = CacheName Text deriving (Eq, Show)
626+{-| 'CacheKey' is used in 'RegexpFilter' to key regex caching.
629+ CacheKey Text deriving (Eq, Show)
631+ Existence Bool deriving (Eq, Show)
633+ NullValue Bool deriving (Eq, Show)
634+newtype CutoffFrequency =
635+ CutoffFrequency Double deriving (Eq, Show, Generic)
637+ Analyzer Text deriving (Eq, Show, Generic)
638+newtype MaxExpansions =
639+ MaxExpansions Int deriving (Eq, Show, Generic)
641+{-| 'Lenient', if set to true, will cause format based failures to be
642+ ignored. I don't know what the bloody default is, Elasticsearch
643+ documentation didn't say what it was. Let me know if you figure it out.
646+ Lenient Bool deriving (Eq, Show, Generic)
648+ Tiebreaker Double deriving (Eq, Show, Generic)
650+ Boost Double deriving (Eq, Show, Generic)
652+ BoostTerms Double deriving (Eq, Show, Generic)
654+{-| 'MinimumMatch' controls how many should clauses in the bool query should
655+ match. Can be an absolute value (2) or a percentage (30%) or a
656+ combination of both.
658+newtype MinimumMatch =
659+ MinimumMatch Int deriving (Eq, Show, Generic)
660+newtype MinimumMatchText =
661+ MinimumMatchText Text deriving (Eq, Show)
662+newtype DisableCoord =
663+ DisableCoord Bool deriving (Eq, Show, Generic)
664+newtype IgnoreTermFrequency =
665+ IgnoreTermFrequency Bool deriving (Eq, Show, Generic)
666+newtype MinimumTermFrequency =
667+ MinimumTermFrequency Int deriving (Eq, Show, Generic)
668+newtype MaxQueryTerms =
669+ MaxQueryTerms Int deriving (Eq, Show, Generic)
671+ Fuzziness Double deriving (Eq, Show, Generic)
673+{-| 'PrefixLength' is the prefix length used in queries, defaults to 0. -}
674+newtype PrefixLength =
675+ PrefixLength Int deriving (Eq, Show, Generic)
677+ TypeName Text deriving (Eq, Show, Generic)
678+newtype PercentMatch =
679+ PercentMatch Double deriving (Eq, Show, Generic)
681+ StopWord Text deriving (Eq, Show, Generic)
683+ QueryPath Text deriving (Eq, Show, Generic)
685+{-| Allowing a wildcard at the beginning of a word (eg "*ing") is particularly
686+ heavy, because all terms in the index need to be examined, just in case
687+ they match. Leading wildcards can be disabled by setting
688+ 'AllowLeadingWildcard' to false. -}
689+newtype AllowLeadingWildcard =
690+ AllowLeadingWildcard Bool deriving (Eq, Show, Generic)
691+newtype LowercaseExpanded =
692+ LowercaseExpanded Bool deriving (Eq, Show, Generic)
693+newtype EnablePositionIncrements =
694+ EnablePositionIncrements Bool deriving (Eq, Show, Generic)
696+{-| By default, wildcard terms in a query are not analyzed.
697+ Setting 'AnalyzeWildcard' to true enables best-effort analysis.
699+newtype AnalyzeWildcard = AnalyzeWildcard Bool deriving (Eq, Show, Generic)
701+{-| 'GeneratePhraseQueries' defaults to false.
703+newtype GeneratePhraseQueries =
704+ GeneratePhraseQueries Bool deriving (Eq, Show, Generic)
706+{-| 'Locale' is used for string conversions - defaults to ROOT.
708+newtype Locale = Locale Text deriving (Eq, Show, Generic)
709+newtype MaxWordLength = MaxWordLength Int deriving (Eq, Show, Generic)
710+newtype MinWordLength = MinWordLength Int deriving (Eq, Show, Generic)
712+{-| 'PhraseSlop' sets the default slop for phrases, 0 means exact
713+ phrase matches. Default is 0.
715+newtype PhraseSlop = PhraseSlop Int deriving (Eq, Show, Generic)
716+newtype MinDocFrequency = MinDocFrequency Int deriving (Eq, Show, Generic)
717+newtype MaxDocFrequency = MaxDocFrequency Int deriving (Eq, Show, Generic)
430{-| 'unpackId' is a silly convenience function that gets used once.
719{-| 'unpackId' is a silly convenience function that gets used once.
@@ -433,6 +722,8 @@ unpackId :: DocId -> Text
433unpackId (DocId docId) = docId
722unpackId (DocId docId) = docId
435type TrackSortScores = Bool
724type TrackSortScores = Bool
725+newtype From = From Int deriving (Eq, Show, ToJSON)
726+newtype Size = Size Int deriving (Eq, Show, ToJSON)
437data Search = Search { queryBody :: Maybe Query
728data Search = Search { queryBody :: Maybe Query
438 , filterBody :: Maybe Filter
729 , filterBody :: Maybe Filter
@@ -442,89 +733,1603 @@ data Search = Search { queryBody :: Maybe Query
442 -- default False
733 -- default False
443 , trackSortScores :: TrackSortScores
734 , trackSortScores :: TrackSortScores
444 , from :: From
735 , from :: From
445− , size :: Size
736+ , size :: Size
446 , searchType :: SearchType
737 , searchType :: SearchType
447− , searchAfterKey :: Maybe SearchAfterKey
448− , fields :: Maybe [FieldName]
738+ , fields :: Maybe [FieldName] } deriving (Eq, Show)
449− , scriptFields :: Maybe ScriptFields
450− , source :: Maybe Source
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)
480−data SearchType = SearchTypeQueryThenFetch
740+data SearchType = SearchTypeQueryThenFetch
481 | SearchTypeDfsQueryThenFetch
741 | SearchTypeDfsQueryThenFetch
744+ | SearchTypeQueryAndFetch
745+ | SearchTypeDfsQueryAndFetch
748+data Highlights = Highlights { globalsettings :: Maybe HighlightSettings
749+ , highlightFields :: [FieldHighlight]
750+ } deriving (Show, Eq)
752+data FieldHighlight = FieldHighlight FieldName (Maybe HighlightSettings)
756+data HighlightSettings = Plain PlainHighlight
757+ | Postings PostingsHighlight
758+ | FastVector FastVectorHighlight
760+data PlainHighlight =
761+ PlainHighlight { plainCommon :: Maybe CommonHighlight
762+ , plainNonPost :: Maybe NonPostings } deriving (Show, Eq)
764+ -- This requires that index_options are set to 'offset' in the mapping.
765+data PostingsHighlight = PostingsHighlight (Maybe CommonHighlight) deriving (Show, Eq)
767+-- This requires that term_vector is set to 'with_positions_offsets' in the mapping.
768+data FastVectorHighlight =
769+ FastVectorHighlight { fvCommon :: Maybe CommonHighlight
770+ , fvNonPostSettings :: Maybe NonPostings
771+ , boundaryChars :: Maybe Text
772+ , boundaryMaxScan :: Maybe Int
773+ , fragmentOffset :: Maybe Int
774+ , matchedFields :: [Text]
775+ , phraseLimit :: Maybe Int
776+ } deriving (Show, Eq)
778+data CommonHighlight =
779+ CommonHighlight { order :: Maybe Text
780+ , forceSource :: Maybe Bool
781+ , tag :: Maybe HighlightTag
782+ , encoder :: Maybe HighlightEncoder
783+ , noMatchSize :: Maybe Int
784+ , highlightQuery :: Maybe Query
785+ , requireFieldMatch :: Maybe Bool
786+ } deriving (Show, Eq)
788+-- Settings that are only applicable to FastVector and Plain highlighters.
790+ NonPostings { fragmentSize :: Maybe Int
791+ , numberOfFragments :: Maybe Int} deriving (Show, Eq)
793+data HighlightEncoder = DefaultEncoder
797+-- NOTE: Should the tags use some kind of HTML type, rather than Text?
798+data HighlightTag = TagSchema Text
799+ | CustomTags ([Text], [Text]) -- Only uses more than the first value in the lists if fvh
804+ TermQuery Term (Maybe Boost)
805+ | TermsQuery (NonEmpty Term)
806+ | QueryMatchQuery MatchQuery
807+ | QueryMultiMatchQuery MultiMatchQuery
808+ | QueryBoolQuery BoolQuery
809+ | QueryBoostingQuery BoostingQuery
810+ | QueryCommonTermsQuery CommonTermsQuery
811+ | ConstantScoreFilter Filter Boost
812+ | ConstantScoreQuery Query Boost
813+ | QueryDisMaxQuery DisMaxQuery
814+ | QueryFilteredQuery FilteredQuery
815+ | QueryFuzzyLikeThisQuery FuzzyLikeThisQuery
816+ | QueryFuzzyLikeFieldQuery FuzzyLikeFieldQuery
817+ | QueryFuzzyQuery FuzzyQuery
818+ | QueryHasChildQuery HasChildQuery
819+ | QueryHasParentQuery HasParentQuery
820+ | IdsQuery MappingName [DocId]
821+ | QueryIndicesQuery IndicesQuery
822+ | MatchAllQuery (Maybe Boost)
823+ | QueryMoreLikeThisQuery MoreLikeThisQuery
824+ | QueryMoreLikeThisFieldQuery MoreLikeThisFieldQuery
825+ | QueryNestedQuery NestedQuery
826+ | QueryPrefixQuery PrefixQuery
827+ | QueryQueryStringQuery QueryStringQuery
828+ | QuerySimpleQueryStringQuery SimpleQueryStringQuery
829+ | QueryRangeQuery RangeQuery
830+ | QueryRegexpQuery RegexpQuery
834+ RegexpQuery { regexpQueryField :: FieldName
835+ , regexpQuery :: Regexp
836+ , regexpQueryFlags :: RegexpFlags
837+ , regexpQueryBoost :: Maybe Boost
838+ } deriving (Eq, Show)
841+ RangeQuery { rangeQueryField :: FieldName
842+ , rangeQueryRange :: RangeValue
843+ , rangeQueryBoost :: Boost } deriving (Eq, Show)
845+mkRangeQuery :: FieldName -> RangeValue -> RangeQuery
846+mkRangeQuery f r = RangeQuery f r (Boost 1.0)
848+data SimpleQueryStringQuery =
849+ SimpleQueryStringQuery
850+ { simpleQueryStringQuery :: QueryString
851+ , simpleQueryStringField :: Maybe FieldOrFields
852+ , simpleQueryStringOperator :: Maybe BooleanOperator
853+ , simpleQueryStringAnalyzer :: Maybe Analyzer
854+ , simpleQueryStringFlags :: Maybe [SimpleQueryFlag]
855+ , simpleQueryStringLowercaseExpanded :: Maybe LowercaseExpanded
856+ , simpleQueryStringLocale :: Maybe Locale
857+ } deriving (Eq, Show)
859+data SimpleQueryFlag =
866+ | SimpleQueryPrecedence
868+ | SimpleQueryWhitespace
871+ | SimpleQuerySlop deriving (Eq, Show)
873+-- use_dis_max and tie_breaker when fields are plural?
874+data QueryStringQuery =
876+ { queryStringQuery :: QueryString
877+ , queryStringDefaultField :: Maybe FieldName
878+ , queryStringOperator :: Maybe BooleanOperator
879+ , queryStringAnalyzer :: Maybe Analyzer
880+ , queryStringAllowLeadingWildcard :: Maybe AllowLeadingWildcard
881+ , queryStringLowercaseExpanded :: Maybe LowercaseExpanded
882+ , queryStringEnablePositionIncrements :: Maybe EnablePositionIncrements
883+ , queryStringFuzzyMaxExpansions :: Maybe MaxExpansions
884+ , queryStringFuzziness :: Maybe Fuzziness
885+ , queryStringFuzzyPrefixLength :: Maybe PrefixLength
886+ , queryStringPhraseSlop :: Maybe PhraseSlop
887+ , queryStringBoost :: Maybe Boost
888+ , queryStringAnalyzeWildcard :: Maybe AnalyzeWildcard
889+ , queryStringGeneratePhraseQueries :: Maybe GeneratePhraseQueries
890+ , queryStringMinimumShouldMatch :: Maybe MinimumMatch
891+ , queryStringLenient :: Maybe Lenient
892+ , queryStringLocale :: Maybe Locale
893+ } deriving (Eq, Show)
895+mkQueryStringQuery :: QueryString -> QueryStringQuery
896+mkQueryStringQuery qs =
897+ QueryStringQuery qs Nothing Nothing
898+ Nothing Nothing Nothing Nothing
899+ Nothing Nothing Nothing Nothing
900+ Nothing Nothing Nothing Nothing
903+data FieldOrFields = FofField FieldName
904+ | FofFields [FieldName] deriving (Eq, Show)
908+ { prefixQueryField :: FieldName
909+ , prefixQueryPrefixValue :: Text
910+ , prefixQueryBoost :: Maybe Boost } deriving (Eq, Show)
914+ { nestedQueryPath :: QueryPath
915+ , nestedQueryScoreType :: ScoreType
916+ , nestedQuery :: Query } deriving (Eq, Show)
918+data MoreLikeThisFieldQuery =
919+ MoreLikeThisFieldQuery
920+ { moreLikeThisFieldText :: Text
921+ , moreLikeThisFieldFields :: FieldName
922+ -- default 0.3 (30%)
923+ , moreLikeThisFieldPercentMatch :: Maybe PercentMatch
924+ , moreLikeThisFieldMinimumTermFreq :: Maybe MinimumTermFrequency
925+ , moreLikeThisFieldMaxQueryTerms :: Maybe MaxQueryTerms
926+ , moreLikeThisFieldStopWords :: Maybe [StopWord]
927+ , moreLikeThisFieldMinDocFrequency :: Maybe MinDocFrequency
928+ , moreLikeThisFieldMaxDocFrequency :: Maybe MaxDocFrequency
929+ , moreLikeThisFieldMinWordLength :: Maybe MinWordLength
930+ , moreLikeThisFieldMaxWordLength :: Maybe MaxWordLength
931+ , moreLikeThisFieldBoostTerms :: Maybe BoostTerms
932+ , moreLikeThisFieldBoost :: Maybe Boost
933+ , moreLikeThisFieldAnalyzer :: Maybe Analyzer
934+ } deriving (Eq, Show)
936+data MoreLikeThisQuery =
938+ { moreLikeThisText :: Text
939+ , moreLikeThisFields :: Maybe [FieldName]
940+ -- default 0.3 (30%)
941+ , moreLikeThisPercentMatch :: Maybe PercentMatch
942+ , moreLikeThisMinimumTermFreq :: Maybe MinimumTermFrequency
943+ , moreLikeThisMaxQueryTerms :: Maybe MaxQueryTerms
944+ , moreLikeThisStopWords :: Maybe [StopWord]
945+ , moreLikeThisMinDocFrequency :: Maybe MinDocFrequency
946+ , moreLikeThisMaxDocFrequency :: Maybe MaxDocFrequency
947+ , moreLikeThisMinWordLength :: Maybe MinWordLength
948+ , moreLikeThisMaxWordLength :: Maybe MaxWordLength
949+ , moreLikeThisBoostTerms :: Maybe BoostTerms
950+ , moreLikeThisBoost :: Maybe Boost
951+ , moreLikeThisAnalyzer :: Maybe Analyzer
952+ } deriving (Eq, Show)
956+ { indicesQueryIndices :: [IndexName]
957+ , indicesQuery :: Query
959+ , indicesQueryNoMatch :: Maybe Query } deriving (Eq, Show)
961+data HasParentQuery =
963+ { hasParentQueryType :: TypeName
964+ , hasParentQuery :: Query
965+ , hasParentQueryScoreType :: Maybe ScoreType } deriving (Eq, Show)
969+ { hasChildQueryType :: TypeName
970+ , hasChildQuery :: Query
971+ , hasChildQueryScoreType :: Maybe ScoreType } deriving (Eq, Show)
977+ | ScoreTypeNone deriving (Eq, Show)
980+ FuzzyQuery { fuzzyQueryField :: FieldName
981+ , fuzzyQueryValue :: Text
982+ , fuzzyQueryPrefixLength :: PrefixLength
983+ , fuzzyQueryMaxExpansions :: MaxExpansions
984+ , fuzzyQueryFuzziness :: Fuzziness
985+ , fuzzyQueryBoost :: Maybe Boost
986+ } deriving (Eq, Show)
988+data FuzzyLikeFieldQuery =
990+ { fuzzyLikeField :: FieldName
991+ -- anaphora is good for the soul.
992+ , fuzzyLikeFieldText :: Text
993+ , fuzzyLikeFieldMaxQueryTerms :: MaxQueryTerms
994+ , fuzzyLikeFieldIgnoreTermFrequency :: IgnoreTermFrequency
995+ , fuzzyLikeFieldFuzziness :: Fuzziness
996+ , fuzzyLikeFieldPrefixLength :: PrefixLength
997+ , fuzzyLikeFieldBoost :: Boost
998+ , fuzzyLikeFieldAnalyzer :: Maybe Analyzer
999+ } deriving (Eq, Show)
1001+data FuzzyLikeThisQuery =
1003+ { fuzzyLikeFields :: [FieldName]
1004+ , fuzzyLikeText :: Text
1005+ , fuzzyLikeMaxQueryTerms :: MaxQueryTerms
1006+ , fuzzyLikeIgnoreTermFrequency :: IgnoreTermFrequency
1007+ , fuzzyLikeFuzziness :: Fuzziness
1008+ , fuzzyLikePrefixLength :: PrefixLength
1009+ , fuzzyLikeBoost :: Boost
1010+ , fuzzyLikeAnalyzer :: Maybe Analyzer
1011+ } deriving (Eq, Show)
1013+data FilteredQuery =
1015+ { filteredQuery :: Query
1016+ , filteredFilter :: Filter } deriving (Eq, Show)
1019+ DisMaxQuery { disMaxQueries :: [Query]
1021+ , disMaxTiebreaker :: Tiebreaker
1022+ , disMaxBoost :: Maybe Boost
1023+ } deriving (Eq, Show)
1026+ MatchQuery { matchQueryField :: FieldName
1027+ , matchQueryQueryString :: QueryString
1028+ , matchQueryOperator :: BooleanOperator
1029+ , matchQueryZeroTerms :: ZeroTermsQuery
1030+ , matchQueryCutoffFrequency :: Maybe CutoffFrequency
1031+ , matchQueryMatchType :: Maybe MatchQueryType
1032+ , matchQueryAnalyzer :: Maybe Analyzer
1033+ , matchQueryMaxExpansions :: Maybe MaxExpansions
1034+ , matchQueryLenient :: Maybe Lenient } deriving (Eq, Show)
1036+{-| 'mkMatchQuery' is a convenience function that defaults the less common parameters,
1037+ enabling you to provide only the 'FieldName' and 'QueryString' to make a 'MatchQuery'
1039+mkMatchQuery :: FieldName -> QueryString -> MatchQuery
1040+mkMatchQuery field query = MatchQuery field query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing
1042+data MatchQueryType =
1044+ | MatchPhrasePrefix deriving (Eq, Show)
1046+data MultiMatchQuery =
1047+ MultiMatchQuery { multiMatchQueryFields :: [FieldName]
1048+ , multiMatchQueryString :: QueryString
1049+ , multiMatchQueryOperator :: BooleanOperator
1050+ , multiMatchQueryZeroTerms :: ZeroTermsQuery
1051+ , multiMatchQueryTiebreaker :: Maybe Tiebreaker
1052+ , multiMatchQueryType :: Maybe MultiMatchQueryType
1053+ , multiMatchQueryCutoffFrequency :: Maybe CutoffFrequency
1054+ , multiMatchQueryAnalyzer :: Maybe Analyzer
1055+ , multiMatchQueryMaxExpansions :: Maybe MaxExpansions
1056+ , multiMatchQueryLenient :: Maybe Lenient } deriving (Eq, Show)
1058+{-| 'mkMultiMatchQuery' is a convenience function that defaults the less common parameters,
1059+ enabling you to provide only the list of 'FieldName's and 'QueryString' to
1060+ make a 'MultiMatchQuery'.
1063+mkMultiMatchQuery :: [FieldName] -> QueryString -> MultiMatchQuery
1064+mkMultiMatchQuery matchFields query =
1065+ MultiMatchQuery matchFields query
1066+ Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1068+data MultiMatchQueryType =
1069+ MultiMatchBestFields
1070+ | MultiMatchMostFields
1071+ | MultiMatchCrossFields
1073+ | MultiMatchPhrasePrefix deriving (Eq, Show)
1076+ BoolQuery { boolQueryMustMatch :: [Query]
1077+ , boolQueryMustNotMatch :: [Query]
1078+ , boolQueryShouldMatch :: [Query]
1079+ , boolQueryMinimumShouldMatch :: Maybe MinimumMatch
1080+ , boolQueryBoost :: Maybe Boost
1081+ , boolQueryDisableCoord :: Maybe DisableCoord
1082+ } deriving (Eq, Show)
1084+mkBoolQuery :: [Query] -> [Query] -> [Query] -> BoolQuery
1085+mkBoolQuery must mustNot should =
1086+ BoolQuery must mustNot should Nothing Nothing Nothing
1088+data BoostingQuery =
1089+ BoostingQuery { positiveQuery :: Query
1090+ , negativeQuery :: Query
1091+ , negativeBoost :: Boost } deriving (Eq, Show)
1093+data CommonTermsQuery =
1094+ CommonTermsQuery { commonField :: FieldName
1095+ , commonQuery :: QueryString
1096+ , commonCutoffFrequency :: CutoffFrequency
1097+ , commonLowFreqOperator :: BooleanOperator
1098+ , commonHighFreqOperator :: BooleanOperator
1099+ , commonMinimumShouldMatch :: Maybe CommonMinimumMatch
1100+ , commonBoost :: Maybe Boost
1101+ , commonAnalyzer :: Maybe Analyzer
1102+ , commonDisableCoord :: Maybe DisableCoord
1103+ } deriving (Eq, Show)
1105+data CommonMinimumMatch =
1106+ CommonMinimumMatchHighLow MinimumMatchHighLow
1107+ | CommonMinimumMatch MinimumMatch
482 deriving (Eq, Show)
1108 deriving (Eq, Show)
484−data Source =
1110+data MinimumMatchHighLow =
485− NoSource
1111+ MinimumMatchHighLow { lowFreq :: MinimumMatch
486− | SourcePatterns PatternOrPatterns
1112+ , highFreq :: MinimumMatch } deriving (Eq, Show)
487− | SourceIncludeExclude Include Exclude
1113+
1114+data Filter = AndFilter [Filter] Cache
1115+ | OrFilter [Filter] Cache
1116+ | NotFilter Filter Cache
1118+ | BoolFilter BoolMatch
1119+ | ExistsFilter FieldName -- always cached
1120+ | GeoBoundingBoxFilter GeoBoundingBoxConstraint
1121+ | GeoDistanceFilter GeoPoint Distance DistanceType OptimizeBbox Cache
1122+ | GeoDistanceRangeFilter GeoPoint DistanceRange
1123+ | GeoPolygonFilter FieldName [LatLon]
1124+ | IdsFilter MappingName [DocId]
1126+ | MissingFilter FieldName Existence NullValue
1127+ | PrefixFilter FieldName PrefixValue Cache
1128+ | QueryFilter Query Cache
1129+ | RangeFilter FieldName RangeValue RangeExecution Cache
1130+ | RegexpFilter FieldName Regexp RegexpFlags CacheName Cache CacheKey
1131+ | TermFilter Term Cache
1132+ deriving (Eq, Show)
1134+data ZeroTermsQuery = ZeroTermsNone
1135+ | ZeroTermsAll deriving (Eq, Show)
1137+data RangeExecution = RangeExecutionIndex
488− deriving (Eq, Show)
1138+ | RangeExecutionFielddata deriving (Eq, Show)
490−instance ToJSON Source where
1140+newtype Regexp = Regexp Text deriving (Eq, Show)
491− toJSON NoSource = toJSON False
492− toJSON (SourcePatterns patterns) = toJSON patterns
493− toJSON (SourceIncludeExclude incl excl) = object [ "includes" .= incl, "excludes" .= excl ]
495−data PatternOrPatterns = PopPattern Pattern
1142+data RegexpFlags = AllRegexpFlags
496− | PopPatterns [Pattern] deriving (Eq, Read, Show)
1143+ | NoRegexpFlags
1144+ | SomeRegexpFlags (NonEmpty RegexpFlag) deriving (Eq, Show)
498−instance ToJSON PatternOrPatterns where
1146+data RegexpFlag = AnyString
499− toJSON (PopPattern pattern) = toJSON pattern
1147+ | Automaton
500− toJSON (PopPatterns patterns) = toJSON patterns
1148+ | Complement
1151+ | Interval deriving (Eq, Show)
502−data Include = Include [Pattern] deriving (Eq, Read, Show)
1153+newtype LessThan = LessThan Double deriving (Eq, Show)
503−data Exclude = Exclude [Pattern] deriving (Eq, Read, Show)
1154+newtype LessThanEq = LessThanEq Double deriving (Eq, Show)
1155+newtype GreaterThan = GreaterThan Double deriving (Eq, Show)
1156+newtype GreaterThanEq = GreaterThanEq Double deriving (Eq, Show)
505−instance ToJSON Include where
1158+newtype LessThanD = LessThanD UTCTime deriving (Eq, Show)
506− toJSON (Include patterns) = toJSON patterns
1159+newtype LessThanEqD = LessThanEqD UTCTime deriving (Eq, Show)
1160+newtype GreaterThanD = GreaterThanD UTCTime deriving (Eq, Show)
1161+newtype GreaterThanEqD = GreaterThanEqD UTCTime deriving (Eq, Show)
508−instance ToJSON Exclude where
1163+data RangeValue = RangeDateLte LessThanEqD
509− toJSON (Exclude patterns) = toJSON patterns
1164+ | RangeDateLt LessThanD
1165+ | RangeDateGte GreaterThanEqD
1166+ | RangeDateGt GreaterThanD
1167+ | RangeDateGtLt GreaterThanD LessThanD
1168+ | RangeDateGteLte GreaterThanEqD LessThanEqD
1169+ | RangeDateGteLt GreaterThanEqD LessThanD
1170+ | RangeDateGtLte GreaterThanD LessThanEqD
1171+ | RangeDoubleLte LessThanEq
1172+ | RangeDoubleLt LessThan
1173+ | RangeDoubleGte GreaterThanEq
1174+ | RangeDoubleGt GreaterThan
1175+ | RangeDoubleGtLt GreaterThan LessThan
1176+ | RangeDoubleGteLte GreaterThanEq LessThanEq
1177+ | RangeDoubleGteLt GreaterThanEq LessThan
1178+ | RangeDoubleGtLte GreaterThan LessThanEq
1179+ deriving (Eq, Show)
511−newtype Pattern = Pattern Text deriving (Eq, Read, Show)
1181+rangeValueToPair :: RangeValue -> [Pair]
1182+rangeValueToPair rv = case rv of
1183+ RangeDateLte (LessThanEqD t) -> ["lte" .= t]
1184+ RangeDateGte (GreaterThanEqD t) -> ["gte" .= t]
1185+ RangeDateLt (LessThanD t) -> ["lt" .= t]
1186+ RangeDateGt (GreaterThanD t) -> ["gt" .= t]
1187+ RangeDateGteLte (GreaterThanEqD l) (LessThanEqD g) -> ["gte" .= l, "lte" .= g]
1188+ RangeDateGtLte (GreaterThanD l) (LessThanEqD g) -> ["gt" .= l, "lte" .= g]
1189+ RangeDateGteLt (GreaterThanEqD l) (LessThanD g) -> ["gte" .= l, "lt" .= g]
1190+ RangeDateGtLt (GreaterThanD l) (LessThanD g) -> ["gt" .= l, "lt" .= g]
1191+ RangeDoubleLte (LessThanEq t) -> ["lte" .= t]
1192+ RangeDoubleGte (GreaterThanEq t) -> ["gte" .= t]
1193+ RangeDoubleLt (LessThan t) -> ["lt" .= t]
1194+ RangeDoubleGt (GreaterThan t) -> ["gt" .= t]
1195+ RangeDoubleGteLte (GreaterThanEq l) (LessThanEq g) -> ["gte" .= l, "lte" .= g]
1196+ RangeDoubleGtLte (GreaterThan l) (LessThanEq g) -> ["gt" .= l, "lte" .= g]
1197+ RangeDoubleGteLt (GreaterThanEq l) (LessThan g) -> ["gte" .= l, "lt" .= g]
1198+ RangeDoubleGtLt (GreaterThan l) (LessThan g) -> ["gt" .= l, "lt" .= g]
513−instance ToJSON Pattern where
1200+data Term = Term { termField :: Text
514− toJSON (Pattern pattern) = toJSON pattern
1201+ , termValue :: Text } deriving (Eq, Show)
1203+data BoolMatch = MustMatch Term Cache
1204+ | MustNotMatch Term Cache
1205+ | ShouldMatch [Term] Cache deriving (Eq, Show)
1207+-- "memory" or "indexed"
1208+data GeoFilterType = GeoFilterMemory
1209+ | GeoFilterIndexed deriving (Eq, Show)
1211+data LatLon = LatLon { lat :: Double
1212+ , lon :: Double } deriving (Eq, Show)
1214+data GeoBoundingBox =
1215+ GeoBoundingBox { topLeft :: LatLon
1216+ , bottomRight :: LatLon } deriving (Eq, Show)
1218+data GeoBoundingBoxConstraint =
1219+ GeoBoundingBoxConstraint { geoBBField :: FieldName
1220+ , constraintBox :: GeoBoundingBox
1221+ , bbConstraintcache :: Cache
1222+ , geoType :: GeoFilterType
1223+ } deriving (Eq, Show)
1226+ GeoPoint { geoField :: FieldName
1227+ , latLon :: LatLon} deriving (Eq, Show)
1229+data DistanceUnit = Miles
1237+ | NauticalMiles deriving (Eq, Show)
1239+data DistanceType = Arc
1240+ | SloppyArc -- doesn't exist <1.0
1241+ | Plane deriving (Eq, Show)
1243+data OptimizeBbox = OptimizeGeoFilterType GeoFilterType
1244+ | NoOptimizeBbox deriving (Eq, Show)
1247+ Distance { coefficient :: Double
1248+ , unit :: DistanceUnit } deriving (Eq, Show)
1250+data DistanceRange =
1251+ DistanceRange { distanceFrom :: Distance
1252+ , distanceTo :: Distance } deriving (Eq, Show)
516data SearchResult a =
1254data SearchResult a =
517 SearchResult { took :: Int
1255 SearchResult { took :: Int
518 , timedOut :: Bool
1256 , timedOut :: Bool
519 , shards :: ShardResult
1257 , shards :: ShardResult
520 , searchHits :: SearchHits a
1258 , searchHits :: SearchHits a
521− , aggregations :: Maybe AggregationResults
1259+ , aggregations :: Maybe AggregationResults
522− , scrollId :: Maybe ScrollId
1260+ , scrollId :: Maybe ScrollId } deriving (Eq, Show)
523− -- ^ Only one Suggestion request / response per
1261+
524− -- Search is supported.
1262+type ScrollId = Text -- Fixme: Newtype
525− , suggest :: Maybe NamedSuggestionResponse
1263+
526− }
1264+type Score = Maybe Double
527− deriving (Eq, Show)
1265+
1267+ SearchHits { hitsTotal :: Int
1268+ , maxScore :: Score
1269+ , hits :: [Hit a] } deriving (Eq, Show)
1272+instance Monoid (SearchHits a) where
1273+ mempty = SearchHits 0 Nothing mempty
1274+ mappend (SearchHits ta ma ha) (SearchHits tb mb hb) =
1275+ SearchHits (ta + tb) (max ma mb) (ha <> hb)
1279+ Hit { hitIndex :: IndexName
1280+ , hitType :: MappingName
1281+ , hitDocId :: DocId
1282+ , hitScore :: Score
1284+ , hitHighlight :: Maybe HitHighlight } deriving (Eq, Show)
1287+ ShardResult { shardTotal :: Int
1288+ , shardsSuccessful :: Int
1289+ , shardsFailed :: Int } deriving (Eq, Show, Generic)
1291+type HitHighlight = M.Map Text [Text]
1293+showText :: Show a => a -> Text
1294+showText = T.pack . show
1296+type Aggregations = M.Map Text Aggregation
1298+emptyAggregations :: Aggregations
1299+emptyAggregations = M.empty
1301+mkAggregations :: Text -> Aggregation -> Aggregations
1302+mkAggregations name aggregation = M.insert name aggregation emptyAggregations
1304+data TermOrder = TermOrder{ termSortField :: Text
1305+ , termSortOrder :: SortOrder } deriving (Eq, Show)
1307+data TermInclusion = TermInclusion Text
1308+ | TermPattern Text Text deriving (Eq, Show)
1310+data CollectionMode = BreadthFirst
1311+ | DepthFirst deriving (Eq, Show)
1313+data ExecutionHint = Ordinals
1315+ | GlobalOrdinalsHash
1316+ | GlobalOrdinalsLowCardinality
1317+ | Map deriving (Eq, Show)
1319+data TimeInterval = Weeks
1323+ | Seconds deriving (Eq)
1325+data Interval = Year
1333+ | FractionalInterval Float TimeInterval deriving (Eq, Show)
1335+data Aggregation = TermsAgg TermsAggregation
1336+ | DateHistogramAgg DateHistogramAggregation
1337+ | ValueCountAgg ValueCountAggregation
1338+ | FilterAgg FilterAggregation deriving (Eq, Show)
1341+data TermsAggregation = TermsAggregation { term :: Either Text Text
1342+ , termInclude :: Maybe TermInclusion
1343+ , termExclude :: Maybe TermInclusion
1344+ , termOrder :: Maybe TermOrder
1345+ , termMinDocCount :: Maybe Int
1346+ , termSize :: Maybe Int
1347+ , termShardSize :: Maybe Int
1348+ , termCollectMode :: Maybe CollectionMode
1349+ , termExecutionHint :: Maybe ExecutionHint
1350+ , termAggs :: Maybe Aggregations
1351+ } deriving (Eq, Show)
1353+data DateHistogramAggregation = DateHistogramAggregation { dateField :: FieldName
1354+ , dateInterval :: Interval
1355+ , dateFormat :: Maybe Text
1356+ -- pre and post deprecated in 1.5
1357+ , datePreZone :: Maybe Text
1358+ , datePostZone :: Maybe Text
1359+ , datePreOffset :: Maybe Text
1360+ , datePostOffset :: Maybe Text
1361+ , dateAggs :: Maybe Aggregations
1362+ } deriving (Eq, Show)
1364+-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html> for more information.
1365+data ValueCountAggregation = FieldValueCount FieldName
1366+ | ScriptValueCount Script deriving (Eq, Show)
1368+-- | 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.
1369+data FilterAggregation = FilterAggregation { faFilter :: Filter
1370+ , faAggs :: Maybe Aggregations} deriving (Eq, Show)
1372+mkTermsAggregation :: Text -> TermsAggregation
1373+mkTermsAggregation t = TermsAggregation (Left t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1375+mkTermsScriptAggregation :: Text -> TermsAggregation
1376+mkTermsScriptAggregation t = TermsAggregation (Right t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1378+mkDateHistogram :: FieldName -> Interval -> DateHistogramAggregation
1379+mkDateHistogram t i = DateHistogramAggregation t i Nothing Nothing Nothing Nothing Nothing Nothing
1381+instance ToJSON TermOrder where
1382+ toJSON (TermOrder termSortField termSortOrder) = object [termSortField .= termSortOrder]
1384+instance ToJSON TermInclusion where
1385+ toJSON (TermInclusion x) = toJSON x
1386+ toJSON (TermPattern pattern flags) = omitNulls [ "pattern" .= pattern,
1389+instance ToJSON CollectionMode where
1390+ toJSON BreadthFirst = "breadth_first"
1391+ toJSON DepthFirst = "depth_first"
1393+instance ToJSON ExecutionHint where
1394+ toJSON Ordinals = "ordinals"
1395+ toJSON GlobalOrdinals = "global_ordinals"
1396+ toJSON GlobalOrdinalsHash = "global_ordinals_hash"
1397+ toJSON GlobalOrdinalsLowCardinality = "global_ordinals_low_cardinality"
1400+instance ToJSON Interval where
1401+ toJSON Year = "year"
1402+ toJSON Quarter = "quarter"
1403+ toJSON Month = "month"
1404+ toJSON Week = "week"
1406+ toJSON Hour = "hour"
1407+ toJSON Minute = "minute"
1408+ toJSON Second = "second"
1409+ toJSON (FractionalInterval fraction interval) = toJSON $ show fraction ++ show interval
1411+instance Show TimeInterval where
1418+instance ToJSON Aggregation where
1419+ toJSON (TermsAgg (TermsAggregation term include exclude order minDocCount size shardSize collectMode executionHint termAggs)) =
1420+ omitNulls ["terms" .= omitNulls [ toJSON' term,
1421+ "include" .= include,
1422+ "exclude" .= exclude,
1424+ "min_doc_count" .= minDocCount,
1426+ "shard_size" .= shardSize,
1427+ "collect_mode" .= collectMode,
1428+ "execution_hint" .= executionHint
1430+ "aggs" .= termAggs ]
1432+ toJSON' x = case x of { Left y -> "field" .= y; Right y -> "script" .= y }
1434+ toJSON (DateHistogramAgg (DateHistogramAggregation field interval format preZone postZone preOffset postOffset dateHistoAggs)) =
1435+ omitNulls ["date_histogram" .= omitNulls [ "field" .= field,
1436+ "interval" .= interval,
1437+ "format" .= format,
1438+ "pre_zone" .= preZone,
1439+ "post_zone" .= postZone,
1440+ "pre_offset" .= preOffset,
1441+ "post_offset" .= postOffset
1443+ "aggs" .= dateHistoAggs ]
1444+ toJSON (ValueCountAgg a) = object ["value_count" .= v]
1445+ where v = case a of
1446+ (FieldValueCount (FieldName n)) -> object ["field" .= n]
1447+ (ScriptValueCount (Script s)) -> object ["script" .= s]
1448+ toJSON (FilterAgg (FilterAggregation filt ags)) =
1449+ omitNulls [ "filter" .= filt
1452+type AggregationResults = M.Map Text Value
1454+class BucketAggregation a where
1456+ docCount :: a -> Int
1457+ aggs :: a -> Maybe AggregationResults
1460+data Bucket a = Bucket { buckets :: [a]} deriving (Show)
1462+data TermsResult = TermsResult { termKey :: Text
1463+ , termsDocCount :: Int
1464+ , termsAggs :: Maybe AggregationResults } deriving (Show)
1466+data DateHistogramResult = DateHistogramResult { dateKey :: Int
1467+ , dateKeyStr :: Maybe Text
1468+ , dateDocCount :: Int
1469+ , dateHistogramAggs :: Maybe AggregationResults } deriving (Show)
1471+toTerms :: Text -> AggregationResults -> Maybe (Bucket TermsResult)
1472+toTerms t a = M.lookup t a >>= deserialize
1473+ where deserialize = parseMaybe parseJSON
1475+toDateHistogram :: Text -> AggregationResults -> Maybe (Bucket DateHistogramResult)
1476+toDateHistogram t a = M.lookup t a >>= deserialize
1477+ where deserialize = parseMaybe parseJSON
1479+instance BucketAggregation TermsResult where
1481+ docCount = termsDocCount
1484+instance BucketAggregation DateHistogramResult where
1485+ key = showText . dateKey
1486+ docCount = dateDocCount
1487+ aggs = dateHistogramAggs
1489+instance (FromJSON a, BucketAggregation a) => FromJSON (Bucket a) where
1490+ parseJSON (Object v) = Bucket <$>
1492+ parseJSON _ = mempty
1494+instance FromJSON TermsResult where
1495+ parseJSON (Object v) = TermsResult <$>
1497+ v .: "doc_count" <*>
1498+ v .:? "aggregations"
1499+ parseJSON _ = mempty
1501+instance FromJSON DateHistogramResult where
1502+ parseJSON (Object v) = DateHistogramResult <$>
1504+ v .:? "key_as_string" <*>
1505+ v .: "doc_count" <*>
1506+ v .:? "aggregations"
1507+ parseJSON _ = mempty
1509+instance Monoid Filter where
1510+ mempty = IdentityFilter
1511+ mappend a b = AndFilter [a, b] defaultCache
1513+instance Seminearring Filter where
1514+ a <||> b = OrFilter [a, b] defaultCache
1516+instance ToJSON Filter where
1517+ toJSON (AndFilter filters cache) =
1519+ object [ "filters" .= fmap toJSON filters
1520+ , "_cache" .= cache]]
1522+ toJSON (OrFilter filters cache) =
1524+ object [ "filters" .= fmap toJSON filters
1525+ , "_cache" .= cache]]
1527+ toJSON (NotFilter notFilter cache) =
1529+ object ["filter" .= notFilter
1530+ , "_cache" .= cache]]
1532+ toJSON (IdentityFilter) =
1533+ object ["match_all" .= object []]
1535+ toJSON (TermFilter (Term termFilterField termFilterValue) cache) =
1536+ object ["term" .= object base]
1537+ where base = [termFilterField .= termFilterValue,
1540+ toJSON (ExistsFilter (FieldName fieldName)) =
1541+ object ["exists" .= object
1542+ ["field" .= fieldName]]
1544+ toJSON (BoolFilter boolMatch) =
1545+ object ["bool" .= boolMatch]
1547+ toJSON (GeoBoundingBoxFilter bbConstraint) =
1548+ object ["geo_bounding_box" .= bbConstraint]
1550+ toJSON (GeoDistanceFilter (GeoPoint (FieldName distanceGeoField) geoDistLatLon)
1551+ distance distanceType optimizeBbox cache) =
1552+ object ["geo_distance" .=
1553+ object ["distance" .= distance
1554+ , "distance_type" .= distanceType
1555+ , "optimize_bbox" .= optimizeBbox
1556+ , distanceGeoField .= geoDistLatLon
1557+ , "_cache" .= cache]]
1559+ toJSON (GeoDistanceRangeFilter (GeoPoint (FieldName gddrField) drLatLon)
1560+ (DistanceRange geoDistRangeDistFrom drDistanceTo)) =
1561+ object ["geo_distance_range" .=
1562+ object ["from" .= geoDistRangeDistFrom
1563+ , "to" .= drDistanceTo
1564+ , gddrField .= drLatLon]]
1566+ toJSON (GeoPolygonFilter (FieldName geoPolygonFilterField) latLons) =
1567+ object ["geo_polygon" .=
1568+ object [geoPolygonFilterField .=
1569+ object ["points" .= fmap toJSON latLons]]]
1571+ toJSON (IdsFilter (MappingName mappingName) values) =
1573+ object ["type" .= mappingName
1574+ , "values" .= fmap unpackId values]]
1576+ toJSON (LimitFilter limit) =
1577+ object ["limit" .= object ["value" .= limit]]
1579+ toJSON (MissingFilter (FieldName fieldName) (Existence existence) (NullValue nullValue)) =
1580+ object ["missing" .=
1581+ object ["field" .= fieldName
1582+ , "existence" .= existence
1583+ , "null_value" .= nullValue]]
1585+ toJSON (PrefixFilter (FieldName fieldName) fieldValue cache) =
1586+ object ["prefix" .=
1587+ object [fieldName .= fieldValue
1588+ , "_cache" .= cache]]
1590+ toJSON (QueryFilter query False) =
1591+ object ["query" .= toJSON query ]
1592+ toJSON (QueryFilter query True) =
1593+ object ["fquery" .=
1594+ object [ "query" .= toJSON query
1595+ , "_cache" .= True ]]
1597+ toJSON (RangeFilter (FieldName fieldName) rangeValue rangeExecution cache) =
1599+ object [ fieldName .= object (rangeValueToPair rangeValue)
1600+ , "execution" .= rangeExecution
1601+ , "_cache" .= cache]]
1603+ toJSON (RegexpFilter (FieldName fieldName)
1604+ (Regexp regexText) flags (CacheName cacheName) cache (CacheKey cacheKey)) =
1605+ object ["regexp" .=
1606+ object [fieldName .=
1607+ object ["value" .= regexText
1608+ , "flags" .= flags]
1609+ , "_name" .= cacheName
1610+ , "_cache" .= cache
1611+ , "_cache_key" .= cacheKey]]
1613+instance ToJSON GeoPoint where
1614+ toJSON (GeoPoint (FieldName geoPointField) geoPointLatLon) =
1615+ object [ geoPointField .= geoPointLatLon ]
1618+instance ToJSON Query where
1619+ toJSON (TermQuery (Term termQueryField termQueryValue) boost) =
1621+ object [termQueryField .= object merged]]
1623+ base = [ "value" .= termQueryValue ]
1624+ boosted = maybe [] (return . ("boost" .=)) boost
1625+ merged = mappend base boosted
1627+ toJSON (TermsQuery terms) =
1628+ object [ "terms" .= object conjoined ]
1629+ where conjoined = [ getTermsField terms .=
1630+ fmap (toJSON . getTermValue) (toList terms)]
1631+ getTermsField ((Term f _ ) :| _) = f
1632+ getTermValue (Term _ v) = v
1633+ toJSON (IdsQuery idsQueryMappingName docIds) =
1634+ object [ "ids" .= object conjoined ]
1635+ where conjoined = [ "type" .= idsQueryMappingName
1636+ , "values" .= fmap toJSON docIds ]
1638+ toJSON (QueryQueryStringQuery qQueryStringQuery) =
1639+ object [ "query_string" .= qQueryStringQuery ]
1641+ toJSON (QueryMatchQuery matchQuery) =
1642+ object [ "match" .= matchQuery ]
1644+ toJSON (QueryMultiMatchQuery multiMatchQuery) =
1645+ toJSON multiMatchQuery
1647+ toJSON (QueryBoolQuery boolQuery) =
1648+ object [ "bool" .= boolQuery ]
1650+ toJSON (QueryBoostingQuery boostingQuery) =
1651+ object [ "boosting" .= boostingQuery ]
1653+ toJSON (QueryCommonTermsQuery commonTermsQuery) =
1654+ object [ "common" .= commonTermsQuery ]
1656+ toJSON (ConstantScoreFilter csFilter boost) =
1657+ object [ "constant_score" .= csFilter
1658+ , "boost" .= boost]
1660+ toJSON (ConstantScoreQuery query boost) =
1661+ object [ "constant_score" .= query
1662+ , "boost" .= boost]
1664+ toJSON (QueryDisMaxQuery disMaxQuery) =
1665+ object [ "dis_max" .= disMaxQuery ]
1667+ toJSON (QueryFilteredQuery qFilteredQuery) =
1668+ object [ "filtered" .= qFilteredQuery ]
1670+ toJSON (QueryFuzzyLikeThisQuery fuzzyQuery) =
1671+ object [ "fuzzy_like_this" .= fuzzyQuery ]
1673+ toJSON (QueryFuzzyLikeFieldQuery fuzzyFieldQuery) =
1674+ object [ "fuzzy_like_this_field" .= fuzzyFieldQuery ]
1676+ toJSON (QueryFuzzyQuery fuzzyQuery) =
1677+ object [ "fuzzy" .= fuzzyQuery ]
1679+ toJSON (QueryHasChildQuery childQuery) =
1680+ object [ "has_child" .= childQuery ]
1682+ toJSON (QueryHasParentQuery parentQuery) =
1683+ object [ "has_parent" .= parentQuery ]
1685+ toJSON (QueryIndicesQuery qIndicesQuery) =
1686+ object [ "indices" .= qIndicesQuery ]
1688+ toJSON (MatchAllQuery boost) =
1689+ object [ "match_all" .= omitNulls [ "boost" .= boost ] ]
1691+ toJSON (QueryMoreLikeThisQuery query) =
1692+ object [ "more_like_this" .= query ]
1694+ toJSON (QueryMoreLikeThisFieldQuery query) =
1695+ object [ "more_like_this_field" .= query ]
1697+ toJSON (QueryNestedQuery query) =
1698+ object [ "nested" .= query ]
1700+ toJSON (QueryPrefixQuery query) =
1701+ object [ "prefix" .= query ]
1703+ toJSON (QueryRangeQuery query) =
1704+ object [ "range" .= query ]
1706+ toJSON (QueryRegexpQuery query) =
1707+ object [ "regexp" .= query ]
1709+ toJSON (QuerySimpleQueryStringQuery query) =
1710+ object [ "simple_query_string" .= query ]
1713+omitNulls :: [(Text, Value)] -> Value
1714+omitNulls = object . filter notNull where
1715+ notNull (_, Null) = False
1716+ notNull (_, Array a) = (not . V.null) a
1720+instance ToJSON SimpleQueryStringQuery where
1721+ toJSON SimpleQueryStringQuery {..} =
1722+ omitNulls (base ++ maybeAdd)
1723+ where base = [ "query" .= simpleQueryStringQuery ]
1724+ maybeAdd = [ "fields" .= simpleQueryStringField
1725+ , "default_operator" .= simpleQueryStringOperator
1726+ , "analyzer" .= simpleQueryStringAnalyzer
1727+ , "flags" .= simpleQueryStringFlags
1728+ , "lowercase_expanded_terms" .= simpleQueryStringLowercaseExpanded
1729+ , "locale" .= simpleQueryStringLocale ]
1732+instance ToJSON FieldOrFields where
1733+ toJSON (FofField fieldName) =
1735+ toJSON (FofFields fieldNames) =
1738+instance ToJSON SimpleQueryFlag where
1739+ toJSON SimpleQueryAll = "ALL"
1740+ toJSON SimpleQueryNone = "NONE"
1741+ toJSON SimpleQueryAnd = "AND"
1742+ toJSON SimpleQueryOr = "OR"
1743+ toJSON SimpleQueryPrefix = "PREFIX"
1744+ toJSON SimpleQueryPhrase = "PHRASE"
1745+ toJSON SimpleQueryPrecedence = "PRECEDENCE"
1746+ toJSON SimpleQueryEscape = "ESCAPE"
1747+ toJSON SimpleQueryWhitespace = "WHITESPACE"
1748+ toJSON SimpleQueryFuzzy = "FUZZY"
1749+ toJSON SimpleQueryNear = "NEAR"
1750+ toJSON SimpleQuerySlop = "SLOP"
1753+instance ToJSON RegexpQuery where
1754+ toJSON (RegexpQuery (FieldName rqQueryField)
1755+ (Regexp regexpQueryQuery) rqQueryFlags
1757+ object [ rqQueryField .= omitNulls base ]
1758+ where base = [ "value" .= regexpQueryQuery
1759+ , "flags" .= rqQueryFlags
1760+ , "boost" .= rqQueryBoost ]
1763+instance ToJSON QueryStringQuery where
1764+ toJSON (QueryStringQuery qsQueryString
1765+ qsDefaultField qsOperator
1766+ qsAnalyzer qsAllowWildcard
1767+ qsLowercaseExpanded qsEnablePositionIncrements
1768+ qsFuzzyMaxExpansions qsFuzziness
1769+ qsFuzzyPrefixLength qsPhraseSlop
1770+ qsBoost qsAnalyzeWildcard
1771+ qsGeneratePhraseQueries qsMinimumShouldMatch
1772+ qsLenient qsLocale) =
1775+ base = [ "query" .= qsQueryString
1776+ , "default_field" .= qsDefaultField
1777+ , "default_operator" .= qsOperator
1778+ , "analyzer" .= qsAnalyzer
1779+ , "allow_leading_wildcard" .= qsAllowWildcard
1780+ , "lowercase_expanded_terms" .= qsLowercaseExpanded
1781+ , "enable_position_increments" .= qsEnablePositionIncrements
1782+ , "fuzzy_max_expansions" .= qsFuzzyMaxExpansions
1783+ , "fuzziness" .= qsFuzziness
1784+ , "fuzzy_prefix_length" .= qsFuzzyPrefixLength
1785+ , "phrase_slop" .= qsPhraseSlop
1786+ , "boost" .= qsBoost
1787+ , "analyze_wildcard" .= qsAnalyzeWildcard
1788+ , "auto_generate_phrase_queries" .= qsGeneratePhraseQueries
1789+ , "minimum_should_match" .= qsMinimumShouldMatch
1790+ , "lenient" .= qsLenient
1791+ , "locale" .= qsLocale ]
1794+instance ToJSON RangeQuery where
1795+ toJSON (RangeQuery (FieldName fieldName) range boost) =
1796+ object [ fieldName .= conjoined ]
1797+ where conjoined = [ "boost" .= boost ] ++ (rangeValueToPair range)
1800+instance ToJSON PrefixQuery where
1801+ toJSON (PrefixQuery (FieldName fieldName) queryValue boost) =
1802+ object [ fieldName .= omitNulls base ]
1803+ where base = [ "value" .= queryValue
1804+ , "boost" .= boost ]
1807+instance ToJSON NestedQuery where
1808+ toJSON (NestedQuery nqPath nqScoreType nqQuery) =
1809+ object [ "path" .= nqPath
1810+ , "score_mode" .= nqScoreType
1811+ , "query" .= nqQuery ]
1814+instance ToJSON MoreLikeThisFieldQuery where
1815+ toJSON (MoreLikeThisFieldQuery text (FieldName fieldName)
1816+ percent mtf mqt stopwords mindf maxdf
1817+ minwl maxwl boostTerms boost analyzer) =
1818+ object [ fieldName .= omitNulls base ]
1819+ where base = [ "like_text" .= text
1820+ , "percent_terms_to_match" .= percent
1821+ , "min_term_freq" .= mtf
1822+ , "max_query_terms" .= mqt
1823+ , "stop_words" .= stopwords
1824+ , "min_doc_freq" .= mindf
1825+ , "max_doc_freq" .= maxdf
1826+ , "min_word_length" .= minwl
1827+ , "max_word_length" .= maxwl
1828+ , "boost_terms" .= boostTerms
1830+ , "analyzer" .= analyzer ]
1833+instance ToJSON MoreLikeThisQuery where
1834+ toJSON (MoreLikeThisQuery text fields percent
1835+ mtf mqt stopwords mindf maxdf
1836+ minwl maxwl boostTerms boost analyzer) =
1838+ where base = [ "like_text" .= text
1839+ , "fields" .= fields
1840+ , "percent_terms_to_match" .= percent
1841+ , "min_term_freq" .= mtf
1842+ , "max_query_terms" .= mqt
1843+ , "stop_words" .= stopwords
1844+ , "min_doc_freq" .= mindf
1845+ , "max_doc_freq" .= maxdf
1846+ , "min_word_length" .= minwl
1847+ , "max_word_length" .= maxwl
1848+ , "boost_terms" .= boostTerms
1850+ , "analyzer" .= analyzer ]
1853+instance ToJSON IndicesQuery where
1854+ toJSON (IndicesQuery indices query noMatch) =
1855+ omitNulls [ "indices" .= indices
1856+ , "no_match_query" .= noMatch
1857+ , "query" .= query ]
1860+instance ToJSON HasParentQuery where
1861+ toJSON (HasParentQuery queryType query scoreType) =
1862+ omitNulls [ "parent_type" .= queryType
1863+ , "score_type" .= scoreType
1864+ , "query" .= query ]
1867+instance ToJSON HasChildQuery where
1868+ toJSON (HasChildQuery queryType query scoreType) =
1869+ omitNulls [ "query" .= query
1870+ , "score_type" .= scoreType
1871+ , "type" .= queryType ]
1874+instance ToJSON FuzzyQuery where
1875+ toJSON (FuzzyQuery (FieldName fieldName) queryText
1876+ prefixLength maxEx fuzziness boost) =
1877+ object [ fieldName .= omitNulls base ]
1878+ where base = [ "value" .= queryText
1879+ , "fuzziness" .= fuzziness
1880+ , "prefix_length" .= prefixLength
1882+ , "max_expansions" .= maxEx ]
1885+instance ToJSON FuzzyLikeFieldQuery where
1886+ toJSON (FuzzyLikeFieldQuery (FieldName fieldName)
1887+ fieldText maxTerms ignoreFreq fuzziness prefixLength
1889+ object [ fieldName .=
1890+ omitNulls [ "like_text" .= fieldText
1891+ , "max_query_terms" .= maxTerms
1892+ , "ignore_tf" .= ignoreFreq
1893+ , "fuzziness" .= fuzziness
1894+ , "prefix_length" .= prefixLength
1895+ , "analyzer" .= analyzer
1896+ , "boost" .= boost ]]
1899+instance ToJSON FuzzyLikeThisQuery where
1900+ toJSON (FuzzyLikeThisQuery fields text maxTerms
1901+ ignoreFreq fuzziness prefixLength boost analyzer) =
1903+ where base = [ "fields" .= fields
1904+ , "like_text" .= text
1905+ , "max_query_terms" .= maxTerms
1906+ , "ignore_tf" .= ignoreFreq
1907+ , "fuzziness" .= fuzziness
1908+ , "prefix_length" .= prefixLength
1909+ , "analyzer" .= analyzer
1910+ , "boost" .= boost ]
1913+instance ToJSON FilteredQuery where
1914+ toJSON (FilteredQuery query fFilter) =
1915+ object [ "query" .= query
1916+ , "filter" .= fFilter ]
1919+instance ToJSON DisMaxQuery where
1920+ toJSON (DisMaxQuery queries tiebreaker boost) =
1922+ where base = [ "queries" .= queries
1924+ , "tie_breaker" .= tiebreaker ]
1927+instance ToJSON CommonTermsQuery where
1928+ toJSON (CommonTermsQuery (FieldName fieldName)
1929+ (QueryString query) cf lfo hfo msm
1930+ boost analyzer disableCoord) =
1931+ object [fieldName .= omitNulls base ]
1932+ where base = [ "query" .= query
1933+ , "cutoff_frequency" .= cf
1934+ , "low_freq_operator" .= lfo
1935+ , "minimum_should_match" .= msm
1937+ , "analyzer" .= analyzer
1938+ , "disable_coord" .= disableCoord
1939+ , "high_freq_operator" .= hfo ]
1942+instance ToJSON CommonMinimumMatch where
1943+ toJSON (CommonMinimumMatch mm) = toJSON mm
1944+ toJSON (CommonMinimumMatchHighLow (MinimumMatchHighLow lowF highF)) =
1945+ object [ "low_freq" .= lowF
1946+ , "high_freq" .= highF ]
1948+instance ToJSON BoostingQuery where
1949+ toJSON (BoostingQuery bqPositiveQuery bqNegativeQuery bqNegativeBoost) =
1950+ object [ "positive" .= bqPositiveQuery
1951+ , "negative" .= bqNegativeQuery
1952+ , "negative_boost" .= bqNegativeBoost ]
1955+instance ToJSON BoolQuery where
1956+ toJSON (BoolQuery mustM notM shouldM bqMin boost disableCoord) =
1958+ where base = [ "must" .= mustM
1959+ , "must_not" .= notM
1960+ , "should" .= shouldM
1961+ , "minimum_should_match" .= bqMin
1963+ , "disable_coord" .= disableCoord ]
1966+instance ToJSON MatchQuery where
1967+ toJSON (MatchQuery (FieldName fieldName)
1968+ (QueryString mqQueryString) booleanOperator
1969+ zeroTermsQuery cutoffFrequency matchQueryType
1970+ analyzer maxExpansions lenient) =
1971+ object [ fieldName .= omitNulls base ]
1972+ where base = [ "query" .= mqQueryString
1973+ , "operator" .= booleanOperator
1974+ , "zero_terms_query" .= zeroTermsQuery
1975+ , "cutoff_frequency" .= cutoffFrequency
1976+ , "type" .= matchQueryType
1977+ , "analyzer" .= analyzer
1978+ , "max_expansions" .= maxExpansions
1979+ , "lenient" .= lenient ]
1982+instance ToJSON MultiMatchQuery where
1983+ toJSON (MultiMatchQuery fields (QueryString query) boolOp
1984+ ztQ tb mmqt cf analyzer maxEx lenient) =
1985+ object ["multi_match" .= omitNulls base]
1986+ where base = [ "fields" .= fmap toJSON fields
1988+ , "operator" .= boolOp
1989+ , "zero_terms_query" .= ztQ
1990+ , "tiebreaker" .= tb
1992+ , "cutoff_frequency" .= cf
1993+ , "analyzer" .= analyzer
1994+ , "max_expansions" .= maxEx
1995+ , "lenient" .= lenient ]
1998+instance ToJSON MultiMatchQueryType where
1999+ toJSON MultiMatchBestFields = "best_fields"
2000+ toJSON MultiMatchMostFields = "most_fields"
2001+ toJSON MultiMatchCrossFields = "cross_fields"
2002+ toJSON MultiMatchPhrase = "phrase"
2003+ toJSON MultiMatchPhrasePrefix = "phrase_prefix"
2005+instance ToJSON BooleanOperator where
2006+ toJSON And = String "and"
2007+ toJSON Or = String "or"
2009+instance ToJSON ZeroTermsQuery where
2010+ toJSON ZeroTermsNone = String "none"
2011+ toJSON ZeroTermsAll = String "all"
2013+instance ToJSON MatchQueryType where
2014+ toJSON MatchPhrase = "phrase"
2015+ toJSON MatchPhrasePrefix = "phrase_prefix"
2017+instance ToJSON FieldName where
2018+ toJSON (FieldName fieldName) = String fieldName
2020+instance ToJSON ReplicaCount
2021+instance ToJSON ShardCount
2022+instance ToJSON CutoffFrequency
2023+instance ToJSON Analyzer
2024+instance ToJSON MaxExpansions
2025+instance ToJSON Lenient
2026+instance ToJSON Boost
2027+instance ToJSON Version
2028+instance ToJSON Tiebreaker
2029+instance ToJSON MinimumMatch
2030+instance ToJSON DisableCoord
2031+instance ToJSON PrefixLength
2032+instance ToJSON Fuzziness
2033+instance ToJSON IgnoreTermFrequency
2034+instance ToJSON MaxQueryTerms
2035+instance ToJSON TypeName
2036+instance ToJSON IndexName
2037+instance ToJSON TemplateName
2038+instance ToJSON TemplatePattern
2039+instance ToJSON BoostTerms
2040+instance ToJSON MaxWordLength
2041+instance ToJSON MinWordLength
2042+instance ToJSON MaxDocFrequency
2043+instance ToJSON MinDocFrequency
2044+instance ToJSON PhraseSlop
2045+instance ToJSON StopWord
2046+instance ToJSON QueryPath
2047+instance ToJSON MinimumTermFrequency
2048+instance ToJSON PercentMatch
2049+instance ToJSON MappingName
2050+instance ToJSON DocId
2051+instance ToJSON QueryString
2052+instance ToJSON AllowLeadingWildcard
2053+instance ToJSON LowercaseExpanded
2054+instance ToJSON AnalyzeWildcard
2055+instance ToJSON GeneratePhraseQueries
2056+instance ToJSON Locale
2057+instance ToJSON EnablePositionIncrements
2058+instance FromJSON Version
2059+instance FromJSON IndexName
2060+instance FromJSON MappingName
2061+instance FromJSON DocId
2064+instance FromJSON Status where
2065+ parseJSON (Object v) = Status <$>
2071+ parseJSON _ = empty
2074+instance ToJSON IndexSettings where
2075+ toJSON (IndexSettings s r) = object ["settings" .=
2077+ object ["number_of_shards" .= s, "number_of_replicas" .= r]
2081+instance ToJSON IndexTemplate where
2082+ toJSON (IndexTemplate p s m) = merge
2083+ (object [ "template" .= p
2084+ , "mappings" .= foldl' merge (object []) m
2088+ merge (Object o1) (Object o2) = toJSON $ HM.union o1 o2
2090+ merge _ _ = undefined
2092+instance (FromJSON a) => FromJSON (EsResult a) where
2093+ parseJSON jsonVal@(Object v) = do
2094+ found <- v .:? "found" .!= False
2096+ then parseJSON jsonVal
2097+ else return Nothing
2098+ EsResult <$> v .: "_index" <*>
2102+ parseJSON _ = empty
2104+instance (FromJSON a) => FromJSON (EsResultFound a) where
2105+ parseJSON (Object v) = EsResultFound <$>
2106+ v .: "_version" <*>
2108+ parseJSON _ = empty
2110+instance ToJSON Search where
2111+ toJSON (Search query sFilter sort searchAggs highlight sTrackSortScores sFrom sSize _ sFields) =
2112+ omitNulls [ "query" .= query
2113+ , "filter" .= sFilter
2115+ , "aggregations" .= searchAggs
2116+ , "highlight" .= highlight
2119+ , "track_scores" .= sTrackSortScores
2120+ , "fields" .= sFields]
2123+instance ToJSON FieldHighlight where
2124+ toJSON (FieldHighlight (FieldName fName) (Just fSettings)) =
2125+ object [ fName .= fSettings ]
2126+ toJSON (FieldHighlight (FieldName fName) Nothing) =
2127+ object [ fName .= emptyObject ]
2129+instance ToJSON Highlights where
2130+ toJSON (Highlights global fields) =
2131+ omitNulls (("fields" .= fields)
2132+ : highlightSettingsPairs global)
2134+instance ToJSON HighlightSettings where
2135+ toJSON hs = omitNulls (highlightSettingsPairs (Just hs))
2137+highlightSettingsPairs :: Maybe HighlightSettings -> [Pair]
2138+highlightSettingsPairs Nothing = []
2139+highlightSettingsPairs (Just (Plain plh)) = plainHighPairs (Just plh)
2140+highlightSettingsPairs (Just (Postings ph)) = postHighPairs (Just ph)
2141+highlightSettingsPairs (Just (FastVector fvh)) = fastVectorHighPairs (Just fvh)
2144+plainHighPairs :: Maybe PlainHighlight -> [Pair]
2145+plainHighPairs Nothing = []
2146+plainHighPairs (Just (PlainHighlight plCom plNonPost)) =
2147+ [ "type" .= String "plain"]
2148+ ++ commonHighlightPairs plCom
2149+ ++ nonPostingsToPairs plNonPost
2151+postHighPairs :: Maybe PostingsHighlight -> [Pair]
2152+postHighPairs Nothing = []
2153+postHighPairs (Just (PostingsHighlight pCom)) =
2154+ ("type" .= String "postings")
2155+ : commonHighlightPairs pCom
2157+fastVectorHighPairs :: Maybe FastVectorHighlight -> [Pair]
2158+fastVectorHighPairs Nothing = []
2159+fastVectorHighPairs (Just
2160+ (FastVectorHighlight fvCom fvNonPostSettings fvBoundChars
2161+ fvBoundMaxScan fvFragOff fvMatchedFields
2163+ [ "type" .= String "fvh"
2164+ , "boundary_chars" .= fvBoundChars
2165+ , "boundary_max_scan" .= fvBoundMaxScan
2166+ , "fragment_offset" .= fvFragOff
2167+ , "matched_fields" .= fvMatchedFields
2168+ , "phraseLimit" .= fvPhraseLim]
2169+ ++ commonHighlightPairs fvCom
2170+ ++ nonPostingsToPairs fvNonPostSettings
2172+commonHighlightPairs :: Maybe CommonHighlight -> [Pair]
2173+commonHighlightPairs Nothing = []
2174+commonHighlightPairs (Just (CommonHighlight chScore chForceSource chTag chEncoder
2175+ chNoMatchSize chHighlightQuery
2176+ chRequireFieldMatch)) =
2177+ [ "order" .= chScore
2178+ , "force_source" .= chForceSource
2179+ , "encoder" .= chEncoder
2180+ , "no_match_size" .= chNoMatchSize
2181+ , "highlight_query" .= chHighlightQuery
2182+ , "require_fieldMatch" .= chRequireFieldMatch]
2183+ ++ highlightTagToPairs chTag
2186+nonPostingsToPairs :: Maybe NonPostings -> [Pair]
2187+nonPostingsToPairs Nothing = []
2188+nonPostingsToPairs (Just (NonPostings npFragSize npNumOfFrags)) =
2189+ [ "fragment_size" .= npFragSize
2190+ , "number_of_fragments" .= npNumOfFrags]
2194+instance ToJSON HighlightEncoder where
2195+ toJSON DefaultEncoder = String "default"
2196+ toJSON HTMLEncoder = String "html"
2198+highlightTagToPairs :: Maybe HighlightTag -> [Pair]
2199+highlightTagToPairs (Just (TagSchema _)) = [ "scheme" .= String "default"]
2200+highlightTagToPairs (Just (CustomTags (pre, post))) = [ "pre_tags" .= pre
2201+ , "post_tags" .= post]
2202+highlightTagToPairs Nothing = []
2204+instance ToJSON SortSpec where
2205+ toJSON (DefaultSortSpec
2206+ (DefaultSort (FieldName dsSortFieldName) dsSortOrder dsIgnoreUnmapped
2207+ dsSortMode dsMissingSort dsNestedFilter)) =
2208+ object [dsSortFieldName .= omitNulls base] where
2209+ base = [ "order" .= dsSortOrder
2210+ , "ignore_unmapped" .= dsIgnoreUnmapped
2211+ , "mode" .= dsSortMode
2212+ , "missing" .= dsMissingSort
2213+ , "nested_filter" .= dsNestedFilter ]
2215+ toJSON (GeoDistanceSortSpec gdsSortOrder (GeoPoint (FieldName field) gdsLatLon) units) =
2216+ object [ "unit" .= units
2217+ , field .= gdsLatLon
2218+ , "order" .= gdsSortOrder ]
2221+instance ToJSON SortOrder where
2222+ toJSON Ascending = String "asc"
2223+ toJSON Descending = String "desc"
2226+instance ToJSON SortMode where
2227+ toJSON SortMin = String "min"
2228+ toJSON SortMax = String "max"
2229+ toJSON SortSum = String "sum"
2230+ toJSON SortAvg = String "avg"
2233+instance ToJSON Missing where
2234+ toJSON LastMissing = String "_last"
2235+ toJSON FirstMissing = String "_first"
2236+ toJSON (CustomMissing txt) = String txt
2239+instance ToJSON ScoreType where
2240+ toJSON ScoreTypeMax = "max"
2241+ toJSON ScoreTypeAvg = "avg"
2242+ toJSON ScoreTypeSum = "sum"
2243+ toJSON ScoreTypeNone = "none"
2246+instance ToJSON Distance where
2247+ toJSON (Distance dCoefficient dUnit) =
2248+ String boltedTogether where
2249+ coefText = showText dCoefficient
2250+ (String unitText) = toJSON dUnit
2251+ boltedTogether = mappend coefText unitText
2254+instance ToJSON DistanceUnit where
2255+ toJSON Miles = String "mi"
2256+ toJSON Yards = String "yd"
2257+ toJSON Feet = String "ft"
2258+ toJSON Inches = String "in"
2259+ toJSON Kilometers = String "km"
2260+ toJSON Meters = String "m"
2261+ toJSON Centimeters = String "cm"
2262+ toJSON Millimeters = String "mm"
2263+ toJSON NauticalMiles = String "nmi"
2266+instance ToJSON DistanceType where
2267+ toJSON Arc = String "arc"
2268+ toJSON SloppyArc = String "sloppy_arc"
2269+ toJSON Plane = String "plane"
2272+instance ToJSON OptimizeBbox where
2273+ toJSON NoOptimizeBbox = String "none"
2274+ toJSON (OptimizeGeoFilterType gft) = toJSON gft
2277+instance ToJSON GeoBoundingBoxConstraint where
2278+ toJSON (GeoBoundingBoxConstraint
2279+ (FieldName gbbcGeoBBField) gbbcConstraintBox cache type') =
2280+ object [gbbcGeoBBField .= gbbcConstraintBox
2281+ , "_cache" .= cache
2285+instance ToJSON GeoFilterType where
2286+ toJSON GeoFilterMemory = String "memory"
2287+ toJSON GeoFilterIndexed = String "indexed"
2290+instance ToJSON GeoBoundingBox where
2291+ toJSON (GeoBoundingBox gbbTopLeft gbbBottomRight) =
2292+ object ["top_left" .= gbbTopLeft
2293+ , "bottom_right" .= gbbBottomRight]
2296+instance ToJSON LatLon where
2297+ toJSON (LatLon lLat lLon) =
2298+ object ["lat" .= lLat
2302+-- index for smaller ranges, fielddata for longer ranges
2303+instance ToJSON RangeExecution where
2304+ toJSON RangeExecutionIndex = "index"
2305+ toJSON RangeExecutionFielddata = "fielddata"
2308+instance ToJSON RegexpFlags where
2309+ toJSON AllRegexpFlags = String "ALL"
2310+ toJSON NoRegexpFlags = String "NONE"
2311+ toJSON (SomeRegexpFlags (h :| fs)) = String $ T.intercalate "|" flagStrs
2312+ where flagStrs = map flagStr . nub $ h:fs
2313+ flagStr AnyString = "ANYSTRING"
2314+ flagStr Automaton = "AUTOMATON"
2315+ flagStr Complement = "COMPLEMENT"
2316+ flagStr Empty = "EMPTY"
2317+ flagStr Intersection = "INTERSECTION"
2318+ flagStr Interval = "INTERVAL"
2320+instance ToJSON Term where
2321+ toJSON (Term field value) = object ["term" .= object
2325+instance ToJSON BoolMatch where
2326+ toJSON (MustMatch term cache) = object ["must" .= term,
2328+ toJSON (MustNotMatch term cache) = object ["must_not" .= term,
2330+ toJSON (ShouldMatch terms cache) = object ["should" .= fmap toJSON terms,
529instance (FromJSON a) => FromJSON (SearchResult a) where
2334instance (FromJSON a) => FromJSON (SearchResult a) where
530 parseJSON (Object v) = SearchResult <$>
2335 parseJSON (Object v) = SearchResult <$>
@@ -533,10 +2338,52 @@ instance (FromJSON a) => FromJSON (SearchResult a) where
533 v .: "_shards" <*>
2338 v .: "_shards" <*>
534 v .: "hits" <*>
2339 v .: "hits" <*>
535 v .:? "aggregations" <*>
2340 v .:? "aggregations" <*>
536− v .:? "_scroll_id" <*>
2341+ v .:? "_scroll_id"
538 parseJSON _ = empty
2342 parseJSON _ = empty
540−newtype ScrollId =
2344+instance (FromJSON a) => FromJSON (SearchHits a) where
541− ScrollId Text
2345+ parseJSON (Object v) = SearchHits <$>
542− deriving (Eq, Show, Ord, ToJSON, FromJSON)
2346+ v .: "total" <*>
2347+ v .: "max_score" <*>
2349+ parseJSON _ = empty
2351+instance (FromJSON a) => FromJSON (Hit a) where
2352+ parseJSON (Object v) = Hit <$>
2359+ parseJSON _ = empty
2361+instance FromJSON ShardResult where
2362+ parseJSON (Object v) = ShardResult <$>
2364+ v .: "successful" <*>
2366+ parseJSON _ = empty
2369+instance FromJSON DocVersion where
2372+ maybe (fail "DocVersion out of range") return $ mkDocVersion i
2374+instance Bounded DocVersion where
2375+ minBound = DocVersion 1
2376+ maxBound = DocVersion 9200000000000000000 -- 9.2e+18
2378+instance Enum DocVersion where
2380+ | x /= maxBound = DocVersion (succ $ docVersionNumber x)
2381+ | otherwise = succError "DocVersion"
2383+ | x /= minBound = DocVersion (pred $ docVersionNumber x)
2384+ | otherwise = predError "DocVersion"
2386+ fromMaybe (error $ show i ++ " out of DocVersion range") $ mkDocVersion i
2387+ fromEnum = docVersionNumber
2388+ enumFrom = boundedEnumFrom
2389+ enumFromThen = boundedEnumFromThen