@@ -1,10 +1,8 @@
1−{-# LANGUAGE DeriveDataTypeable #-}
2−{-# LANGUAGE DeriveGeneric #-}
31{-# LANGUAGE FlexibleContexts #-}
42{-# LANGUAGE FlexibleInstances #-}
53{-# LANGUAGE GeneralizedNewtypeDeriving #-}
64{-# LANGUAGE MultiParamTypeClasses #-}
7−{-# LANGUAGE NoMonomorphismRestriction #-}
5+{-# LANGUAGE NamedFieldPuns #-}
86{-# LANGUAGE OverloadedStrings #-}
97{-# LANGUAGE RecordWildCards #-}
108{-# LANGUAGE UndecidableInstances #-}
@@ -12,11 +10,11 @@
1210-------------------------------------------------------------------------------
1311-- |
1412-- Module : Database.Bloodhound.Types
15−-- Copyright : (C) 2014 Chris Allen
13+-- Copyright : (C) 2014, 2018 Chris Allen
1614-- License : BSD-style (see the file LICENSE)
1715-- Maintainer : Chris Allen <cma@bitemyapp.com
1816-- Stability : provisional
19−-- Portability : DeriveGeneric, RecordWildCards
17+-- Portability : RecordWildCards
2018--
2119-- Data types for describing actions and data structures performed to interact
2220-- with Elasticsearch. The two main buckets your queries against Elasticsearch
@@ -44,26 +42,53 @@ module Database.Bloodhound.Types
4442 , mkTermsAggregation
4543 , mkTermsScriptAggregation
4644 , mkDateHistogram
45+ , mkCardinalityAggregation
4746 , mkDocVersion
47+ , mkStatsAggregation
48+ , mkExtendedStatsAggregation
4849 , docVersionNumber
50+ , toMissing
4951 , toTerms
5052 , toDateHistogram
53+ , toTopHits
5154 , omitNulls
5255 , BH(..)
5356 , runBH
54− , BHEnv(..)
57+ , BHEnv
58+ , bhServer
59+ , bhManager
60+ , bhRequestHook
61+ , mkBHEnv
5562 , MonadBH(..)
5663 , Version(..)
64+ , VersionNumber(..)
65+ , MaybeNA(..)
66+ , BuildHash(..)
5767 , Status(..)
5868 , Existence(..)
5969 , NullValue(..)
6070 , IndexSettings(..)
71+ , UpdatableIndexSetting(..)
72+ , IndexSettingsSummary(..)
73+ , AllocationPolicy(..)
74+ , Compression(..)
75+ , ReplicaBounds(..)
76+ , Bytes(..)
77+ , gigabytes
78+ , megabytes
79+ , kilobytes
80+ , FSType(..)
81+ , InitialShardCount(..)
82+ , NodeAttrFilter(..)
83+ , NodeAttrName(..)
84+ , CompoundFormat(..)
6185 , IndexTemplate(..)
6286 , Server(..)
6387 , Reply
6488 , EsResult(..)
6589 , EsResultFound(..)
6690 , EsError(..)
91+ , EsProtocolException(..)
6792 , IndexAlias(..)
6893 , IndexAliasName(..)
6994 , IndexAliasAction(..)
@@ -95,8 +120,8 @@ module Database.Bloodhound.Types
95120 , Pattern(..)
96121 , ShardResult(..)
97122 , Hit(..)
123+ , HitFields(..)
98124 , Filter(..)
99− , Seminearring(..)
100125 , BoolMatch(..)
101126 , Term(..)
102127 , GeoPoint(..)
@@ -123,8 +148,22 @@ module Database.Bloodhound.Types
123148 , RegexpFlags(..)
124149 , RegexpFlag(..)
125150 , FieldName(..)
151+ , ScriptFields(..)
152+ , ScriptFieldName
153+ , ScriptFieldValue
126154 , Script(..)
155+ , ScriptLanguage(..)
156+ , ScriptInline(..)
157+ , ScriptId(..)
158+ , ScriptParams(..)
159+ , ScriptParamName
160+ , ScriptParamValue
127161 , IndexName(..)
162+ , IndexSelection(..)
163+ , NodeSelection(..)
164+ , NodeSelector(..)
165+ , ForceMergeIndexSettings(..)
166+ , defaultForceMergeIndexSettings
128167 , TemplateName(..)
129168 , TemplatePattern(..)
130169 , MappingName(..)
@@ -148,8 +187,19 @@ module Database.Bloodhound.Types
148187 , BoolQuery(..)
149188 , BoostingQuery(..)
150189 , CommonTermsQuery(..)
190+ , FunctionScoreQuery(..)
191+ , BoostMode(..)
192+ , ScoreMode(..)
193+ , FunctionScoreFunctions(..)
194+ , ComponentFunctionScoreFunction(..)
195+ , FunctionScoreFunction(..)
196+ , Weight(..)
197+ , Seed(..)
198+ , FieldValueFactor(..)
199+ , Factor(..)
200+ , FactorModifier(..)
201+ , FactorMissingFieldValue(..)
151202 , DisMaxQuery(..)
152− , FilteredQuery(..)
153203 , FuzzyLikeThisQuery(..)
154204 , FuzzyLikeFieldQuery(..)
155205 , FuzzyQuery(..)
@@ -165,10 +215,16 @@ module Database.Bloodhound.Types
165215 , RangeQuery(..)
166216 , RegexpQuery(..)
167217 , QueryString(..)
218+ , TemplateQueryInline(..)
219+ , TemplateQueryKeyValuePairs(..)
220+ , WildcardQuery(..)
168221 , BooleanOperator(..)
169222 , ZeroTermsQuery(..)
170223 , CutoffFrequency(..)
171224 , Analyzer(..)
225+ , Tokenizer(..)
226+ , TokenFilter(..)
227+ , CharFilter(..)
172228 , MaxExpansions(..)
173229 , Lenient(..)
174230 , MatchQueryType(..)
@@ -215,15 +271,108 @@ module Database.Bloodhound.Types
215271 , CollectionMode(..)
216272 , TermOrder(..)
217273 , TermInclusion(..)
274+ , SnapshotRepoSelection(..)
275+ , GenericSnapshotRepo(..)
276+ , SnapshotRepo(..)
277+ , SnapshotRepoConversionError(..)
278+ , SnapshotRepoType(..)
279+ , GenericSnapshotRepoSettings(..)
280+ , SnapshotRepoUpdateSettings(..)
281+ , defaultSnapshotRepoUpdateSettings
282+ , SnapshotRepoName(..)
283+ , SnapshotRepoPattern(..)
284+ , SnapshotVerification(..)
285+ , SnapshotNodeVerification(..)
286+ , FullNodeId(..)
287+ , NodeName(..)
288+ , ClusterName(..)
289+ , NodesInfo(..)
290+ , NodesStats(..)
291+ , NodeStats(..)
292+ , NodeBreakersStats(..)
293+ , NodeBreakerStats(..)
294+ , NodeHTTPStats(..)
295+ , NodeTransportStats(..)
296+ , NodeFSStats(..)
297+ , NodeDataPathStats(..)
298+ , NodeFSTotalStats(..)
299+ , NodeNetworkStats(..)
300+ , NodeThreadPoolsStats(..)
301+ , NodeThreadPoolStats(..)
302+ , NodeJVMStats(..)
303+ , JVMBufferPoolStats(..)
304+ , JVMGCStats(..)
305+ , JVMPoolStats(..)
306+ , NodeProcessStats(..)
307+ , NodeOSStats(..)
308+ , LoadAvgs(..)
309+ , NodeIndicesStats(..)
310+ , EsAddress(..)
311+ , PluginName(..)
312+ , NodeInfo(..)
313+ , NodePluginInfo(..)
314+ , NodeHTTPInfo(..)
315+ , NodeTransportInfo(..)
316+ , BoundTransportAddress(..)
317+ , NodeNetworkInfo(..)
318+ , MacAddress(..)
319+ , NetworkInterfaceName(..)
320+ , NodeNetworkInterface(..)
321+ , NodeThreadPoolsInfo(..)
322+ , NodeThreadPoolInfo(..)
323+ , ThreadPoolSize(..)
324+ , ThreadPoolType(..)
325+ , NodeJVMInfo(..)
326+ , JVMMemoryPool(..)
327+ , JVMGCCollector(..)
328+ , JVMMemoryInfo(..)
329+ , PID(..)
330+ , NodeOSInfo(..)
331+ , CPUInfo(..)
332+ , NodeProcessInfo(..)
333+ , FsSnapshotRepo(..)
334+ , SnapshotCreateSettings(..)
335+ , defaultSnapshotCreateSettings
336+ , SnapshotSelection(..)
337+ , SnapshotPattern(..)
338+ , SnapshotInfo(..)
339+ , SnapshotShardFailure(..)
340+ , ShardId(..)
341+ , SnapshotName(..)
342+ , SnapshotState(..)
343+ , SnapshotRestoreSettings(..)
344+ , defaultSnapshotRestoreSettings
345+ , RestoreRenamePattern(..)
346+ , RestoreRenameToken(..)
347+ , RRGroupRefNum
348+ , rrGroupRefNum
349+ , mkRRGroupRefNum
350+ , RestoreIndexSettings(..)
351+ , Suggest(..)
352+ , SuggestType(..)
353+ , PhraseSuggester(..)
354+ , PhraseSuggesterHighlighter(..)
355+ , PhraseSuggesterCollate(..)
356+ , mkPhraseSuggester
357+ , SuggestOptions(..)
358+ , SuggestResponse(..)
359+ , NamedSuggestionResponse(..)
360+ , DirectGenerators(..)
361+ , mkDirectGenerators
362+ , DirectGeneratorSuggestModeTypes (..)
218363
219364 , Aggregation(..)
220365 , Aggregations
221366 , AggregationResults
367+ , BucketValue(..)
222368 , Bucket(..)
223369 , BucketAggregation(..)
224370 , TermsAggregation(..)
371+ , MissingAggregation(..)
225372 , ValueCountAggregation(..)
226373 , FilterAggregation(..)
374+ , CardinalityAggregation(..)
375+ , MaxAggregation(..)
227376 , DateHistogramAggregation(..)
228377 , DateRangeAggregation(..)
229378 , DateRangeAggRange(..)
@@ -231,6 +380,9 @@ module Database.Bloodhound.Types
231380 , DateMathAnchor(..)
232381 , DateMathModifier(..)
233382 , DateMathUnit(..)
383+ , TopHitsAggregation(..)
384+ , StatisticsAggregation(..)
385+ , SearchAfterKey
234386
235387 , Highlights(..)
236388 , FieldHighlight(..)
@@ -244,546 +396,36 @@ module Database.Bloodhound.Types
244396 , HighlightTag(..)
245397 , HitHighlight
246398
399+ , MissingResult(..)
247400 , TermsResult(..)
248401 , DateHistogramResult(..)
249402 , DateRangeResult(..)
250− ) where
251−
252−import Control.Applicative
253−import Control.Monad.Catch
254−import Control.Monad.Except
255−import Control.Monad.Reader
256−import Control.Monad.State
257−import Control.Monad.Writer
258−import Data.Aeson
259−import Data.Aeson.Types (Pair, Parser, emptyObject,
260− parseMaybe)
261−import qualified Data.ByteString.Lazy.Char8 as L
262−import Data.Char
263−import Data.Hashable (Hashable)
264−import qualified Data.HashMap.Strict as HM
265−import Data.List (foldl', nub)
266−import Data.List.NonEmpty (NonEmpty (..), toList)
267−import qualified Data.Map.Strict as M
268−import Data.Maybe
269−import Data.Text (Text)
270−import qualified Data.Text as T
271−import Data.Time.Calendar
272−import Data.Time.Clock (UTCTime)
273−import Data.Time.Clock.POSIX
274−import qualified Data.Traversable as DT
275−import Data.Typeable (Typeable)
276−import qualified Data.Vector as V
277−import GHC.Enum
278−import GHC.Generics (Generic)
279−import Network.HTTP.Client
280−import qualified Network.HTTP.Types.Method as NHTM
281−
282−import Database.Bloodhound.Types.Class
283−
284−-- $setup
285−-- >>> :set -XOverloadedStrings
286−-- >>> import Database.Bloodhound
287−-- >>> let testServer = (Server "http://localhost:9200")
288−-- >>> let testIndex = IndexName "twitter"
289−-- >>> let testMapping = MappingName "tweet"
290−-- >>> let defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
291−
292−-- defaultIndexSettings is exported by Database.Bloodhound as well
293−-- no trailing slashes in servers, library handles building the path.
294−
295−{-| Common environment for Elasticsearch calls. Connections will be
296− pipelined according to the provided HTTP connection manager.
297−-}
298−data BHEnv = BHEnv { bhServer :: Server
299− , bhManager :: Manager
300− }
301−
302−{-| All API calls to Elasticsearch operate within
303− MonadBH. The idea is that it can be easily embedded in your
304− own monad transformer stack. A default instance for a ReaderT and
305− alias 'BH' is provided for the simple case.
306−-}
307−class (Functor m, Applicative m, MonadIO m) => MonadBH m where
308− getBHEnv :: m BHEnv
309−
310−newtype BH m a = BH {
311− unBH :: ReaderT BHEnv m a
312− } deriving ( Functor
313− , Applicative
314− , Monad
315− , MonadIO
316− , MonadState s
317− , MonadWriter w
318− , MonadError e
319− , Alternative
320− , MonadPlus
321− , MonadFix
322− , MonadThrow
323− , MonadCatch
324− , MonadMask)
325−
326−instance MonadTrans BH where
327− lift = BH . lift
328−
329−instance (MonadReader r m) => MonadReader r (BH m) where
330− ask = lift ask
331− local f (BH (ReaderT m)) = BH $ ReaderT $ \r ->
332− local f (m r)
333−
334−instance (Functor m, Applicative m, MonadIO m) => MonadBH (BH m) where
335− getBHEnv = BH getBHEnv
336−
337−
338−instance (Functor m, Applicative m, MonadIO m) => MonadBH (ReaderT BHEnv m) where
339− getBHEnv = ask
340−
341−runBH :: BHEnv -> BH m a -> m a
342−runBH e f = runReaderT (unBH f) e
343−
344−{-| 'Version' is embedded in 'Status' -}
345−data Version = Version { number :: Text
346− , build_hash :: Text
347− , build_timestamp :: UTCTime
348− , build_snapshot :: Bool
349− , lucene_version :: Text } deriving (Eq, Show, Generic, Typeable)
350−
351−{-| 'Status' is a data type for describing the JSON body returned by
352− Elasticsearch when you query its status. This was deprecated in 1.2.0.
353−
354− <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-status.html#indices-status>
355−-}
356−
357−data Status = Status { ok :: Maybe Bool
358− , status :: Int
359− , name :: Text
360− , version :: Version
361− , tagline :: Text } deriving (Eq, Show)
362−
363−{-| 'IndexSettings' is used to configure the shards and replicas when you create
364− an Elasticsearch Index.
365−
366− <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html>
367−-}
368−
369−data IndexSettings =
370− IndexSettings { indexShards :: ShardCount
371− , indexReplicas :: ReplicaCount } deriving (Eq, Show)
372−
373−{-| 'defaultIndexSettings' is an 'IndexSettings' with 3 shards and 2 replicas. -}
374−defaultIndexSettings :: IndexSettings
375−defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
376−
377−{-| 'Reply' and 'Method' are type synonyms from 'Network.HTTP.Types.Method.Method' -}
378−type Reply = Network.HTTP.Client.Response L.ByteString
379−type Method = NHTM.Method
380−
381−{-| 'OpenCloseIndex' is a sum type for opening and closing indices.
382−
383− <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-open-close.html>
384−-}
385−data OpenCloseIndex = OpenIndex | CloseIndex deriving (Eq, Show)
386−
387−data FieldType = GeoPointType
388− | GeoShapeType
389− | FloatType
390− | IntegerType
391− | LongType
392− | ShortType
393− | ByteType deriving (Eq, Show)
394−
395−data FieldDefinition =
396− FieldDefinition { fieldType :: FieldType } deriving (Eq, Show)
397−
398−{-| An 'IndexTemplate' defines a template that will automatically be
399− applied to new indices created. The templates include both
400− 'IndexSettings' and mappings, and a simple 'TemplatePattern' that
401− controls if the template will be applied to the index created.
402− Specify mappings as follows: @[toJSON TweetMapping, ...]@
403−
404− https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-templates.html
405−-}
406−data IndexTemplate =
407− IndexTemplate { templatePattern :: TemplatePattern
408− , templateSettings :: Maybe IndexSettings
409− , templateMappings :: [Value]
410− }
411−
412−data MappingField =
413− MappingField { mappingFieldName :: FieldName
414− , fieldDefinition :: FieldDefinition } deriving (Eq, Show)
415−
416−{-| Support for type reification of 'Mapping's is currently incomplete, for
417− now the mapping API verbiage expects a 'ToJSON'able blob.
418−
419− Indexes have mappings, mappings are schemas for the documents contained in the
420− index. I'd recommend having only one mapping per index, always having a mapping,
421− and keeping different kinds of documents separated if possible.
422−-}
423−data Mapping = Mapping { typeName :: TypeName
424− , mappingFields :: [MappingField] } deriving (Eq, Show)
425−
426−{-| 'BulkOperation' is a sum type for expressing the four kinds of bulk
427− operation index, create, delete, and update. 'BulkIndex' behaves like an
428− "upsert", 'BulkCreate' will fail if a document already exists at the DocId.
429−
430− <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-bulk.html#docs-bulk>
431−-}
432−data BulkOperation =
433− BulkIndex IndexName MappingName DocId Value
434− | BulkCreate IndexName MappingName DocId Value
435− | BulkDelete IndexName MappingName DocId
436− | BulkUpdate IndexName MappingName DocId Value deriving (Eq, Show)
437−
438−{-| 'EsResult' describes the standard wrapper JSON document that you see in
439− successful Elasticsearch lookups or lookups that couldn't find the document.
440−-}
441−data EsResult a = EsResult { _index :: Text
442− , _type :: Text
443− , _id :: Text
444− , foundResult :: Maybe (EsResultFound a)} deriving (Eq, Show)
445−
446−{-| 'EsResultFound' contains the document and its metadata inside of an
447− 'EsResult' when the document was successfully found.
448−-}
449−data EsResultFound a = EsResultFound { _version :: DocVersion
450− , _source :: a } deriving (Eq, Show)
451−
452−{-| 'EsError' is the generic type that will be returned when there was a
453− problem. If you can't parse the expected response, its a good idea to
454− try parsing this.
455−-}
456−data EsError = EsError { errorStatus :: Int
457− , errorMessage :: Text } deriving (Eq, Show)
458−
459−data IndexAlias = IndexAlias { srcIndex :: IndexName
460− , indexAlias :: IndexAliasName } deriving (Eq, Show)
461−
462−newtype IndexAliasName = IndexAliasName { indexAliasName :: IndexName } deriving (Eq, Show, ToJSON)
463−
464−data IndexAliasAction = AddAlias IndexAlias IndexAliasCreate
465− | RemoveAlias IndexAlias deriving (Show, Eq, Typeable)
466−
467−data IndexAliasCreate = IndexAliasCreate { aliasCreateRouting :: Maybe AliasRouting
468− , aliasCreateFilter :: Maybe Filter}
469− deriving (Show, Eq, Typeable)
470−
471−data AliasRouting = AllAliasRouting RoutingValue
472− | GranularAliasRouting (Maybe SearchAliasRouting) (Maybe IndexAliasRouting)
473− deriving (Show, Eq, Typeable)
474−
475−newtype SearchAliasRouting = SearchAliasRouting (NonEmpty RoutingValue) deriving (Show, Eq, Typeable)
476−
477−newtype IndexAliasRouting = IndexAliasRouting RoutingValue deriving (Show, Eq, ToJSON, FromJSON, Typeable)
478−
479−newtype RoutingValue = RoutingValue { routingValue :: Text } deriving (Show, Eq, ToJSON, FromJSON, Typeable)
480−
481−newtype IndexAliasesSummary = IndexAliasesSummary { indexAliasesSummary :: [IndexAliasSummary] } deriving (Show, Eq, Typeable)
482−
483−{-| 'IndexAliasSummary' is a summary of an index alias configured for a server. -}
484−data IndexAliasSummary = IndexAliasSummary { indexAliasSummaryAlias :: IndexAlias
485− , indexAliasSummaryCreate :: IndexAliasCreate} deriving (Show, Eq)
486−
487−{-| 'DocVersion' is an integer version number for a document between 1
488−and 9.2e+18 used for <<https://www.elastic.co/guide/en/elasticsearch/guide/current/optimistic-concurrency-control.html optimistic concurrency control>>.
489−-}
490−newtype DocVersion = DocVersion {
491− docVersionNumber :: Int
492− } deriving (Eq, Show, Ord, ToJSON)
493−
494−-- | Smart constructor for in-range doc version
495−mkDocVersion :: Int -> Maybe DocVersion
496−mkDocVersion i
497− | i >= (docVersionNumber minBound) && i <= (docVersionNumber maxBound) =
498− Just $ DocVersion i
499− | otherwise = Nothing
500−
501−
502−{-| 'ExternalDocVersion' is a convenience wrapper if your code uses its
503−own version numbers instead of ones from ES.
504−-}
505−newtype ExternalDocVersion = ExternalDocVersion DocVersion
506− deriving (Eq, Show, Ord, Bounded, Enum, ToJSON)
507−
508−{-| 'VersionControl' is specified when indexing documents as a
509−optimistic concurrency control.
510−-}
511−data VersionControl = NoVersionControl
512− -- ^ Don't send a version. This is a pure overwrite.
513− | InternalVersion DocVersion
514− -- ^ Use the default ES versioning scheme. Only
515− -- index the document if the version is the same
516− -- as the one specified. Only applicable to
517− -- updates, as you should be getting Version from
518− -- a search result.
519− | ExternalGT ExternalDocVersion
520− -- ^ Use your own version numbering. Only index
521− -- the document if the version is strictly higher
522− -- OR the document doesn't exist. The given
523− -- version will be used as the new version number
524− -- for the stored document. N.B. All updates must
525− -- increment this number, meaning there is some
526− -- global, external ordering of updates.
527− | ExternalGTE ExternalDocVersion
528− -- ^ Use your own version numbering. Only index
529− -- the document if the version is equal or higher
530− -- than the stored version. Will succeed if there
531− -- is no existing document. The given version will
532− -- be used as the new version number for the
533− -- stored document. Use with care, as this could
534− -- result in data loss.
535− | ForceVersion ExternalDocVersion
536− -- ^ The document will always be indexed and the
537− -- given version will be the new version. This is
538− -- typically used for correcting errors. Use with
539− -- care, as this could result in data loss.
540− deriving (Show, Eq, Ord)
541−
542−{-| 'DocumentParent' is used to specify a parent document.
543−-}
544−newtype DocumentParent = DocumentParent DocId
545− deriving (Eq, Show)
546−
547−{-| 'IndexDocumentSettings' are special settings supplied when indexing
548−a document. For the best backwards compatiblity when new fields are
549−added, you should probably prefer to start with 'defaultIndexDocumentSettings'
550−-}
551−data IndexDocumentSettings =
552− IndexDocumentSettings { idsVersionControl :: VersionControl
553− , idsParent :: Maybe DocumentParent
554− } deriving (Eq, Show)
555−
556−{-| Reasonable default settings. Chooses no version control and no parent.
557−-}
558−defaultIndexDocumentSettings :: IndexDocumentSettings
559−defaultIndexDocumentSettings = IndexDocumentSettings NoVersionControl Nothing
560−
561−{-| 'Sort' is a synonym for a list of 'SortSpec's. Sort behavior is order
562− dependent with later sorts acting as tie-breakers for earlier sorts.
563−-}
564−type Sort = [SortSpec]
565−
566−{-| The two main kinds of 'SortSpec' are 'DefaultSortSpec' and
567− 'GeoDistanceSortSpec'. The latter takes a 'SortOrder', 'GeoPoint', and
568− 'DistanceUnit' to express "nearness" to a single geographical point as a
569− sort specification.
570−
571−<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
572−-}
573−data SortSpec = DefaultSortSpec DefaultSort
574− | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit deriving (Eq, Show)
575−
576−{-| 'DefaultSort' is usually the kind of 'SortSpec' you'll want. There's a
577− 'mkSort' convenience function for when you want to specify only the most
578− common parameters.
579−
580−<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
581−-}
582−data DefaultSort =
583− DefaultSort { sortFieldName :: FieldName
584− , sortOrder :: SortOrder
585− -- default False
586− , ignoreUnmapped :: Bool
587− , sortMode :: Maybe SortMode
588− , missingSort :: Maybe Missing
589− , nestedFilter :: Maybe Filter } deriving (Eq, Show)
590−
591−{-| 'SortOrder' is 'Ascending' or 'Descending', as you might expect. These get
592− encoded into "asc" or "desc" when turned into JSON.
593−
594−<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
595−-}
596−data SortOrder = Ascending
597− | Descending deriving (Eq, Show)
598−
599−{-| 'Missing' prescribes how to handle missing fields. A missing field can be
600− sorted last, first, or using a custom value as a substitute.
601−
602−<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_missing_values>
603−-}
604−data Missing = LastMissing
605− | FirstMissing
606− | CustomMissing Text deriving (Eq, Show)
607−
608−{-| 'SortMode' prescribes how to handle sorting array/multi-valued fields.
609−
610−http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_sort_mode_option
611−-}
612−data SortMode = SortMin
613− | SortMax
614− | SortSum
615− | SortAvg deriving (Eq, Show)
616−
617−{-| 'mkSort' defaults everything but the 'FieldName' and the 'SortOrder' so
618− that you can concisely describe the usual kind of 'SortSpec's you want.
619−-}
620−mkSort :: FieldName -> SortOrder -> DefaultSort
621−mkSort fieldName sOrder = DefaultSort fieldName sOrder False Nothing Nothing Nothing
622−
623−{-| 'Cache' is for telling ES whether it should cache a 'Filter' not.
624− 'Query's cannot be cached.
625−-}
626−type Cache = Bool -- caching on/off
627−defaultCache :: Cache
628−defaultCache = False
629−
630−{-| 'PrefixValue' is used in 'PrefixQuery' as the main query component.
631−-}
632−type PrefixValue = Text
633−
634−{-| 'BooleanOperator' is the usual And/Or operators with an ES compatible
635− JSON encoding baked in. Used all over the place.
636−-}
637−data BooleanOperator = And | Or deriving (Eq, Show, Typeable)
638−
639−{-| 'ShardCount' is part of 'IndexSettings'
640−-}
641−newtype ShardCount = ShardCount Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
642−
643−{-| 'ReplicaCount' is part of 'IndexSettings'
644−-}
645−newtype ReplicaCount = ReplicaCount Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
646−
647−{-| 'Server' is used with the client functions to point at the ES instance
648−-}
649−newtype Server = Server Text deriving (Eq, Show)
650−
651−{-| 'IndexName' is used to describe which index to query/create/delete
652−-}
653−newtype IndexName = IndexName Text deriving (Eq, Generic, Show, ToJSON, FromJSON, Typeable)
654−
655−{-| 'TemplateName' is used to describe which template to query/create/delete
656−-}
657−newtype TemplateName = TemplateName Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
658−
659−{-| 'TemplatePattern' represents a pattern which is matched against index names
660−-}
661−newtype TemplatePattern = TemplatePattern Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
662−
663−{-| 'MappingName' is part of mappings which are how ES describes and schematizes
664− the data in the indices.
665−-}
666−newtype MappingName = MappingName Text deriving (Eq, Generic, Show, ToJSON, FromJSON, Typeable)
667−
668−{-| 'DocId' is a generic wrapper value for expressing unique Document IDs.
669− Can be set by the user or created by ES itself. Often used in client
670− functions for poking at specific documents.
671−-}
672−newtype DocId = DocId Text deriving (Eq, Generic, Show, ToJSON, FromJSON, Typeable)
673−
674−{-| 'QueryString' is used to wrap query text bodies, be they human written or not.
675−-}
676−newtype QueryString = QueryString Text deriving (Eq, Generic, Show, ToJSON, FromJSON, Typeable)
677−
678−{-| 'FieldName' is used all over the place wherever a specific field within
679− a document needs to be specified, usually in 'Query's or 'Filter's.
680−-}
681−newtype FieldName = FieldName Text deriving (Eq, Show, ToJSON, FromJSON, Typeable)
682−
683−
684−{-| 'Script' is often used in place of 'FieldName' to specify more
685−complex ways of extracting a value from a document.
686−-}
687−newtype Script = Script { scriptText :: Text } deriving (Eq, Show)
688−
689−{-| 'CacheName' is used in 'RegexpFilter' for describing the
690− 'CacheKey' keyed caching behavior.
691−-}
692−newtype CacheName = CacheName Text deriving (Eq, Show, ToJSON, FromJSON, Typeable)
693−
694−{-| 'CacheKey' is used in 'RegexpFilter' to key regex caching.
695−-}
696−newtype CacheKey =
697− CacheKey Text deriving (Eq, Show, ToJSON, FromJSON, Typeable)
698−newtype Existence =
699− Existence Bool deriving (Eq, Show, ToJSON, FromJSON, Typeable)
700−newtype NullValue =
701− NullValue Bool deriving (Eq, Show, ToJSON, FromJSON, Typeable)
702−newtype CutoffFrequency =
703− CutoffFrequency Double deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
704−newtype Analyzer =
705− Analyzer Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
706−newtype MaxExpansions =
707− MaxExpansions Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
708−
709−{-| 'Lenient', if set to true, will cause format based failures to be
710− ignored. I don't know what the bloody default is, Elasticsearch
711− documentation didn't say what it was. Let me know if you figure it out.
712−-}
713−newtype Lenient =
714− Lenient Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
715−newtype Tiebreaker =
716− Tiebreaker Double deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
717−newtype Boost =
718− Boost Double deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
719−newtype BoostTerms =
720− BoostTerms Double deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
721−
722−{-| 'MinimumMatch' controls how many should clauses in the bool query should
723− match. Can be an absolute value (2) or a percentage (30%) or a
724− combination of both.
725−-}
726−newtype MinimumMatch =
727− MinimumMatch Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
728−newtype DisableCoord =
729− DisableCoord Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
730−newtype IgnoreTermFrequency =
731− IgnoreTermFrequency Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
732−newtype MinimumTermFrequency =
733− MinimumTermFrequency Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
734−newtype MaxQueryTerms =
735− MaxQueryTerms Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
736−newtype Fuzziness =
737− Fuzziness Double deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
738−
739−{-| 'PrefixLength' is the prefix length used in queries, defaults to 0. -}
740−newtype PrefixLength =
741− PrefixLength Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
742−newtype TypeName =
743− TypeName Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
744−newtype PercentMatch =
745− PercentMatch Double deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
746−newtype StopWord =
747− StopWord Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
748−newtype QueryPath =
749− QueryPath Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
750−
751−{-| Allowing a wildcard at the beginning of a word (eg "*ing") is particularly
752− heavy, because all terms in the index need to be examined, just in case
753− they match. Leading wildcards can be disabled by setting
754− 'AllowLeadingWildcard' to false. -}
755−newtype AllowLeadingWildcard =
756− AllowLeadingWildcard Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
757−newtype LowercaseExpanded =
758− LowercaseExpanded Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
759−newtype EnablePositionIncrements =
760− EnablePositionIncrements Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
761−
762−{-| By default, wildcard terms in a query are not analyzed.
763− Setting 'AnalyzeWildcard' to true enables best-effort analysis.
764−-}
765−newtype AnalyzeWildcard = AnalyzeWildcard Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
766−
767−{-| 'GeneratePhraseQueries' defaults to false.
768−-}
769−newtype GeneratePhraseQueries =
770− GeneratePhraseQueries Bool deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
771−
772−{-| 'Locale' is used for string conversions - defaults to ROOT.
773−-}
774−newtype Locale = Locale Text deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
775−newtype MaxWordLength = MaxWordLength Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
776−newtype MinWordLength = MinWordLength Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
777−
778−{-| 'PhraseSlop' sets the default slop for phrases, 0 means exact
779− phrase matches. Default is 0.
780−-}
781−newtype PhraseSlop = PhraseSlop Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
782−newtype MinDocFrequency = MinDocFrequency Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
783−newtype MaxDocFrequency = MaxDocFrequency Int deriving (Eq, Show, Generic, ToJSON, FromJSON, Typeable)
784−
785−-- | Newtype wrapper to parse ES's concerning tendency to in some APIs return a floating point number of milliseconds since epoch ಠ_ಠ
786−newtype POSIXMS = POSIXMS { posixMS :: UTCTime }
403+ , TopHitResult(..)
404+
405+ , EsUsername(..)
406+ , EsPassword(..)
407+
408+ , Analysis(..)
409+ , AnalyzerDefinition(..)
410+ , TokenizerDefinition(..)
411+ , TokenFilterDefinition(..)
412+ , CharFilterDefinition(..)
413+ , Ngram(..)
414+ , TokenChar(..)
415+ , Shingle(..)
416+ , Language(..)
417+ ) where
418+
419+import Bloodhound.Import
420+
421+import Database.Bloodhound.Internal.Aggregation
422+import Database.Bloodhound.Internal.Analysis
423+import Database.Bloodhound.Internal.Client
424+import Database.Bloodhound.Internal.Highlight
425+import Database.Bloodhound.Internal.Newtypes
426+import Database.Bloodhound.Internal.Query
427+import Database.Bloodhound.Internal.Sort
428+import Database.Bloodhound.Internal.Suggest
787429
788430{-| 'unpackId' is a silly convenience function that gets used once.
789431-}
@@ -791,8 +433,6 @@ unpackId :: DocId -> Text
791433unpackId (DocId docId) = docId
792434
793435type TrackSortScores = Bool
794−newtype From = From Int deriving (Eq, Show, ToJSON)
795−newtype Size = Size Int deriving (Eq, Show, ToJSON)
796436
797437data Search = Search { queryBody :: Maybe Query
798438 , filterBody :: Maybe Filter
@@ -804,2322 +444,87 @@ data Search = Search { queryBody :: Maybe Query
804444 , from :: From
805445 , size :: Size
806446 , searchType :: SearchType
447+ , searchAfterKey :: Maybe SearchAfterKey
807448 , fields :: Maybe [FieldName]
808− , source :: Maybe Source } 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)
453+
454+
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'
460+ , "sort" .= sort
461+ , "aggregations" .= searchAggs
462+ , "highlight" .= highlight
463+ , "from" .= sFrom
464+ , "size" .= sSize
465+ , "track_scores" .= sTrackSortScores
466+ , "search_after" .= sAfter
467+ , "fields" .= sFields
468+ , "script_fields" .= sScriptFields
469+ , "_source" .= sSource
470+ , "suggest" .= sSuggest]
471+
472+ where query' = case sFilter of
473+ Nothing -> mquery
474+ Just x ->
475+ Just
476+ . QueryBoolQuery
477+ $ mkBoolQuery (maybeToList mquery)
478+ [x] [] []
809479
810480data SearchType = SearchTypeQueryThenFetch
811481 | SearchTypeDfsQueryThenFetch
812− | SearchTypeCount
813− | SearchTypeScan
814− | SearchTypeQueryAndFetch
815− | SearchTypeDfsQueryAndFetch
816482 deriving (Eq, Show)
817483
818484data Source =
819485 NoSource
820486 | SourcePatterns PatternOrPatterns
821487 | SourceIncludeExclude Include Exclude
822− deriving (Show, Eq)
823−
824−data PatternOrPatterns = PopPattern Pattern
825− | PopPatterns [Pattern] deriving (Eq, Show)
826−
827−data Include = Include [Pattern] deriving (Eq, Show)
828−data Exclude = Exclude [Pattern] deriving (Eq, Show)
829−
830−newtype Pattern = Pattern Text deriving (Eq, Show)
831−
832−data Highlights = Highlights { globalsettings :: Maybe HighlightSettings
833− , highlightFields :: [FieldHighlight]
834− } deriving (Show, Eq)
835−
836−data FieldHighlight = FieldHighlight FieldName (Maybe HighlightSettings)
837− deriving (Show, Eq)
838−
839−
840−data HighlightSettings = Plain PlainHighlight
841− | Postings PostingsHighlight
842− | FastVector FastVectorHighlight
843− deriving (Show, Eq)
844−data PlainHighlight =
845− PlainHighlight { plainCommon :: Maybe CommonHighlight
846− , plainNonPost :: Maybe NonPostings } deriving (Show, Eq)
847−
848− -- This requires that index_options are set to 'offset' in the mapping.
849−data PostingsHighlight = PostingsHighlight (Maybe CommonHighlight) deriving (Show, Eq)
850−
851−-- This requires that term_vector is set to 'with_positions_offsets' in the mapping.
852−data FastVectorHighlight =
853− FastVectorHighlight { fvCommon :: Maybe CommonHighlight
854− , fvNonPostSettings :: Maybe NonPostings
855− , boundaryChars :: Maybe Text
856− , boundaryMaxScan :: Maybe Int
857− , fragmentOffset :: Maybe Int
858− , matchedFields :: [Text]
859− , phraseLimit :: Maybe Int
860− } deriving (Show, Eq)
861−
862−data CommonHighlight =
863− CommonHighlight { order :: Maybe Text
864− , forceSource :: Maybe Bool
865− , tag :: Maybe HighlightTag
866− , encoder :: Maybe HighlightEncoder
867− , noMatchSize :: Maybe Int
868− , highlightQuery :: Maybe Query
869− , requireFieldMatch :: Maybe Bool
870− } deriving (Show, Eq)
871−
872−-- Settings that are only applicable to FastVector and Plain highlighters.
873−data NonPostings =
874− NonPostings { fragmentSize :: Maybe Int
875− , numberOfFragments :: Maybe Int} deriving (Show, Eq)
876−
877−data HighlightEncoder = DefaultEncoder
878− | HTMLEncoder
879− deriving (Show, Eq)
880−
881−-- NOTE: Should the tags use some kind of HTML type, rather than Text?
882−data HighlightTag = TagSchema Text
883− | CustomTags ([Text], [Text]) -- Only uses more than the first value in the lists if fvh
884− deriving (Show, Eq)
885−
886−
887−data Query =
888− TermQuery Term (Maybe Boost)
889− | TermsQuery Text (NonEmpty Text)
890− | QueryMatchQuery MatchQuery
891− | QueryMultiMatchQuery MultiMatchQuery
892− | QueryBoolQuery BoolQuery
893− | QueryBoostingQuery BoostingQuery
894− | QueryCommonTermsQuery CommonTermsQuery
895− | ConstantScoreFilter Filter Boost
896− | ConstantScoreQuery Query Boost
897− | QueryDisMaxQuery DisMaxQuery
898− | QueryFilteredQuery FilteredQuery
899− | QueryFuzzyLikeThisQuery FuzzyLikeThisQuery
900− | QueryFuzzyLikeFieldQuery FuzzyLikeFieldQuery
901− | QueryFuzzyQuery FuzzyQuery
902− | QueryHasChildQuery HasChildQuery
903− | QueryHasParentQuery HasParentQuery
904− | IdsQuery MappingName [DocId]
905− | QueryIndicesQuery IndicesQuery
906− | MatchAllQuery (Maybe Boost)
907− | QueryMoreLikeThisQuery MoreLikeThisQuery
908− | QueryMoreLikeThisFieldQuery MoreLikeThisFieldQuery
909− | QueryNestedQuery NestedQuery
910− | QueryPrefixQuery PrefixQuery
911− | QueryQueryStringQuery QueryStringQuery
912− | QuerySimpleQueryStringQuery SimpleQueryStringQuery
913− | QueryRangeQuery RangeQuery
914− | QueryRegexpQuery RegexpQuery
915− deriving (Eq, Show, Typeable)
916−
917−data RegexpQuery =
918− RegexpQuery { regexpQueryField :: FieldName
919− , regexpQuery :: Regexp
920− , regexpQueryFlags :: RegexpFlags
921− , regexpQueryBoost :: Maybe Boost
922− } deriving (Eq, Show, Typeable)
923−
924−data RangeQuery =
925− RangeQuery { rangeQueryField :: FieldName
926− , rangeQueryRange :: RangeValue
927− , rangeQueryBoost :: Boost } deriving (Eq, Show, Typeable)
928−
929−mkRangeQuery :: FieldName -> RangeValue -> RangeQuery
930−mkRangeQuery f r = RangeQuery f r (Boost 1.0)
931−
932−data SimpleQueryStringQuery =
933− SimpleQueryStringQuery
934− { simpleQueryStringQuery :: QueryString
935− , simpleQueryStringField :: Maybe FieldOrFields
936− , simpleQueryStringOperator :: Maybe BooleanOperator
937− , simpleQueryStringAnalyzer :: Maybe Analyzer
938− , simpleQueryStringFlags :: Maybe (NonEmpty SimpleQueryFlag)
939− , simpleQueryStringLowercaseExpanded :: Maybe LowercaseExpanded
940− , simpleQueryStringLocale :: Maybe Locale
941− } deriving (Eq, Show, Typeable)
942−
943−data SimpleQueryFlag =
944− SimpleQueryAll
945− | SimpleQueryNone
946− | SimpleQueryAnd
947− | SimpleQueryOr
948− | SimpleQueryPrefix
949− | SimpleQueryPhrase
950− | SimpleQueryPrecedence
951− | SimpleQueryEscape
952− | SimpleQueryWhitespace
953− | SimpleQueryFuzzy
954− | SimpleQueryNear
955− | SimpleQuerySlop deriving (Eq, Show, Typeable)
956−
957−-- use_dis_max and tie_breaker when fields are plural?
958−data QueryStringQuery =
959− QueryStringQuery
960− { queryStringQuery :: QueryString
961− , queryStringDefaultField :: Maybe FieldName
962− , queryStringOperator :: Maybe BooleanOperator
963− , queryStringAnalyzer :: Maybe Analyzer
964− , queryStringAllowLeadingWildcard :: Maybe AllowLeadingWildcard
965− , queryStringLowercaseExpanded :: Maybe LowercaseExpanded
966− , queryStringEnablePositionIncrements :: Maybe EnablePositionIncrements
967− , queryStringFuzzyMaxExpansions :: Maybe MaxExpansions
968− , queryStringFuzziness :: Maybe Fuzziness
969− , queryStringFuzzyPrefixLength :: Maybe PrefixLength
970− , queryStringPhraseSlop :: Maybe PhraseSlop
971− , queryStringBoost :: Maybe Boost
972− , queryStringAnalyzeWildcard :: Maybe AnalyzeWildcard
973− , queryStringGeneratePhraseQueries :: Maybe GeneratePhraseQueries
974− , queryStringMinimumShouldMatch :: Maybe MinimumMatch
975− , queryStringLenient :: Maybe Lenient
976− , queryStringLocale :: Maybe Locale
977− } deriving (Eq, Show, Typeable)
978−
979−mkQueryStringQuery :: QueryString -> QueryStringQuery
980−mkQueryStringQuery qs =
981− QueryStringQuery qs Nothing Nothing
982− Nothing Nothing Nothing Nothing
983− Nothing Nothing Nothing Nothing
984− Nothing Nothing Nothing Nothing
985− Nothing Nothing
986−
987−data FieldOrFields = FofField FieldName
988− | FofFields (NonEmpty FieldName) deriving (Eq, Show, Typeable)
989−
990−data PrefixQuery =
991− PrefixQuery
992− { prefixQueryField :: FieldName
993− , prefixQueryPrefixValue :: Text
994− , prefixQueryBoost :: Maybe Boost } deriving (Eq, Show, Typeable)
995−
996−data NestedQuery =
997− NestedQuery
998− { nestedQueryPath :: QueryPath
999− , nestedQueryScoreType :: ScoreType
1000− , nestedQuery :: Query } deriving (Eq, Show, Typeable)
1001−
1002−data MoreLikeThisFieldQuery =
1003− MoreLikeThisFieldQuery
1004− { moreLikeThisFieldText :: Text
1005− , moreLikeThisFieldFields :: FieldName
1006− -- default 0.3 (30%)
1007− , moreLikeThisFieldPercentMatch :: Maybe PercentMatch
1008− , moreLikeThisFieldMinimumTermFreq :: Maybe MinimumTermFrequency
1009− , moreLikeThisFieldMaxQueryTerms :: Maybe MaxQueryTerms
1010− , moreLikeThisFieldStopWords :: Maybe (NonEmpty StopWord)
1011− , moreLikeThisFieldMinDocFrequency :: Maybe MinDocFrequency
1012− , moreLikeThisFieldMaxDocFrequency :: Maybe MaxDocFrequency
1013− , moreLikeThisFieldMinWordLength :: Maybe MinWordLength
1014− , moreLikeThisFieldMaxWordLength :: Maybe MaxWordLength
1015− , moreLikeThisFieldBoostTerms :: Maybe BoostTerms
1016− , moreLikeThisFieldBoost :: Maybe Boost
1017− , moreLikeThisFieldAnalyzer :: Maybe Analyzer
1018− } deriving (Eq, Show, Typeable)
1019−
1020−data MoreLikeThisQuery =
1021− MoreLikeThisQuery
1022− { moreLikeThisText :: Text
1023− , moreLikeThisFields :: Maybe (NonEmpty FieldName)
1024− -- default 0.3 (30%)
1025− , moreLikeThisPercentMatch :: Maybe PercentMatch
1026− , moreLikeThisMinimumTermFreq :: Maybe MinimumTermFrequency
1027− , moreLikeThisMaxQueryTerms :: Maybe MaxQueryTerms
1028− , moreLikeThisStopWords :: Maybe (NonEmpty StopWord)
1029− , moreLikeThisMinDocFrequency :: Maybe MinDocFrequency
1030− , moreLikeThisMaxDocFrequency :: Maybe MaxDocFrequency
1031− , moreLikeThisMinWordLength :: Maybe MinWordLength
1032− , moreLikeThisMaxWordLength :: Maybe MaxWordLength
1033− , moreLikeThisBoostTerms :: Maybe BoostTerms
1034− , moreLikeThisBoost :: Maybe Boost
1035− , moreLikeThisAnalyzer :: Maybe Analyzer
1036− } deriving (Eq, Show, Typeable)
1037−
1038−data IndicesQuery =
1039− IndicesQuery
1040− { indicesQueryIndices :: [IndexName]
1041− , indicesQuery :: Query
1042− -- default "all"
1043− , indicesQueryNoMatch :: Maybe Query } deriving (Eq, Show, Typeable)
1044−
1045−data HasParentQuery =
1046− HasParentQuery
1047− { hasParentQueryType :: TypeName
1048− , hasParentQuery :: Query
1049− , hasParentQueryScoreType :: Maybe ScoreType } deriving (Eq, Show, Typeable)
1050−
1051−data HasChildQuery =
1052− HasChildQuery
1053− { hasChildQueryType :: TypeName
1054− , hasChildQuery :: Query
1055− , hasChildQueryScoreType :: Maybe ScoreType } deriving (Eq, Show, Typeable)
1056−
1057−data ScoreType =
1058− ScoreTypeMax
1059− | ScoreTypeSum
1060− | ScoreTypeAvg
1061− | ScoreTypeNone deriving (Eq, Show, Typeable)
1062−
1063−data FuzzyQuery =
1064− FuzzyQuery { fuzzyQueryField :: FieldName
1065− , fuzzyQueryValue :: Text
1066− , fuzzyQueryPrefixLength :: PrefixLength
1067− , fuzzyQueryMaxExpansions :: MaxExpansions
1068− , fuzzyQueryFuzziness :: Fuzziness
1069− , fuzzyQueryBoost :: Maybe Boost
1070− } deriving (Eq, Show, Typeable)
1071−
1072−data FuzzyLikeFieldQuery =
1073− FuzzyLikeFieldQuery
1074− { fuzzyLikeField :: FieldName
1075− -- anaphora is good for the soul.
1076− , fuzzyLikeFieldText :: Text
1077− , fuzzyLikeFieldMaxQueryTerms :: MaxQueryTerms
1078− , fuzzyLikeFieldIgnoreTermFrequency :: IgnoreTermFrequency
1079− , fuzzyLikeFieldFuzziness :: Fuzziness
1080− , fuzzyLikeFieldPrefixLength :: PrefixLength
1081− , fuzzyLikeFieldBoost :: Boost
1082− , fuzzyLikeFieldAnalyzer :: Maybe Analyzer
1083− } deriving (Eq, Show, Typeable)
1084−
1085−data FuzzyLikeThisQuery =
1086− FuzzyLikeThisQuery
1087− { fuzzyLikeFields :: [FieldName]
1088− , fuzzyLikeText :: Text
1089− , fuzzyLikeMaxQueryTerms :: MaxQueryTerms
1090− , fuzzyLikeIgnoreTermFrequency :: IgnoreTermFrequency
1091− , fuzzyLikeFuzziness :: Fuzziness
1092− , fuzzyLikePrefixLength :: PrefixLength
1093− , fuzzyLikeBoost :: Boost
1094− , fuzzyLikeAnalyzer :: Maybe Analyzer
1095− } deriving (Eq, Show, Typeable)
1096−
1097−data FilteredQuery =
1098− FilteredQuery
1099− { filteredQuery :: Query
1100− , filteredFilter :: Filter } deriving (Eq, Show, Typeable)
1101−
1102−data DisMaxQuery =
1103− DisMaxQuery { disMaxQueries :: [Query]
1104− -- default 0.0
1105− , disMaxTiebreaker :: Tiebreaker
1106− , disMaxBoost :: Maybe Boost
1107− } deriving (Eq, Show, Typeable)
1108−
1109−data MatchQuery =
1110− MatchQuery { matchQueryField :: FieldName
1111− , matchQueryQueryString :: QueryString
1112− , matchQueryOperator :: BooleanOperator
1113− , matchQueryZeroTerms :: ZeroTermsQuery
1114− , matchQueryCutoffFrequency :: Maybe CutoffFrequency
1115− , matchQueryMatchType :: Maybe MatchQueryType
1116− , matchQueryAnalyzer :: Maybe Analyzer
1117− , matchQueryMaxExpansions :: Maybe MaxExpansions
1118− , matchQueryLenient :: Maybe Lenient
1119− , matchQueryBoost :: Maybe Boost } deriving (Eq, Show, Typeable)
1120−
1121−{-| 'mkMatchQuery' is a convenience function that defaults the less common parameters,
1122− enabling you to provide only the 'FieldName' and 'QueryString' to make a 'MatchQuery'
1123−-}
1124−mkMatchQuery :: FieldName -> QueryString -> MatchQuery
1125−mkMatchQuery field query = MatchQuery field query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1126−
1127−data MatchQueryType =
1128− MatchPhrase
1129− | MatchPhrasePrefix deriving (Eq, Show, Typeable)
1130−
1131−data MultiMatchQuery =
1132− MultiMatchQuery { multiMatchQueryFields :: [FieldName]
1133− , multiMatchQueryString :: QueryString
1134− , multiMatchQueryOperator :: BooleanOperator
1135− , multiMatchQueryZeroTerms :: ZeroTermsQuery
1136− , multiMatchQueryTiebreaker :: Maybe Tiebreaker
1137− , multiMatchQueryType :: Maybe MultiMatchQueryType
1138− , multiMatchQueryCutoffFrequency :: Maybe CutoffFrequency
1139− , multiMatchQueryAnalyzer :: Maybe Analyzer
1140− , multiMatchQueryMaxExpansions :: Maybe MaxExpansions
1141− , multiMatchQueryLenient :: Maybe Lenient } deriving (Eq, Show, Typeable)
1142−
1143−{-| 'mkMultiMatchQuery' is a convenience function that defaults the less common parameters,
1144− enabling you to provide only the list of 'FieldName's and 'QueryString' to
1145− make a 'MultiMatchQuery'.
1146−-}
1147−
1148−mkMultiMatchQuery :: [FieldName] -> QueryString -> MultiMatchQuery
1149−mkMultiMatchQuery matchFields query =
1150− MultiMatchQuery matchFields query
1151− Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1152−
1153−data MultiMatchQueryType =
1154− MultiMatchBestFields
1155− | MultiMatchMostFields
1156− | MultiMatchCrossFields
1157− | MultiMatchPhrase
1158− | MultiMatchPhrasePrefix deriving (Eq, Show, Typeable)
1159−
1160−data BoolQuery =
1161− BoolQuery { boolQueryMustMatch :: [Query]
1162− , boolQueryMustNotMatch :: [Query]
1163− , boolQueryShouldMatch :: [Query]
1164− , boolQueryMinimumShouldMatch :: Maybe MinimumMatch
1165− , boolQueryBoost :: Maybe Boost
1166− , boolQueryDisableCoord :: Maybe DisableCoord
1167− } deriving (Eq, Show, Typeable)
1168−
1169−mkBoolQuery :: [Query] -> [Query] -> [Query] -> BoolQuery
1170−mkBoolQuery must mustNot should =
1171− BoolQuery must mustNot should Nothing Nothing Nothing
1172−
1173−data BoostingQuery =
1174− BoostingQuery { positiveQuery :: Query
1175− , negativeQuery :: Query
1176− , negativeBoost :: Boost } deriving (Eq, Show, Typeable)
1177−
1178−data CommonTermsQuery =
1179− CommonTermsQuery { commonField :: FieldName
1180− , commonQuery :: QueryString
1181− , commonCutoffFrequency :: CutoffFrequency
1182− , commonLowFreqOperator :: BooleanOperator
1183− , commonHighFreqOperator :: BooleanOperator
1184− , commonMinimumShouldMatch :: Maybe CommonMinimumMatch
1185− , commonBoost :: Maybe Boost
1186− , commonAnalyzer :: Maybe Analyzer
1187− , commonDisableCoord :: Maybe DisableCoord
1188− } deriving (Eq, Show, Typeable)
1189−
1190−data CommonMinimumMatch =
1191− CommonMinimumMatchHighLow MinimumMatchHighLow
1192− | CommonMinimumMatch MinimumMatch
1193− deriving (Eq, Show, Typeable)
1194−
1195−data MinimumMatchHighLow =
1196− MinimumMatchHighLow { lowFreq :: MinimumMatch
1197− , highFreq :: MinimumMatch } deriving (Eq, Show, Typeable)
1198−
1199−data Filter = AndFilter [Filter] Cache
1200− | OrFilter [Filter] Cache
1201− | NotFilter Filter Cache
1202− | IdentityFilter
1203− | BoolFilter BoolMatch
1204− | ExistsFilter FieldName -- always cached
1205− | GeoBoundingBoxFilter GeoBoundingBoxConstraint
1206− | GeoDistanceFilter GeoPoint Distance DistanceType OptimizeBbox Cache
1207− | GeoDistanceRangeFilter GeoPoint DistanceRange
1208− | GeoPolygonFilter FieldName [LatLon]
1209− | IdsFilter MappingName [DocId]
1210− | LimitFilter Int
1211− | MissingFilter FieldName Existence NullValue
1212− | PrefixFilter FieldName PrefixValue Cache
1213− | QueryFilter Query Cache
1214− | RangeFilter FieldName RangeValue RangeExecution Cache
1215− | RegexpFilter FieldName Regexp RegexpFlags CacheName Cache CacheKey
1216− | TermFilter Term Cache
1217− deriving (Eq, Show, Typeable)
1218−
1219−data ZeroTermsQuery = ZeroTermsNone
1220− | ZeroTermsAll deriving (Eq, Show, Typeable)
1221−
1222−data RangeExecution = RangeExecutionIndex
1223− | RangeExecutionFielddata deriving (Eq, Show, Typeable)
1224−
1225−newtype Regexp = Regexp Text deriving (Eq, Show, FromJSON)
1226−
1227−data RegexpFlags = AllRegexpFlags
1228− | NoRegexpFlags
1229− | SomeRegexpFlags (NonEmpty RegexpFlag) deriving (Eq, Show)
1230−
1231−data RegexpFlag = AnyString
1232− | Automaton
1233− | Complement
1234− | Empty
1235− | Intersection
1236− | Interval deriving (Eq, Show)
1237−
1238−newtype LessThan = LessThan Double deriving (Eq, Show)
1239−newtype LessThanEq = LessThanEq Double deriving (Eq, Show)
1240−newtype GreaterThan = GreaterThan Double deriving (Eq, Show)
1241−newtype GreaterThanEq = GreaterThanEq Double deriving (Eq, Show)
1242−
1243−newtype LessThanD = LessThanD UTCTime deriving (Eq, Show)
1244−newtype LessThanEqD = LessThanEqD UTCTime deriving (Eq, Show)
1245−newtype GreaterThanD = GreaterThanD UTCTime deriving (Eq, Show)
1246−newtype GreaterThanEqD = GreaterThanEqD UTCTime deriving (Eq, Show)
1247−
1248−data RangeValue = RangeDateLte LessThanEqD
1249− | RangeDateLt LessThanD
1250− | RangeDateGte GreaterThanEqD
1251− | RangeDateGt GreaterThanD
1252− | RangeDateGtLt GreaterThanD LessThanD
1253− | RangeDateGteLte GreaterThanEqD LessThanEqD
1254− | RangeDateGteLt GreaterThanEqD LessThanD
1255− | RangeDateGtLte GreaterThanD LessThanEqD
1256− | RangeDoubleLte LessThanEq
1257− | RangeDoubleLt LessThan
1258− | RangeDoubleGte GreaterThanEq
1259− | RangeDoubleGt GreaterThan
1260− | RangeDoubleGtLt GreaterThan LessThan
1261− | RangeDoubleGteLte GreaterThanEq LessThanEq
1262− | RangeDoubleGteLt GreaterThanEq LessThan
1263− | RangeDoubleGtLte GreaterThan LessThanEq
1264− deriving (Eq, Show)
1265−
1266−rangeValueToPair :: RangeValue -> [Pair]
1267−rangeValueToPair rv = case rv of
1268− RangeDateLte (LessThanEqD t) -> ["lte" .= t]
1269− RangeDateGte (GreaterThanEqD t) -> ["gte" .= t]
1270− RangeDateLt (LessThanD t) -> ["lt" .= t]
1271− RangeDateGt (GreaterThanD t) -> ["gt" .= t]
1272− RangeDateGteLte (GreaterThanEqD l) (LessThanEqD g) -> ["gte" .= l, "lte" .= g]
1273− RangeDateGtLte (GreaterThanD l) (LessThanEqD g) -> ["gt" .= l, "lte" .= g]
1274− RangeDateGteLt (GreaterThanEqD l) (LessThanD g) -> ["gte" .= l, "lt" .= g]
1275− RangeDateGtLt (GreaterThanD l) (LessThanD g) -> ["gt" .= l, "lt" .= g]
1276− RangeDoubleLte (LessThanEq t) -> ["lte" .= t]
1277− RangeDoubleGte (GreaterThanEq t) -> ["gte" .= t]
1278− RangeDoubleLt (LessThan t) -> ["lt" .= t]
1279− RangeDoubleGt (GreaterThan t) -> ["gt" .= t]
1280− RangeDoubleGteLte (GreaterThanEq l) (LessThanEq g) -> ["gte" .= l, "lte" .= g]
1281− RangeDoubleGtLte (GreaterThan l) (LessThanEq g) -> ["gt" .= l, "lte" .= g]
1282− RangeDoubleGteLt (GreaterThanEq l) (LessThan g) -> ["gte" .= l, "lt" .= g]
1283− RangeDoubleGtLt (GreaterThan l) (LessThan g) -> ["gt" .= l, "lt" .= g]
1284−
1285−data Term = Term { termField :: Text
1286− , termValue :: Text } deriving (Eq, Show, Typeable)
1287−
1288−data BoolMatch = MustMatch Term Cache
1289− | MustNotMatch Term Cache
1290− | ShouldMatch [Term] Cache deriving (Eq, Show, Typeable)
1291−
1292−-- "memory" or "indexed"
1293−data GeoFilterType = GeoFilterMemory
1294− | GeoFilterIndexed deriving (Eq, Show, Typeable)
1295−
1296−data LatLon = LatLon { lat :: Double
1297− , lon :: Double } deriving (Eq, Show, Typeable)
1298−
1299−data GeoBoundingBox =
1300− GeoBoundingBox { topLeft :: LatLon
1301− , bottomRight :: LatLon } deriving (Eq, Show, Typeable)
1302−
1303−data GeoBoundingBoxConstraint =
1304− GeoBoundingBoxConstraint { geoBBField :: FieldName
1305− , constraintBox :: GeoBoundingBox
1306− , bbConstraintcache :: Cache
1307− , geoType :: GeoFilterType
1308− } deriving (Eq, Show, Typeable)
1309−
1310−data GeoPoint =
1311− GeoPoint { geoField :: FieldName
1312− , latLon :: LatLon} deriving (Eq, Show, Typeable)
1313−
1314−data DistanceUnit = Miles
1315− | Yards
1316− | Feet
1317− | Inches
1318− | Kilometers
1319− | Meters
1320− | Centimeters
1321− | Millimeters
1322− | NauticalMiles deriving (Eq, Show, Typeable)
1323−
1324−data DistanceType = Arc
1325− | SloppyArc -- doesn't exist <1.0
1326− | Plane deriving (Eq, Show, Typeable)
1327−
1328−data OptimizeBbox = OptimizeGeoFilterType GeoFilterType
1329− | NoOptimizeBbox deriving (Eq, Show, Typeable)
1330−
1331−data Distance =
1332− Distance { coefficient :: Double
1333− , unit :: DistanceUnit } deriving (Eq, Show, Typeable)
1334−
1335−data DistanceRange =
1336− DistanceRange { distanceFrom :: Distance
1337− , distanceTo :: Distance } deriving (Eq, Show)
1338−
1339−data SearchResult a =
1340− SearchResult { took :: Int
1341− , timedOut :: Bool
1342− , shards :: ShardResult
1343− , searchHits :: SearchHits a
1344− , aggregations :: Maybe AggregationResults
1345− , scrollId :: Maybe ScrollId } deriving (Eq, Show)
1346−
1347−newtype ScrollId = ScrollId Text deriving (Eq, Show, Ord, ToJSON, FromJSON)
1348−
1349−type Score = Maybe Double
1350−
1351−data SearchHits a =
1352− SearchHits { hitsTotal :: Int
1353− , maxScore :: Score
1354− , hits :: [Hit a] } deriving (Eq, Show)
1355−
1356−
1357−instance Monoid (SearchHits a) where
1358− mempty = SearchHits 0 Nothing mempty
1359− mappend (SearchHits ta ma ha) (SearchHits tb mb hb) =
1360− SearchHits (ta + tb) (max ma mb) (ha <> hb)
1361−
1362−
1363−data Hit a =
1364− Hit { hitIndex :: IndexName
1365− , hitType :: MappingName
1366− , hitDocId :: DocId
1367− , hitScore :: Score
1368− , hitSource :: Maybe a
1369− , hitHighlight :: Maybe HitHighlight } deriving (Eq, Show)
1370−
1371−data ShardResult =
1372− ShardResult { shardTotal :: Int
1373− , shardsSuccessful :: Int
1374− , shardsFailed :: Int } deriving (Eq, Show, Generic)
1375−
1376−type HitHighlight = M.Map Text [Text]
1377−
1378−showText :: Show a => a -> Text
1379−showText = T.pack . show
1380−
1381−type Aggregations = M.Map Text Aggregation
1382−
1383−emptyAggregations :: Aggregations
1384−emptyAggregations = M.empty
1385−
1386−mkAggregations :: Text -> Aggregation -> Aggregations
1387−mkAggregations name aggregation = M.insert name aggregation emptyAggregations
1388−
1389−data TermOrder = TermOrder{ termSortField :: Text
1390− , termSortOrder :: SortOrder } deriving (Eq, Show)
1391−
1392−data TermInclusion = TermInclusion Text
1393− | TermPattern Text Text deriving (Eq, Show)
1394−
1395−data CollectionMode = BreadthFirst
1396− | DepthFirst deriving (Eq, Show)
1397−
1398−data ExecutionHint = Ordinals
1399− | GlobalOrdinals
1400− | GlobalOrdinalsHash
1401− | GlobalOrdinalsLowCardinality
1402− | Map deriving (Eq, Show)
1403−
1404−data TimeInterval = Weeks
1405− | Days
1406− | Hours
1407− | Minutes
1408− | Seconds deriving (Eq)
1409−
1410−data Interval = Year
1411− | Quarter
1412− | Month
1413− | Week
1414− | Day
1415− | Hour
1416− | Minute
1417− | Second
1418− | FractionalInterval Float TimeInterval deriving (Eq, Show)
1419−
1420−data Aggregation = TermsAgg TermsAggregation
1421− | DateHistogramAgg DateHistogramAggregation
1422− | ValueCountAgg ValueCountAggregation
1423− | FilterAgg FilterAggregation
1424− | DateRangeAgg DateRangeAggregation deriving (Eq, Show)
1425−
1426−
1427−data TermsAggregation = TermsAggregation { term :: Either Text Text
1428− , termInclude :: Maybe TermInclusion
1429− , termExclude :: Maybe TermInclusion
1430− , termOrder :: Maybe TermOrder
1431− , termMinDocCount :: Maybe Int
1432− , termSize :: Maybe Int
1433− , termShardSize :: Maybe Int
1434− , termCollectMode :: Maybe CollectionMode
1435− , termExecutionHint :: Maybe ExecutionHint
1436− , termAggs :: Maybe Aggregations
1437− } deriving (Eq, Show)
1438−
1439−data DateHistogramAggregation = DateHistogramAggregation { dateField :: FieldName
1440− , dateInterval :: Interval
1441− , dateFormat :: Maybe Text
1442− -- pre and post deprecated in 1.5
1443− , datePreZone :: Maybe Text
1444− , datePostZone :: Maybe Text
1445− , datePreOffset :: Maybe Text
1446− , datePostOffset :: Maybe Text
1447− , dateAggs :: Maybe Aggregations
1448− } deriving (Eq, Show)
1449−
1450−
1451−data DateRangeAggregation = DateRangeAggregation { draField :: FieldName
1452− , draFormat :: Maybe Text
1453− , draRanges :: NonEmpty DateRangeAggRange
1454− } deriving (Eq, Show)
1455−
1456−data DateRangeAggRange = DateRangeFrom DateMathExpr
1457− | DateRangeTo DateMathExpr
1458− | DateRangeFromAndTo DateMathExpr DateMathExpr deriving (Eq, Show)
1459−
1460−-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math> for more information.
1461−data DateMathExpr = DateMathExpr DateMathAnchor [DateMathModifier] deriving (Eq, Show)
1462−
1463−
1464−-- | Starting point for a date range. This along with the 'DateMathModifiers' gets you the date ES will start from.
1465−data DateMathAnchor = DMNow
1466− | DMDate Day deriving (Eq, Show)
1467−
1468−data DateMathModifier = AddTime Int DateMathUnit
1469− | SubtractTime Int DateMathUnit
1470− | RoundDownTo DateMathUnit deriving (Eq, Show)
1471−
1472−data DateMathUnit = DMYear
1473− | DMMonth
1474− | DMWeek
1475− | DMDay
1476− | DMHour
1477− | DMMinute
1478− | DMSecond deriving (Eq, Show)
1479−
1480−-- | See <https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html> for more information.
1481−data ValueCountAggregation = FieldValueCount FieldName
1482− | ScriptValueCount Script deriving (Eq, Show)
1483−
1484−-- | 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.
1485−data FilterAggregation = FilterAggregation { faFilter :: Filter
1486− , faAggs :: Maybe Aggregations} deriving (Eq, Show)
1487−
1488−mkTermsAggregation :: Text -> TermsAggregation
1489−mkTermsAggregation t = TermsAggregation (Left t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1490−
1491−mkTermsScriptAggregation :: Text -> TermsAggregation
1492−mkTermsScriptAggregation t = TermsAggregation (Right t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1493−
1494−mkDateHistogram :: FieldName -> Interval -> DateHistogramAggregation
1495−mkDateHistogram t i = DateHistogramAggregation t i Nothing Nothing Nothing Nothing Nothing Nothing
1496−
1497−instance ToJSON Version where
1498− toJSON Version {..} = object ["number" .= number
1499− ,"build_hash" .= build_hash
1500− ,"build_timestamp" .= build_timestamp
1501− ,"build_snapshot" .= build_snapshot
1502− ,"lucene_version" .= lucene_version]
1503−
1504−instance FromJSON Version where
1505− parseJSON = withObject "Version" parse
1506− where parse o = Version
1507− <$> o .: "number"
1508− <*> o .: "build_hash"
1509− <*> o .: "build_timestamp"
1510− <*> o .: "build_snapshot"
1511− <*> o .: "lucene_version"
1512−
1513−instance ToJSON TermOrder where
1514− toJSON (TermOrder termSortField termSortOrder) = object [termSortField .= termSortOrder]
1515−
1516−instance ToJSON TermInclusion where
1517− toJSON (TermInclusion x) = toJSON x
1518− toJSON (TermPattern pattern flags) = omitNulls [ "pattern" .= pattern,
1519− "flags" .= flags]
1520−
1521−instance ToJSON CollectionMode where
1522− toJSON BreadthFirst = "breadth_first"
1523− toJSON DepthFirst = "depth_first"
1524−
1525−instance ToJSON ExecutionHint where
1526− toJSON Ordinals = "ordinals"
1527− toJSON GlobalOrdinals = "global_ordinals"
1528− toJSON GlobalOrdinalsHash = "global_ordinals_hash"
1529− toJSON GlobalOrdinalsLowCardinality = "global_ordinals_low_cardinality"
1530− toJSON Map = "map"
1531−
1532−instance ToJSON Interval where
1533− toJSON Year = "year"
1534− toJSON Quarter = "quarter"
1535− toJSON Month = "month"
1536− toJSON Week = "week"
1537− toJSON Day = "day"
1538− toJSON Hour = "hour"
1539− toJSON Minute = "minute"
1540− toJSON Second = "second"
1541− toJSON (FractionalInterval fraction interval) = toJSON $ show fraction ++ show interval
1542−
1543−instance Show TimeInterval where
1544− show Weeks = "w"
1545− show Days = "d"
1546− show Hours = "h"
1547− show Minutes = "m"
1548− show Seconds = "s"
1549−
1550−instance ToJSON Aggregation where
1551− toJSON (TermsAgg (TermsAggregation term include exclude order minDocCount size shardSize collectMode executionHint termAggs)) =
1552− omitNulls ["terms" .= omitNulls [ toJSON' term,
1553− "include" .= include,
1554− "exclude" .= exclude,
1555− "order" .= order,
1556− "min_doc_count" .= minDocCount,
1557− "size" .= size,
1558− "shard_size" .= shardSize,
1559− "collect_mode" .= collectMode,
1560− "execution_hint" .= executionHint
1561− ],
1562− "aggs" .= termAggs ]
1563− where
1564− toJSON' x = case x of { Left y -> "field" .= y; Right y -> "script" .= y }
1565−
1566− toJSON (DateHistogramAgg (DateHistogramAggregation field interval format preZone postZone preOffset postOffset dateHistoAggs)) =
1567− omitNulls ["date_histogram" .= omitNulls [ "field" .= field,
1568− "interval" .= interval,
1569− "format" .= format,
1570− "pre_zone" .= preZone,
1571− "post_zone" .= postZone,
1572− "pre_offset" .= preOffset,
1573− "post_offset" .= postOffset
1574− ],
1575− "aggs" .= dateHistoAggs ]
1576− toJSON (ValueCountAgg a) = object ["value_count" .= v]
1577− where v = case a of
1578− (FieldValueCount (FieldName n)) -> object ["field" .= n]
1579− (ScriptValueCount (Script s)) -> object ["script" .= s]
1580− toJSON (FilterAgg (FilterAggregation filt ags)) =
1581− omitNulls [ "filter" .= filt
1582− , "aggs" .= ags]
1583− toJSON (DateRangeAgg a) = object [ "date_range" .= a
1584− ]
1585−
1586−instance ToJSON DateRangeAggregation where
1587− toJSON DateRangeAggregation {..} =
1588− omitNulls [ "field" .= draField
1589− , "format" .= draFormat
1590− , "ranges" .= toList draRanges
1591− ]
1592−
1593−instance ToJSON DateRangeAggRange where
1594− toJSON (DateRangeFrom e) = object [ "from" .= e ]
1595− toJSON (DateRangeTo e) = object [ "to" .= e ]
1596− toJSON (DateRangeFromAndTo f t) = object [ "from" .= f, "to" .= t ]
1597−
1598−instance ToJSON DateMathExpr where
1599− toJSON (DateMathExpr a mods) = String (fmtA a <> mconcat (fmtMod <$> mods))
1600− where fmtA DMNow = "now"
1601− fmtA (DMDate date) = case toGregorian date of
1602− (y,m,d) -> showText y <> "-" <>
1603− showText m <> "-" <>
1604− showText d <> "||"
1605− fmtMod (AddTime n u) = "+" <> showText n <> fmtU u
1606− fmtMod (SubtractTime n u) = "-" <> showText n <> fmtU u
1607− fmtMod (RoundDownTo u) = "/" <> fmtU u
1608− fmtU DMYear = "y"
1609− fmtU DMMonth = "M"
1610− fmtU DMWeek = "w"
1611− fmtU DMDay = "d"
1612− fmtU DMHour = "h"
1613− fmtU DMMinute = "m"
1614− fmtU DMSecond = "s"
1615−
1616−
1617−type AggregationResults = M.Map Text Value
1618−
1619−class BucketAggregation a where
1620− key :: a -> Text
1621− docCount :: a -> Int
1622− aggs :: a -> Maybe AggregationResults
1623−
1624−
1625−data Bucket a = Bucket { buckets :: [a]} deriving (Show)
1626−
1627−data TermsResult = TermsResult { termKey :: Text
1628− , termsDocCount :: Int
1629− , termsAggs :: Maybe AggregationResults } deriving (Show)
1630−
1631−data DateHistogramResult = DateHistogramResult { dateKey :: Int
1632− , dateKeyStr :: Maybe Text
1633− , dateDocCount :: Int
1634− , dateHistogramAggs :: Maybe AggregationResults } deriving (Show)
1635−
1636−data DateRangeResult = DateRangeResult { dateRangeKey :: Text
1637− , dateRangeFrom :: Maybe UTCTime
1638− , dateRangeFromAsString :: Maybe Text
1639− , dateRangeTo :: Maybe UTCTime
1640− , dateRangeToAsString :: Maybe Text
1641− , dateRangeDocCount :: Int
1642− , dateRangeAggs :: Maybe AggregationResults } deriving (Show, Eq)
1643−
1644−toTerms :: Text -> AggregationResults -> Maybe (Bucket TermsResult)
1645−toTerms t a = M.lookup t a >>= deserialize
1646− where deserialize = parseMaybe parseJSON
1647−
1648−toDateHistogram :: Text -> AggregationResults -> Maybe (Bucket DateHistogramResult)
1649−toDateHistogram t a = M.lookup t a >>= deserialize
1650− where deserialize = parseMaybe parseJSON
1651−
1652−instance BucketAggregation TermsResult where
1653− key = termKey
1654− docCount = termsDocCount
1655− aggs = termsAggs
1656−
1657−instance BucketAggregation DateHistogramResult where
1658− key = showText . dateKey
1659− docCount = dateDocCount
1660− aggs = dateHistogramAggs
1661−
1662−instance BucketAggregation DateRangeResult where
1663− key = dateRangeKey
1664− docCount = dateRangeDocCount
1665− aggs = dateRangeAggs
1666−
1667−instance (FromJSON a, BucketAggregation a) => FromJSON (Bucket a) where
1668− parseJSON (Object v) = Bucket <$>
1669− v .: "buckets"
1670− parseJSON _ = mempty
1671−
1672−instance FromJSON TermsResult where
1673− parseJSON (Object v) = TermsResult <$>
1674− v .: "key" <*>
1675− v .: "doc_count" <*>
1676− v .:? "aggregations"
1677− parseJSON _ = mempty
1678−
1679−instance FromJSON DateHistogramResult where
1680− parseJSON (Object v) = DateHistogramResult <$>
1681− v .: "key" <*>
1682− v .:? "key_as_string" <*>
1683− v .: "doc_count" <*>
1684− v .:? "aggregations"
1685− parseJSON _ = mempty
1686−
1687−instance FromJSON DateRangeResult where
1688− parseJSON = withObject "DateRangeResult" parse
1689− where parse v = DateRangeResult <$>
1690− v .: "key" <*>
1691− (fmap posixMS <$> v .:? "from") <*>
1692− v .:? "from_as_string" <*>
1693− (fmap posixMS <$> v .:? "to") <*>
1694− v .:? "to_as_string" <*>
1695− v .: "doc_count" <*>
1696− v .:? "aggregations"
1697−
1698−instance FromJSON POSIXMS where
1699− parseJSON = withScientific "POSIXMS" (return . parse)
1700− where parse n = let n' = truncate n :: Integer
1701− in POSIXMS (posixSecondsToUTCTime (fromInteger (n' `div` 1000)))
1702−
1703−instance Monoid Filter where
1704− mempty = IdentityFilter
1705− mappend a b = AndFilter [a, b] defaultCache
1706−
1707−instance Seminearring Filter where
1708− a <||> b = OrFilter [a, b] defaultCache
1709−
1710−instance ToJSON Filter where
1711− toJSON (AndFilter filters cache) =
1712− object ["and" .=
1713− object [ "filters" .= fmap toJSON filters
1714− , "_cache" .= cache]]
1715−
1716− toJSON (OrFilter filters cache) =
1717− object ["or" .=
1718− object [ "filters" .= fmap toJSON filters
1719− , "_cache" .= cache]]
1720−
1721− toJSON (NotFilter notFilter cache) =
1722− object ["not" .=
1723− object ["filter" .= notFilter
1724− , "_cache" .= cache]]
1725−
1726− toJSON (IdentityFilter) =
1727− object ["match_all" .= object []]
1728−
1729− toJSON (TermFilter (Term termFilterField termFilterValue) cache) =
1730− object ["term" .= object base]
1731− where base = [termFilterField .= termFilterValue,
1732− "_cache" .= cache]
1733−
1734− toJSON (ExistsFilter (FieldName fieldName)) =
1735− object ["exists" .= object
1736− ["field" .= fieldName]]
1737−
1738− toJSON (BoolFilter boolMatch) =
1739− object ["bool" .= boolMatch]
1740−
1741− toJSON (GeoBoundingBoxFilter bbConstraint) =
1742− object ["geo_bounding_box" .= bbConstraint]
1743−
1744− toJSON (GeoDistanceFilter (GeoPoint (FieldName distanceGeoField) geoDistLatLon)
1745− distance distanceType optimizeBbox cache) =
1746− object ["geo_distance" .=
1747− object ["distance" .= distance
1748− , "distance_type" .= distanceType
1749− , "optimize_bbox" .= optimizeBbox
1750− , distanceGeoField .= geoDistLatLon
1751− , "_cache" .= cache]]
1752−
1753− toJSON (GeoDistanceRangeFilter (GeoPoint (FieldName gddrField) drLatLon)
1754− (DistanceRange geoDistRangeDistFrom drDistanceTo)) =
1755− object ["geo_distance_range" .=
1756− object ["from" .= geoDistRangeDistFrom
1757− , "to" .= drDistanceTo
1758− , gddrField .= drLatLon]]
1759−
1760− toJSON (GeoPolygonFilter (FieldName geoPolygonFilterField) latLons) =
1761− object ["geo_polygon" .=
1762− object [geoPolygonFilterField .=
1763− object ["points" .= fmap toJSON latLons]]]
1764−
1765− toJSON (IdsFilter (MappingName mappingName) values) =
1766− object ["ids" .=
1767− object ["type" .= mappingName
1768− , "values" .= fmap unpackId values]]
1769−
1770− toJSON (LimitFilter limit) =
1771− object ["limit" .= object ["value" .= limit]]
1772−
1773− toJSON (MissingFilter (FieldName fieldName) (Existence existence) (NullValue nullValue)) =
1774− object ["missing" .=
1775− object ["field" .= fieldName
1776− , "existence" .= existence
1777− , "null_value" .= nullValue]]
1778−
1779− toJSON (PrefixFilter (FieldName fieldName) fieldValue cache) =
1780− object ["prefix" .=
1781− object [fieldName .= fieldValue
1782− , "_cache" .= cache]]
1783−
1784− toJSON (QueryFilter query False) =
1785− object ["query" .= toJSON query ]
1786− toJSON (QueryFilter query True) =
1787− object ["fquery" .=
1788− object [ "query" .= toJSON query
1789− , "_cache" .= True ]]
1790−
1791− toJSON (RangeFilter (FieldName fieldName) rangeValue rangeExecution cache) =
1792− object ["range" .=
1793− object [ fieldName .= object (rangeValueToPair rangeValue)
1794− , "execution" .= rangeExecution
1795− , "_cache" .= cache]]
1796−
1797− toJSON (RegexpFilter (FieldName fieldName)
1798− (Regexp regexText) flags (CacheName cacheName) cache (CacheKey cacheKey)) =
1799− object ["regexp" .=
1800− object [fieldName .=
1801− object ["value" .= regexText
1802− , "flags" .= flags]
1803− , "_name" .= cacheName
1804− , "_cache" .= cache
1805− , "_cache_key" .= cacheKey]]
1806−
1807−instance FromJSON Filter where
1808− parseJSON = withObject "Filter" parse
1809− where parse o = andFilter `taggedWith` "and"
1810− <|> orFilter `taggedWith` "or"
1811− <|> notFilter `taggedWith` "not"
1812− <|> identityFilter `taggedWith` "match_all"
1813− <|> boolFilter `taggedWith` "bool"
1814− <|> existsFilter `taggedWith` "exists"
1815− <|> geoBoundingBoxFilter `taggedWith` "geo_bounding_box"
1816− <|> geoDistanceFilter `taggedWith` "geo_distance"
1817− <|> geoDistanceRangeFilter `taggedWith` "geo_distance_range"
1818− <|> geoPolygonFilter `taggedWith` "geo_polygon"
1819− <|> idsFilter `taggedWith` "ids"
1820− <|> limitFilter `taggedWith` "limit"
1821− <|> missingFilter `taggedWith` "missing"
1822− <|> prefixFilter `taggedWith` "prefix"
1823− <|> queryFilter `taggedWith` "query"
1824− <|> fqueryFilter `taggedWith` "fquery"
1825− <|> rangeFilter `taggedWith` "range"
1826− <|> regexpFilter `taggedWith` "regexp"
1827− <|> termFilter `taggedWith` "term"
1828− where taggedWith parser k = parser =<< o .: k
1829− andFilter o = AndFilter <$> o .: "filters"
1830− <*> o .:? "_cache" .!= defaultCache
1831− orFilter o = OrFilter <$> o .: "filters"
1832− <*> o .:? "_cache" .!= defaultCache
1833− notFilter o = NotFilter <$> o .: "filter"
1834− <*> o .: "_cache" .!= defaultCache
1835− identityFilter :: Object -> Parser Filter
1836− identityFilter m
1837− | HM.null m = pure IdentityFilter
1838− | otherwise = fail ("Identityfilter expected empty object but got " <> show m)
1839− boolFilter = pure . BoolFilter
1840− existsFilter o = ExistsFilter <$> o .: "field"
1841− geoBoundingBoxFilter = pure . GeoBoundingBoxFilter
1842− geoDistanceFilter o = do
1843− case HM.toList (deleteSeveral ["distance", "distance_type", "optimize_bbox", "_cache"] o) of
1844− [(fn, v)] -> do
1845− gp <- GeoPoint (FieldName fn) <$> parseJSON v
1846− GeoDistanceFilter gp <$> o .: "distance"
1847− <*> o .: "distance_type"
1848− <*> o .: "optimize_bbox"
1849− <*> o .:? "_cache" .!= defaultCache
1850− _ -> fail "Could not find GeoDistanceFilter field name"
1851− geoDistanceRangeFilter o = do
1852− case HM.toList (deleteSeveral ["from", "to"] o) of
1853− [(fn, v)] -> do
1854− gp <- GeoPoint (FieldName fn) <$> parseJSON v
1855− rng <- DistanceRange <$> o .: "from" <*> o .: "to"
1856− return (GeoDistanceRangeFilter gp rng)
1857− _ -> fail "Could not find GeoDistanceRangeFilter field name"
1858− geoPolygonFilter = fieldTagged $ \fn o -> GeoPolygonFilter fn <$> o .: "points"
1859− idsFilter o = IdsFilter <$> o .: "type"
1860− <*> o .: "values"
1861− limitFilter o = LimitFilter <$> o .: "value"
1862− missingFilter o = MissingFilter <$> o .: "field"
1863− <*> o .: "existence"
1864− <*> o .: "null_value"
1865− prefixFilter o = case HM.toList (HM.delete "_cache" o) of
1866− [(fn, String v)] -> PrefixFilter (FieldName fn) v <$> o .:? "_cache" .!= defaultCache
1867− _ -> fail "Could not parse PrefixFilter"
1868−
1869− queryFilter q = pure (QueryFilter q False)
1870− fqueryFilter o = QueryFilter <$> o .: "query" <*> pure True
1871− rangeFilter o = case HM.toList (deleteSeveral ["execution", "_cache"] o) of
1872− [(fn, v)] -> RangeFilter (FieldName fn)
1873− <$> parseJSON v
1874− <*> o .: "execution"
1875− <*> o .:? "_cache" .!= defaultCache
1876− _ -> fail "Could not find field name for RangeFilter"
1877− regexpFilter o = case HM.toList (deleteSeveral ["_name", "_cache", "_cache_key"] o) of
1878− [(fn, Object o')] -> RegexpFilter (FieldName fn)
1879− <$> o' .: "value"
1880− <*> o' .: "flags"
1881− <*> o .: "_name"
1882− <*> o .:? "_cache" .!= defaultCache
1883− <*> o .: "_cache_key"
1884− _ -> fail "Could not find field name for RegexpFilter"
1885− termFilter o = case HM.toList (HM.delete "_cache" o) of
1886− [(termField, String termVal)] -> TermFilter (Term termField termVal)
1887− <$> o .:? "_cache" .!= defaultCache
1888− _ -> fail "Could not find term field for TermFilter"
1889−
1890−fieldTagged :: Monad m => (FieldName -> Object -> m a) -> Object -> m a
1891−fieldTagged f o = case HM.toList o of
1892− [(k, Object o')] -> f (FieldName k) o'
1893− _ -> fail "Expected object with 1 field-named key"
1894−
1895−instance ToJSON GeoPoint where
1896− toJSON (GeoPoint (FieldName geoPointField) geoPointLatLon) =
1897− object [ geoPointField .= geoPointLatLon ]
1898−
1899−
1900−instance ToJSON Query where
1901− toJSON (TermQuery (Term termQueryField termQueryValue) boost) =
1902− object [ "term" .=
1903− object [termQueryField .= object merged]]
1904− where
1905− base = [ "value" .= termQueryValue ]
1906− boosted = maybe [] (return . ("boost" .=)) boost
1907− merged = mappend base boosted
1908−
1909− toJSON (TermsQuery fieldName terms) =
1910− object [ "terms" .= object conjoined ]
1911− where conjoined = [fieldName .= terms]
1912− toJSON (IdsQuery idsQueryMappingName docIds) =
1913− object [ "ids" .= object conjoined ]
1914− where conjoined = [ "type" .= idsQueryMappingName
1915− , "values" .= fmap toJSON docIds ]
1916−
1917− toJSON (QueryQueryStringQuery qQueryStringQuery) =
1918− object [ "query_string" .= qQueryStringQuery ]
1919−
1920− toJSON (QueryMatchQuery matchQuery) =
1921− object [ "match" .= matchQuery ]
1922−
1923− toJSON (QueryMultiMatchQuery multiMatchQuery) =
1924− toJSON multiMatchQuery
1925−
1926− toJSON (QueryBoolQuery boolQuery) =
1927− object [ "bool" .= boolQuery ]
1928−
1929− toJSON (QueryBoostingQuery boostingQuery) =
1930− object [ "boosting" .= boostingQuery ]
1931−
1932− toJSON (QueryCommonTermsQuery commonTermsQuery) =
1933− object [ "common" .= commonTermsQuery ]
1934−
1935− toJSON (ConstantScoreFilter csFilter boost) =
1936− object ["constant_score" .= object ["filter" .= csFilter
1937− , "boost" .= boost]]
1938−
1939− toJSON (ConstantScoreQuery query boost) =
1940− object ["constant_score" .= object ["query" .= query
1941− , "boost" .= boost]]
1942−
1943− toJSON (QueryDisMaxQuery disMaxQuery) =
1944− object [ "dis_max" .= disMaxQuery ]
1945−
1946− toJSON (QueryFilteredQuery qFilteredQuery) =
1947− object [ "filtered" .= qFilteredQuery ]
1948−
1949− toJSON (QueryFuzzyLikeThisQuery fuzzyQuery) =
1950− object [ "fuzzy_like_this" .= fuzzyQuery ]
1951−
1952− toJSON (QueryFuzzyLikeFieldQuery fuzzyFieldQuery) =
1953− object [ "fuzzy_like_this_field" .= fuzzyFieldQuery ]
1954−
1955− toJSON (QueryFuzzyQuery fuzzyQuery) =
1956− object [ "fuzzy" .= fuzzyQuery ]
1957−
1958− toJSON (QueryHasChildQuery childQuery) =
1959− object [ "has_child" .= childQuery ]
1960−
1961− toJSON (QueryHasParentQuery parentQuery) =
1962− object [ "has_parent" .= parentQuery ]
1963−
1964− toJSON (QueryIndicesQuery qIndicesQuery) =
1965− object [ "indices" .= qIndicesQuery ]
1966−
1967− toJSON (MatchAllQuery boost) =
1968− object [ "match_all" .= omitNulls [ "boost" .= boost ] ]
1969−
1970− toJSON (QueryMoreLikeThisQuery query) =
1971− object [ "more_like_this" .= query ]
1972−
1973− toJSON (QueryMoreLikeThisFieldQuery query) =
1974− object [ "more_like_this_field" .= query ]
1975−
1976− toJSON (QueryNestedQuery query) =
1977− object [ "nested" .= query ]
1978−
1979− toJSON (QueryPrefixQuery query) =
1980− object [ "prefix" .= query ]
1981−
1982− toJSON (QueryRangeQuery query) =
1983− object [ "range" .= query ]
1984−
1985− toJSON (QueryRegexpQuery query) =
1986− object [ "regexp" .= query ]
1987−
1988− toJSON (QuerySimpleQueryStringQuery query) =
1989− object [ "simple_query_string" .= query ]
1990−
1991−instance FromJSON Query where
1992− parseJSON v = withObject "Query" parse v
1993− where parse o = termQuery `taggedWith` "term"
1994− <|> termsQuery `taggedWith` "terms"
1995− <|> idsQuery `taggedWith` "ids"
1996− <|> queryQueryStringQuery `taggedWith` "query_string"
1997− <|> queryMatchQuery `taggedWith` "match"
1998− <|> queryMultiMatchQuery
1999− <|> queryBoolQuery `taggedWith` "bool"
2000− <|> queryBoostingQuery `taggedWith` "boosting"
2001− <|> queryCommonTermsQuery `taggedWith` "common"
2002− <|> constantScoreFilter `taggedWith` "constant_score"
2003− <|> constantScoreQuery `taggedWith` "constant_score"
2004− <|> queryDisMaxQuery `taggedWith` "dis_max"
2005− <|> queryFilteredQuery `taggedWith` "filtered"
2006− <|> queryFuzzyLikeThisQuery `taggedWith` "fuzzy_like_this"
2007− <|> queryFuzzyLikeFieldQuery `taggedWith` "fuzzy_like_this_field"
2008− <|> queryFuzzyQuery `taggedWith` "fuzzy"
2009− <|> queryHasChildQuery `taggedWith` "has_child"
2010− <|> queryHasParentQuery `taggedWith` "has_parent"
2011− <|> queryIndicesQuery `taggedWith` "indices"
2012− <|> matchAllQuery `taggedWith` "match_all"
2013− <|> queryMoreLikeThisQuery `taggedWith` "more_like_this"
2014− <|> queryMoreLikeThisFieldQuery `taggedWith` "more_like_this_field"
2015− <|> queryNestedQuery `taggedWith` "nested"
2016− <|> queryPrefixQuery `taggedWith` "prefix"
2017− <|> queryRangeQuery `taggedWith` "range"
2018− <|> queryRegexpQuery `taggedWith` "regexp"
2019− <|> querySimpleQueryStringQuery `taggedWith` "simple_query_string"
2020− where taggedWith parser k = parser =<< o .: k
2021− termQuery = fieldTagged $ \(FieldName fn) o ->
2022− TermQuery <$> (Term fn <$> o .: "value") <*> o .:? "boost"
2023− termsQuery o = case HM.toList o of
2024− [(fn, vs)] -> do vals <- parseJSON vs
2025− case vals of
2026− x:xs -> return (TermsQuery fn (x :| xs))
2027− _ -> fail "Expected non empty list of values"
2028− _ -> fail "Expected object with 1 field-named key"
2029− idsQuery o = IdsQuery <$> o .: "type"
2030− <*> o .: "values"
2031− queryQueryStringQuery = pure . QueryQueryStringQuery
2032− queryMatchQuery = pure . QueryMatchQuery
2033− queryMultiMatchQuery = QueryMultiMatchQuery <$> parseJSON v
2034− queryBoolQuery = pure . QueryBoolQuery
2035− queryBoostingQuery = pure . QueryBoostingQuery
2036− queryCommonTermsQuery = pure . QueryCommonTermsQuery
2037− constantScoreFilter o = case HM.lookup "filter" o of
2038− Just x -> ConstantScoreFilter <$> parseJSON x
2039− <*> o .: "boost"
2040− _ -> fail "Does not appear to be a ConstantScoreFilter"
2041− constantScoreQuery o = case HM.lookup "query" o of
2042− Just x -> ConstantScoreQuery <$> parseJSON x
2043− <*> o .: "boost"
2044− _ -> fail "Does not appear to be a ConstantScoreQuery"
2045− queryDisMaxQuery = pure . QueryDisMaxQuery
2046− queryFilteredQuery = pure . QueryFilteredQuery
2047− queryFuzzyLikeThisQuery = pure . QueryFuzzyLikeThisQuery
2048− queryFuzzyLikeFieldQuery = pure . QueryFuzzyLikeFieldQuery
2049− queryFuzzyQuery = pure . QueryFuzzyQuery
2050− queryHasChildQuery = pure . QueryHasChildQuery
2051− queryHasParentQuery = pure . QueryHasParentQuery
2052− queryIndicesQuery = pure . QueryIndicesQuery
2053− matchAllQuery o = MatchAllQuery <$> o .:? "boost"
2054− queryMoreLikeThisQuery = pure . QueryMoreLikeThisQuery
2055− queryMoreLikeThisFieldQuery = pure . QueryMoreLikeThisFieldQuery
2056− queryNestedQuery = pure . QueryNestedQuery
2057− queryPrefixQuery = pure . QueryPrefixQuery
2058− queryRangeQuery = pure . QueryRangeQuery
2059− queryRegexpQuery = pure . QueryRegexpQuery
2060− querySimpleQueryStringQuery = pure . QuerySimpleQueryStringQuery
2061−
2062−
2063−omitNulls :: [(Text, Value)] -> Value
2064−omitNulls = object . filter notNull where
2065− notNull (_, Null) = False
2066− notNull (_, Array a) = (not . V.null) a
2067− notNull _ = True
2068−
2069−
2070−instance ToJSON SimpleQueryStringQuery where
2071− toJSON SimpleQueryStringQuery {..} =
2072− omitNulls (base ++ maybeAdd)
2073− where base = [ "query" .= simpleQueryStringQuery ]
2074− maybeAdd = [ "fields" .= simpleQueryStringField
2075− , "default_operator" .= simpleQueryStringOperator
2076− , "analyzer" .= simpleQueryStringAnalyzer
2077− , "flags" .= simpleQueryStringFlags
2078− , "lowercase_expanded_terms" .= simpleQueryStringLowercaseExpanded
2079− , "locale" .= simpleQueryStringLocale ]
2080−
2081−instance FromJSON SimpleQueryStringQuery where
2082− parseJSON = withObject "SimpleQueryStringQuery" parse
2083− where parse o = SimpleQueryStringQuery <$> o .: "query"
2084− <*> o .:? "fields"
2085− <*> o .:? "default_operator"
2086− <*> o .:? "analyzer"
2087− <*> (parseFlags <$> o .:? "flags")
2088− <*> o .:? "lowercase_expanded_terms"
2089− <*> o .:? "locale"
2090− parseFlags (Just (x:xs)) = Just (x :| xs)
2091− parseFlags _ = Nothing
2092−
2093−instance ToJSON FieldOrFields where
2094− toJSON (FofField fieldName) =
2095− toJSON fieldName
2096− toJSON (FofFields fieldNames) =
2097− toJSON fieldNames
2098−
2099−instance FromJSON FieldOrFields where
2100− parseJSON v = FofField <$> parseJSON v
2101− <|> FofFields <$> (parseNEJSON =<< parseJSON v)
2102−
2103−instance ToJSON SimpleQueryFlag where
2104− toJSON SimpleQueryAll = "ALL"
2105− toJSON SimpleQueryNone = "NONE"
2106− toJSON SimpleQueryAnd = "AND"
2107− toJSON SimpleQueryOr = "OR"
2108− toJSON SimpleQueryPrefix = "PREFIX"
2109− toJSON SimpleQueryPhrase = "PHRASE"
2110− toJSON SimpleQueryPrecedence = "PRECEDENCE"
2111− toJSON SimpleQueryEscape = "ESCAPE"
2112− toJSON SimpleQueryWhitespace = "WHITESPACE"
2113− toJSON SimpleQueryFuzzy = "FUZZY"
2114− toJSON SimpleQueryNear = "NEAR"
2115− toJSON SimpleQuerySlop = "SLOP"
2116−
2117−instance FromJSON SimpleQueryFlag where
2118− parseJSON = withText "SimpleQueryFlag" parse
2119− where parse "ALL" = pure SimpleQueryAll
2120− parse "NONE" = pure SimpleQueryNone
2121− parse "AND" = pure SimpleQueryAnd
2122− parse "OR" = pure SimpleQueryOr
2123− parse "PREFIX" = pure SimpleQueryPrefix
2124− parse "PHRASE" = pure SimpleQueryPhrase
2125− parse "PRECEDENCE" = pure SimpleQueryPrecedence
2126− parse "ESCAPE" = pure SimpleQueryEscape
2127− parse "WHITESPACE" = pure SimpleQueryWhitespace
2128− parse "FUZZY" = pure SimpleQueryFuzzy
2129− parse "NEAR" = pure SimpleQueryNear
2130− parse "SLOP" = pure SimpleQuerySlop
2131− parse f = fail ("Unexpected SimpleQueryFlag: " <> show f)
2132−
2133−instance ToJSON RegexpQuery where
2134− toJSON (RegexpQuery (FieldName rqQueryField)
2135− (Regexp regexpQueryQuery) rqQueryFlags
2136− rqQueryBoost) =
2137− object [ rqQueryField .= omitNulls base ]
2138− where base = [ "value" .= regexpQueryQuery
2139− , "flags" .= rqQueryFlags
2140− , "boost" .= rqQueryBoost ]
2141−
2142−instance FromJSON RegexpQuery where
2143− parseJSON = withObject "RegexpQuery" parse
2144− where parse = fieldTagged $ \fn o ->
2145− RegexpQuery fn
2146− <$> o .: "value"
2147− <*> o .: "flags"
2148− <*> o .:? "boost"
2149−
2150−instance ToJSON QueryStringQuery where
2151− toJSON (QueryStringQuery qsQueryString
2152− qsDefaultField qsOperator
2153− qsAnalyzer qsAllowWildcard
2154− qsLowercaseExpanded qsEnablePositionIncrements
2155− qsFuzzyMaxExpansions qsFuzziness
2156− qsFuzzyPrefixLength qsPhraseSlop
2157− qsBoost qsAnalyzeWildcard
2158− qsGeneratePhraseQueries qsMinimumShouldMatch
2159− qsLenient qsLocale) =
2160− omitNulls base
2161− where
2162− base = [ "query" .= qsQueryString
2163− , "default_field" .= qsDefaultField
2164− , "default_operator" .= qsOperator
2165− , "analyzer" .= qsAnalyzer
2166− , "allow_leading_wildcard" .= qsAllowWildcard
2167− , "lowercase_expanded_terms" .= qsLowercaseExpanded
2168− , "enable_position_increments" .= qsEnablePositionIncrements
2169− , "fuzzy_max_expansions" .= qsFuzzyMaxExpansions
2170− , "fuzziness" .= qsFuzziness
2171− , "fuzzy_prefix_length" .= qsFuzzyPrefixLength
2172− , "phrase_slop" .= qsPhraseSlop
2173− , "boost" .= qsBoost
2174− , "analyze_wildcard" .= qsAnalyzeWildcard
2175− , "auto_generate_phrase_queries" .= qsGeneratePhraseQueries
2176− , "minimum_should_match" .= qsMinimumShouldMatch
2177− , "lenient" .= qsLenient
2178− , "locale" .= qsLocale ]
2179−
2180−instance FromJSON QueryStringQuery where
2181− parseJSON = withObject "QueryStringQuery" parse
2182− where parse o = QueryStringQuery
2183− <$> o .: "query"
2184− <*> o .:? "default_field"
2185− <*> o .:? "default_operator"
2186− <*> o .:? "analyzer"
2187− <*> o .:? "allow_leading_wildcard"
2188− <*> o .:? "lowercase_expanded_terms"
2189− <*> o .:? "enable_position_increments"
2190− <*> o .:? "fuzzy_max_expansions"
2191− <*> o .:? "fuzziness"
2192− <*> o .:? "fuzzy_prefix_length"
2193− <*> o .:? "phrase_slop"
2194− <*> o .:? "boost"
2195− <*> o .:? "analyze_wildcard"
2196− <*> o .:? "auto_generate_phrase_queries"
2197− <*> o .:? "minimum_should_match"
2198− <*> o .:? "lenient"
2199− <*> o .:? "locale"
2200−
2201−instance ToJSON RangeQuery where
2202− toJSON (RangeQuery (FieldName fieldName) range boost) =
2203− object [ fieldName .= object conjoined ]
2204− where conjoined = [ "boost" .= boost ] ++ (rangeValueToPair range)
2205−
2206−instance FromJSON RangeQuery where
2207− parseJSON = withObject "RangeQuery" parse
2208− where parse = fieldTagged $ \fn o ->
2209− RangeQuery fn
2210− <$> parseJSON (Object o)
2211− <*> o .: "boost"
2212−
2213−instance FromJSON RangeValue where
2214− parseJSON = withObject "RangeValue" parse
2215− where parse o = parseDate o
2216− <|> parseDouble o
2217− parseDate o = do lt <- o .:? "lt"
2218− lte <- o .:? "lte"
2219− gt <- o .:? "gt"
2220− gte <- o .:? "gte"
2221− case (lt, lte, gt, gte) of
2222− (Just a, _, Just b, _) -> return (RangeDateGtLt (GreaterThanD b) (LessThanD a))
2223− (Just a, _, _, Just b)-> return (RangeDateGteLt (GreaterThanEqD b) (LessThanD a))
2224− (_, Just a, Just b, _)-> return (RangeDateGtLte (GreaterThanD b) (LessThanEqD a))
2225− (_, Just a, _, Just b)-> return (RangeDateGteLte (GreaterThanEqD b) (LessThanEqD a))
2226− (_, _, Just a, _)-> return (RangeDateGt (GreaterThanD a))
2227− (Just a, _, _, _)-> return (RangeDateLt (LessThanD a))
2228− (_, _, _, Just a)-> return (RangeDateGte (GreaterThanEqD a))
2229− (_, Just a, _, _)-> return (RangeDateLte (LessThanEqD a))
2230− (Nothing, Nothing, Nothing, Nothing) -> mzero
2231− parseDouble o = do lt <- o .:? "lt"
2232− lte <- o .:? "lte"
2233− gt <- o .:? "gt"
2234− gte <- o .:? "gte"
2235− case (lt, lte, gt, gte) of
2236− (Just a, _, Just b, _) -> return (RangeDoubleGtLt (GreaterThan b) (LessThan a))
2237− (Just a, _, _, Just b)-> return (RangeDoubleGteLt (GreaterThanEq b) (LessThan a))
2238− (_, Just a, Just b, _)-> return (RangeDoubleGtLte (GreaterThan b) (LessThanEq a))
2239− (_, Just a, _, Just b)-> return (RangeDoubleGteLte (GreaterThanEq b) (LessThanEq a))
2240− (_, _, Just a, _)-> return (RangeDoubleGt (GreaterThan a))
2241− (Just a, _, _, _)-> return (RangeDoubleLt (LessThan a))
2242− (_, _, _, Just a)-> return (RangeDoubleGte (GreaterThanEq a))
2243− (_, Just a, _, _)-> return (RangeDoubleLte (LessThanEq a))
2244− (Nothing, Nothing, Nothing, Nothing) -> mzero
2245−
2246−instance ToJSON PrefixQuery where
2247− toJSON (PrefixQuery (FieldName fieldName) queryValue boost) =
2248− object [ fieldName .= omitNulls base ]
2249− where base = [ "value" .= queryValue
2250− , "boost" .= boost ]
2251−
2252−instance FromJSON PrefixQuery where
2253− parseJSON = withObject "PrefixQuery" parse
2254− where parse = fieldTagged $ \fn o ->
2255− PrefixQuery fn
2256− <$> o .: "value"
2257− <*> o .:? "boost"
2258−
2259−instance ToJSON NestedQuery where
2260− toJSON (NestedQuery nqPath nqScoreType nqQuery) =
2261− object [ "path" .= nqPath
2262− , "score_mode" .= nqScoreType
2263− , "query" .= nqQuery ]
2264−
2265−instance FromJSON NestedQuery where
2266− parseJSON = withObject "NestedQuery" parse
2267− where parse o = NestedQuery
2268− <$> o .: "path"
2269− <*> o .: "score_mode"
2270− <*> o .: "query"
2271−
2272−instance ToJSON MoreLikeThisFieldQuery where
2273− toJSON (MoreLikeThisFieldQuery text (FieldName fieldName)
2274− percent mtf mqt stopwords mindf maxdf
2275− minwl maxwl boostTerms boost analyzer) =
2276− object [ fieldName .= omitNulls base ]
2277− where base = [ "like_text" .= text
2278− , "percent_terms_to_match" .= percent
2279− , "min_term_freq" .= mtf
2280− , "max_query_terms" .= mqt
2281− , "stop_words" .= stopwords
2282− , "min_doc_freq" .= mindf
2283− , "max_doc_freq" .= maxdf
2284− , "min_word_length" .= minwl
2285− , "max_word_length" .= maxwl
2286− , "boost_terms" .= boostTerms
2287− , "boost" .= boost
2288− , "analyzer" .= analyzer ]
2289−
2290−instance FromJSON MoreLikeThisFieldQuery where
2291− parseJSON = withObject "MoreLikeThisFieldQuery" parse
2292− where parse = fieldTagged $ \fn o ->
2293− MoreLikeThisFieldQuery
2294− <$> o .: "like_text"
2295− <*> pure fn
2296− <*> o .:? "percent_terms_to_match"
2297− <*> o .:? "min_term_freq"
2298− <*> o .:? "max_query_terms"
2299− <*> (optionalNE =<< o .:? "stop_words")
2300− <*> o .:? "min_doc_freq"
2301− <*> o .:? "max_doc_freq"
2302− <*> o .:? "min_word_length"
2303− <*> o .:? "max_word_length"
2304− <*> o .:? "boost_terms"
2305− <*> o .:? "boost"
2306− <*> o .:? "analyzer"
2307− optionalNE = maybe (pure Nothing) (fmap Just . parseNEJSON)
2308−
2309−instance ToJSON MoreLikeThisQuery where
2310− toJSON (MoreLikeThisQuery text fields percent
2311− mtf mqt stopwords mindf maxdf
2312− minwl maxwl boostTerms boost analyzer) =
2313− omitNulls base
2314− where base = [ "like_text" .= text
2315− , "fields" .= fields
2316− , "percent_terms_to_match" .= percent
2317− , "min_term_freq" .= mtf
2318− , "max_query_terms" .= mqt
2319− , "stop_words" .= stopwords
2320− , "min_doc_freq" .= mindf
2321− , "max_doc_freq" .= maxdf
2322− , "min_word_length" .= minwl
2323− , "max_word_length" .= maxwl
2324− , "boost_terms" .= boostTerms
2325− , "boost" .= boost
2326− , "analyzer" .= analyzer ]
2327−
2328−instance FromJSON MoreLikeThisQuery where
2329− parseJSON = withObject "MoreLikeThisQuery" parse
2330− where parse o = MoreLikeThisQuery
2331− <$> o .: "like_text"
2332− <*> (optionalNE =<< o .:? "fields")
2333− <*> o .:? "percent_terms_to_match"
2334− <*> o .:? "min_term_freq"
2335− <*> o .:? "max_query_terms"
2336− <*> (optionalNE =<< o .:? "stop_words")
2337− <*> o .:? "min_doc_freq"
2338− <*> o .:? "max_doc_freq"
2339− <*> o .:? "min_word_length"
2340− <*> o .:? "max_word_length"
2341− <*> o .:? "boost_terms"
2342− <*> o .:? "boost"
2343− <*> o .:? "analyzer"
2344− optionalNE = maybe (pure Nothing) (fmap Just . parseNEJSON)
2345−
2346−instance ToJSON IndicesQuery where
2347− toJSON (IndicesQuery indices query noMatch) =
2348− omitNulls [ "indices" .= indices
2349− , "no_match_query" .= noMatch
2350− , "query" .= query ]
2351−
2352−instance FromJSON IndicesQuery where
2353− parseJSON = withObject "IndicesQuery" parse
2354− where parse o = IndicesQuery
2355− <$> o .:? "indices" .!= []
2356− <*> o .: "query"
2357− <*> o .:? "no_match_query"
2358−
2359−instance ToJSON HasParentQuery where
2360− toJSON (HasParentQuery queryType query scoreType) =
2361− omitNulls [ "parent_type" .= queryType
2362− , "score_type" .= scoreType
2363− , "query" .= query ]
2364−
2365−instance FromJSON HasParentQuery where
2366− parseJSON = withObject "HasParentQuery" parse
2367− where parse o = HasParentQuery
2368− <$> o .: "parent_type"
2369− <*> o .: "query"
2370− <*> o .:? "score_type"
2371−
2372−instance ToJSON HasChildQuery where
2373− toJSON (HasChildQuery queryType query scoreType) =
2374− omitNulls [ "query" .= query
2375− , "score_type" .= scoreType
2376− , "type" .= queryType ]
2377−
2378−instance FromJSON HasChildQuery where
2379− parseJSON = withObject "HasChildQuery" parse
2380− where parse o = HasChildQuery
2381− <$> o .: "type"
2382− <*> o .: "query"
2383− <*> o .:? "score_type"
2384−
2385−instance ToJSON FuzzyQuery where
2386− toJSON (FuzzyQuery (FieldName fieldName) queryText
2387− prefixLength maxEx fuzziness boost) =
2388− object [ fieldName .= omitNulls base ]
2389− where base = [ "value" .= queryText
2390− , "fuzziness" .= fuzziness
2391− , "prefix_length" .= prefixLength
2392− , "boost" .= boost
2393− , "max_expansions" .= maxEx ]
2394−
2395−instance FromJSON FuzzyQuery where
2396− parseJSON = withObject "FuzzyQuery" parse
2397− where parse = fieldTagged $ \fn o ->
2398− FuzzyQuery fn
2399− <$> o .: "value"
2400− <*> o .: "prefix_length"
2401− <*> o .: "max_expansions"
2402− <*> o .: "fuzziness"
2403− <*> o .:? "boost"
2404−
2405−instance ToJSON FuzzyLikeFieldQuery where
2406− toJSON (FuzzyLikeFieldQuery (FieldName fieldName)
2407− fieldText maxTerms ignoreFreq fuzziness prefixLength
2408− boost analyzer) =
2409− object [ fieldName .=
2410− omitNulls [ "like_text" .= fieldText
2411− , "max_query_terms" .= maxTerms
2412− , "ignore_tf" .= ignoreFreq
2413− , "fuzziness" .= fuzziness
2414− , "prefix_length" .= prefixLength
2415− , "analyzer" .= analyzer
2416− , "boost" .= boost ]]
2417−
2418−instance FromJSON FuzzyLikeFieldQuery where
2419− parseJSON = withObject "FuzzyLikeFieldQuery" parse
2420− where parse = fieldTagged $ \fn o ->
2421− FuzzyLikeFieldQuery fn
2422− <$> o .: "like_text"
2423− <*> o .: "max_query_terms"
2424− <*> o .: "ignore_tf"
2425− <*> o .: "fuzziness"
2426− <*> o .: "prefix_length"
2427− <*> o .: "boost"
2428− <*> o .:? "analyzer"
2429−
2430−instance ToJSON FuzzyLikeThisQuery where
2431− toJSON (FuzzyLikeThisQuery fields text maxTerms
2432− ignoreFreq fuzziness prefixLength boost analyzer) =
2433− omitNulls base
2434− where base = [ "fields" .= fields
2435− , "like_text" .= text
2436− , "max_query_terms" .= maxTerms
2437− , "ignore_tf" .= ignoreFreq
2438− , "fuzziness" .= fuzziness
2439− , "prefix_length" .= prefixLength
2440− , "analyzer" .= analyzer
2441− , "boost" .= boost ]
2442−
2443−instance FromJSON FuzzyLikeThisQuery where
2444− parseJSON = withObject "FuzzyLikeThisQuery" parse
2445− where parse o = FuzzyLikeThisQuery
2446− <$> o .:? "fields" .!= []
2447− <*> o .: "like_text"
2448− <*> o .: "max_query_terms"
2449− <*> o .: "ignore_tf"
2450− <*> o .: "fuzziness"
2451− <*> o .: "prefix_length"
2452− <*> o .: "boost"
2453− <*> o .:? "analyzer"
2454−
2455−instance ToJSON FilteredQuery where
2456− toJSON (FilteredQuery query fFilter) =
2457− object [ "query" .= query
2458− , "filter" .= fFilter ]
2459−
2460−instance FromJSON FilteredQuery where
2461− parseJSON = withObject "FilteredQuery" parse
2462− where parse o = FilteredQuery
2463− <$> o .: "query"
2464− <*> o .: "filter"
2465−
2466−instance ToJSON DisMaxQuery where
2467− toJSON (DisMaxQuery queries tiebreaker boost) =
2468− omitNulls base
2469− where base = [ "queries" .= queries
2470− , "boost" .= boost
2471− , "tie_breaker" .= tiebreaker ]
2472−
2473−instance FromJSON DisMaxQuery where
2474− parseJSON = withObject "DisMaxQuery" parse
2475− where parse o = DisMaxQuery
2476− <$> o .:? "queries" .!= []
2477− <*> o .: "tie_breaker"
2478− <*> o .:? "boost"
2479−
2480−instance ToJSON CommonTermsQuery where
2481− toJSON (CommonTermsQuery (FieldName fieldName)
2482− (QueryString query) cf lfo hfo msm
2483− boost analyzer disableCoord) =
2484− object [fieldName .= omitNulls base ]
2485− where base = [ "query" .= query
2486− , "cutoff_frequency" .= cf
2487− , "low_freq_operator" .= lfo
2488− , "minimum_should_match" .= msm
2489− , "boost" .= boost
2490− , "analyzer" .= analyzer
2491− , "disable_coord" .= disableCoord
2492− , "high_freq_operator" .= hfo ]
2493−
2494−instance FromJSON CommonTermsQuery where
2495− parseJSON = withObject "CommonTermsQuery" parse
2496− where parse = fieldTagged $ \fn o ->
2497− CommonTermsQuery fn
2498− <$> o .: "query"
2499− <*> o .: "cutoff_frequency"
2500− <*> o .: "low_freq_operator"
2501− <*> o .: "high_freq_operator"
2502− <*> o .:? "minimum_should_match"
2503− <*> o .:? "boost"
2504− <*> o .:? "analyzer"
2505− <*> o .:? "disable_coord"
2506−
2507−instance ToJSON CommonMinimumMatch where
2508− toJSON (CommonMinimumMatch mm) = toJSON mm
2509− toJSON (CommonMinimumMatchHighLow (MinimumMatchHighLow lowF highF)) =
2510− object [ "low_freq" .= lowF
2511− , "high_freq" .= highF ]
2512−
2513−instance FromJSON CommonMinimumMatch where
2514− parseJSON v = parseMinimum v
2515− <|> parseMinimumHighLow v
2516− where parseMinimum = fmap CommonMinimumMatch . parseJSON
2517− parseMinimumHighLow = fmap CommonMinimumMatchHighLow . withObject "CommonMinimumMatchHighLow" (\o ->
2518− MinimumMatchHighLow
2519− <$> o .: "low_freq"
2520− <*> o .: "high_freq")
2521−
2522−
2523−instance ToJSON BoostingQuery where
2524− toJSON (BoostingQuery bqPositiveQuery bqNegativeQuery bqNegativeBoost) =
2525− object [ "positive" .= bqPositiveQuery
2526− , "negative" .= bqNegativeQuery
2527− , "negative_boost" .= bqNegativeBoost ]
2528−
2529−instance FromJSON BoostingQuery where
2530− parseJSON = withObject "BoostingQuery" parse
2531− where parse o = BoostingQuery
2532− <$> o .: "positive"
2533− <*> o .: "negative"
2534− <*> o .: "negative_boost"
2535−
2536−instance ToJSON BoolQuery where
2537− toJSON (BoolQuery mustM notM shouldM bqMin boost disableCoord) =
2538− omitNulls base
2539− where base = [ "must" .= mustM
2540− , "must_not" .= notM
2541− , "should" .= shouldM
2542− , "minimum_should_match" .= bqMin
2543− , "boost" .= boost
2544− , "disable_coord" .= disableCoord ]
2545−
2546−instance FromJSON BoolQuery where
2547− parseJSON = withObject "BoolQuery" parse
2548− where parse o = BoolQuery
2549− <$> o .:? "must" .!= []
2550− <*> o .:? "must_not" .!= []
2551− <*> o .:? "should" .!= []
2552− <*> o .:? "minimum_should_match"
2553− <*> o .:? "boost"
2554− <*> o .:? "disable_coord"
2555−
2556−instance ToJSON MatchQuery where
2557− toJSON (MatchQuery (FieldName fieldName)
2558− (QueryString mqQueryString) booleanOperator
2559− zeroTermsQuery cutoffFrequency matchQueryType
2560− analyzer maxExpansions lenient boost) =
2561− object [ fieldName .= omitNulls base ]
2562− where base = [ "query" .= mqQueryString
2563− , "operator" .= booleanOperator
2564− , "zero_terms_query" .= zeroTermsQuery
2565− , "cutoff_frequency" .= cutoffFrequency
2566− , "type" .= matchQueryType
2567− , "analyzer" .= analyzer
2568− , "max_expansions" .= maxExpansions
2569− , "lenient" .= lenient
2570− , "boost" .= boost ]
2571−
2572−instance FromJSON MatchQuery where
2573− parseJSON = withObject "MatchQuery" parse
2574− where parse = fieldTagged $ \fn o ->
2575− MatchQuery fn
2576− <$> o .: "query"
2577− <*> o .: "operator"
2578− <*> o .: "zero_terms_query"
2579− <*> o .:? "cutoff_frequency"
2580− <*> o .:? "type"
2581− <*> o .:? "analyzer"
2582− <*> o .:? "max_expansions"
2583− <*> o .:? "lenient"
2584− <*> o .:? "boost"
2585−
2586−instance ToJSON MultiMatchQuery where
2587− toJSON (MultiMatchQuery fields (QueryString query) boolOp
2588− ztQ tb mmqt cf analyzer maxEx lenient) =
2589− object ["multi_match" .= omitNulls base]
2590− where base = [ "fields" .= fmap toJSON fields
2591− , "query" .= query
2592− , "operator" .= boolOp
2593− , "zero_terms_query" .= ztQ
2594− , "tiebreaker" .= tb
2595− , "type" .= mmqt
2596− , "cutoff_frequency" .= cf
2597− , "analyzer" .= analyzer
2598− , "max_expansions" .= maxEx
2599− , "lenient" .= lenient ]
2600−
2601−instance FromJSON MultiMatchQuery where
2602− parseJSON = withObject "MultiMatchQuery" parse
2603− where parse raw = do o <- raw .: "multi_match"
2604− MultiMatchQuery
2605− <$> o .:? "fields" .!= []
2606− <*> o .: "query"
2607− <*> o .: "operator"
2608− <*> o .: "zero_terms_query"
2609− <*> o .:? "tiebreaker"
2610− <*> o .:? "type"
2611− <*> o .:? "cutoff_frequency"
2612− <*> o .:? "analyzer"
2613− <*> o .:? "max_expansions"
2614− <*> o .:? "lenient"
2615−
2616−instance ToJSON MultiMatchQueryType where
2617− toJSON MultiMatchBestFields = "best_fields"
2618− toJSON MultiMatchMostFields = "most_fields"
2619− toJSON MultiMatchCrossFields = "cross_fields"
2620− toJSON MultiMatchPhrase = "phrase"
2621− toJSON MultiMatchPhrasePrefix = "phrase_prefix"
2622−
2623−instance FromJSON MultiMatchQueryType where
2624− parseJSON = withText "MultiMatchPhrasePrefix" parse
2625− where parse "best_fields" = pure MultiMatchBestFields
2626− parse "most_fields" = pure MultiMatchMostFields
2627− parse "cross_fields" = pure MultiMatchCrossFields
2628− parse "phrase" = pure MultiMatchPhrase
2629− parse "phrase_prefix" = pure MultiMatchPhrasePrefix
2630− parse t = fail ("Unexpected MultiMatchPhrasePrefix: " <> show t)
2631−
2632−instance ToJSON BooleanOperator where
2633− toJSON And = String "and"
2634− toJSON Or = String "or"
2635−
2636−instance FromJSON BooleanOperator where
2637− parseJSON = withText "BooleanOperator" parse
2638− where parse "and" = pure And
2639− parse "or" = pure Or
2640− parse o = fail ("Unexpected BooleanOperator: " <> show o)
2641−
2642−instance ToJSON ZeroTermsQuery where
2643− toJSON ZeroTermsNone = String "none"
2644− toJSON ZeroTermsAll = String "all"
2645−
2646−instance FromJSON ZeroTermsQuery where
2647− parseJSON = withText "ZeroTermsQuery" parse
2648− where parse "none" = pure ZeroTermsNone
2649− parse "all" = pure ZeroTermsAll
2650− parse q = fail ("Unexpected ZeroTermsQuery: " <> show q)
2651−
2652−instance ToJSON MatchQueryType where
2653− toJSON MatchPhrase = "phrase"
2654− toJSON MatchPhrasePrefix = "phrase_prefix"
2655−
2656−instance FromJSON MatchQueryType where
2657− parseJSON = withText "MatchQueryType" parse
2658− where parse "phrase" = pure MatchPhrase
2659− parse "phrase_prefix" = pure MatchPhrasePrefix
2660− parse t = fail ("Unexpected MatchQueryType: " <> show t)
2661−
2662−instance FromJSON Status where
2663− parseJSON (Object v) = Status <$>
2664− v .:? "ok" <*>
2665− v .: "status" <*>
2666− v .: "name" <*>
2667− v .: "version" <*>
2668− v .: "tagline"
2669− parseJSON _ = empty
2670−
2671−
2672−instance ToJSON IndexSettings where
2673− toJSON (IndexSettings s r) = object ["settings" .=
2674− object ["index" .=
2675− object ["number_of_shards" .= s, "number_of_replicas" .= r]
2676− ]
2677− ]
2678−
2679−instance ToJSON IndexTemplate where
2680− toJSON (IndexTemplate p s m) = merge
2681− (object [ "template" .= p
2682− , "mappings" .= foldl' merge (object []) m
2683− ])
2684− (toJSON s)
2685− where
2686− merge (Object o1) (Object o2) = toJSON $ HM.union o1 o2
2687− merge o Null = o
2688− merge _ _ = undefined
2689−
2690−instance (FromJSON a) => FromJSON (EsResult a) where
2691− parseJSON jsonVal@(Object v) = do
2692− found <- v .:? "found" .!= False
2693− fr <- if found
2694− then parseJSON jsonVal
2695− else return Nothing
2696− EsResult <$> v .: "_index" <*>
2697− v .: "_type" <*>
2698− v .: "_id" <*>
2699− pure fr
2700− parseJSON _ = empty
2701−
2702−instance (FromJSON a) => FromJSON (EsResultFound a) where
2703− parseJSON (Object v) = EsResultFound <$>
2704− v .: "_version" <*>
2705− v .: "_source"
2706− parseJSON _ = empty
2707−
2708−instance FromJSON EsError where
2709− parseJSON (Object v) = EsError <$>
2710− v .: "status" <*>
2711− v .: "error"
2712− parseJSON _ = empty
2713−
2714−instance FromJSON IndexAliasesSummary where
2715− parseJSON = withObject "IndexAliasesSummary" parse
2716− where parse o = IndexAliasesSummary . mconcat <$> mapM (uncurry go) (HM.toList o)
2717− go ixn = withObject "index aliases" $ \ia -> do
2718− aliases <- ia .: "aliases"
2719− forM (HM.toList aliases) $ \(aName, v) -> do
2720− let indexAlias = IndexAlias (IndexName ixn) (IndexAliasName (IndexName aName))
2721− IndexAliasSummary indexAlias <$> parseJSON v
2722−
2723−
2724−instance ToJSON IndexAliasAction where
2725− toJSON (AddAlias ia opts) = object ["add" .= (iaObj <> optsObj)]
2726− where Object iaObj = toJSON ia
2727− Object optsObj = toJSON opts
2728− toJSON (RemoveAlias ia) = object ["remove" .= iaObj]
2729− where Object iaObj = toJSON ia
2730−
2731−instance ToJSON IndexAlias where
2732− toJSON IndexAlias {..} = object ["index" .= srcIndex
2733− , "alias" .= indexAlias
2734− ]
2735−
2736−instance ToJSON IndexAliasCreate where
2737− toJSON IndexAliasCreate {..} = Object (filterObj <> routingObj)
2738− where filterObj = maybe mempty (HM.singleton "filter" . toJSON) aliasCreateFilter
2739− Object routingObj = maybe (Object mempty) toJSON aliasCreateRouting
2740−
2741−instance ToJSON AliasRouting where
2742− toJSON (AllAliasRouting v) = object ["routing" .= v]
2743− toJSON (GranularAliasRouting srch idx) = object (catMaybes prs)
2744− where prs = [("search_routing" .=) <$> srch
2745− ,("index_routing" .=) <$> idx]
2746−
2747−instance FromJSON AliasRouting where
2748− parseJSON = withObject "AliasRouting" parse
2749− where parse o = parseAll o <|> parseGranular o
2750− parseAll o = AllAliasRouting <$> o .: "routing"
2751− parseGranular o = do
2752− sr <- o .:? "search_routing"
2753− ir <- o .:? "index_routing"
2754− if isNothing sr && isNothing ir
2755− then fail "Both search_routing and index_routing can't be blank"
2756− else return (GranularAliasRouting sr ir)
2757−
2758−instance FromJSON IndexAliasCreate where
2759− parseJSON v = withObject "IndexAliasCreate" parse v
2760− where parse o = IndexAliasCreate <$> optional (parseJSON v)
2761− <*> o .:? "filter"
2762−
2763−instance ToJSON SearchAliasRouting where
2764− toJSON (SearchAliasRouting rvs) = toJSON (T.intercalate "," (routingValue <$> toList rvs))
2765−
2766−instance FromJSON SearchAliasRouting where
2767− parseJSON = withText "SearchAliasRouting" parse
2768− where parse t = SearchAliasRouting <$> parseNEJSON (String <$> T.splitOn "," t)
2769−
2770−instance ToJSON Search where
2771− toJSON (Search query sFilter sort searchAggs highlight sTrackSortScores sFrom sSize _ sFields sSource) =
2772− omitNulls [ "query" .= query
2773− , "filter" .= sFilter
2774− , "sort" .= sort
2775− , "aggregations" .= searchAggs
2776− , "highlight" .= highlight
2777− , "from" .= sFrom
2778− , "size" .= sSize
2779− , "track_scores" .= sTrackSortScores
2780− , "fields" .= sFields
2781− , "_source" .= sSource]
2782−
488+ deriving (Eq, Show)
2783489
2784490instance ToJSON Source where
2785491 toJSON NoSource = toJSON False
2786492 toJSON (SourcePatterns patterns) = toJSON patterns
2787− toJSON (SourceIncludeExclude incl excl) = object [ "include" .= incl, "exclude" .= excl ]
493+ toJSON (SourceIncludeExclude incl excl) = object [ "includes" .= incl, "excludes" .= excl ]
494+
495+data PatternOrPatterns = PopPattern Pattern
496+ | PopPatterns [Pattern] deriving (Eq, Read, Show)
2788497
2789498instance ToJSON PatternOrPatterns where
2790499 toJSON (PopPattern pattern) = toJSON pattern
2791500 toJSON (PopPatterns patterns) = toJSON patterns
2792501
502+data Include = Include [Pattern] deriving (Eq, Read, Show)
503+data Exclude = Exclude [Pattern] deriving (Eq, Read, Show)
504+
2793505instance ToJSON Include where
2794506 toJSON (Include patterns) = toJSON patterns
2795507
2796508instance ToJSON Exclude where
2797509 toJSON (Exclude patterns) = toJSON patterns
2798510
511+newtype Pattern = Pattern Text deriving (Eq, Read, Show)
512+
2799513instance ToJSON Pattern where
2800514 toJSON (Pattern pattern) = toJSON pattern
2801515
2802−
2803−instance ToJSON FieldHighlight where
2804− toJSON (FieldHighlight (FieldName fName) (Just fSettings)) =
2805− object [ fName .= fSettings ]
2806− toJSON (FieldHighlight (FieldName fName) Nothing) =
2807− object [ fName .= emptyObject ]
2808−
2809−instance ToJSON Highlights where
2810− toJSON (Highlights global fields) =
2811− omitNulls (("fields" .= fields)
2812− : highlightSettingsPairs global)
2813−
2814−instance ToJSON HighlightSettings where
2815− toJSON hs = omitNulls (highlightSettingsPairs (Just hs))
2816−
2817−highlightSettingsPairs :: Maybe HighlightSettings -> [Pair]
2818−highlightSettingsPairs Nothing = []
2819−highlightSettingsPairs (Just (Plain plh)) = plainHighPairs (Just plh)
2820−highlightSettingsPairs (Just (Postings ph)) = postHighPairs (Just ph)
2821−highlightSettingsPairs (Just (FastVector fvh)) = fastVectorHighPairs (Just fvh)
2822−
2823−
2824−plainHighPairs :: Maybe PlainHighlight -> [Pair]
2825−plainHighPairs Nothing = []
2826−plainHighPairs (Just (PlainHighlight plCom plNonPost)) =
2827− [ "type" .= String "plain"]
2828− ++ commonHighlightPairs plCom
2829− ++ nonPostingsToPairs plNonPost
2830−
2831−postHighPairs :: Maybe PostingsHighlight -> [Pair]
2832−postHighPairs Nothing = []
2833−postHighPairs (Just (PostingsHighlight pCom)) =
2834− ("type" .= String "postings")
2835− : commonHighlightPairs pCom
2836−
2837−fastVectorHighPairs :: Maybe FastVectorHighlight -> [Pair]
2838−fastVectorHighPairs Nothing = []
2839−fastVectorHighPairs (Just
2840− (FastVectorHighlight fvCom fvNonPostSettings fvBoundChars
2841− fvBoundMaxScan fvFragOff fvMatchedFields
2842− fvPhraseLim)) =
2843− [ "type" .= String "fvh"
2844− , "boundary_chars" .= fvBoundChars
2845− , "boundary_max_scan" .= fvBoundMaxScan
2846− , "fragment_offset" .= fvFragOff
2847− , "matched_fields" .= fvMatchedFields
2848− , "phraseLimit" .= fvPhraseLim]
2849− ++ commonHighlightPairs fvCom
2850− ++ nonPostingsToPairs fvNonPostSettings
2851−
2852−deleteSeveral :: (Eq k, Hashable k) => [k] -> HM.HashMap k v -> HM.HashMap k v
2853−deleteSeveral ks hm = foldr HM.delete hm ks
2854−
2855−commonHighlightPairs :: Maybe CommonHighlight -> [Pair]
2856−commonHighlightPairs Nothing = []
2857−commonHighlightPairs (Just (CommonHighlight chScore chForceSource chTag chEncoder
2858− chNoMatchSize chHighlightQuery
2859− chRequireFieldMatch)) =
2860− [ "order" .= chScore
2861− , "force_source" .= chForceSource
2862− , "encoder" .= chEncoder
2863− , "no_match_size" .= chNoMatchSize
2864− , "highlight_query" .= chHighlightQuery
2865− , "require_fieldMatch" .= chRequireFieldMatch]
2866− ++ highlightTagToPairs chTag
2867−
2868−
2869−nonPostingsToPairs :: Maybe NonPostings -> [Pair]
2870−nonPostingsToPairs Nothing = []
2871−nonPostingsToPairs (Just (NonPostings npFragSize npNumOfFrags)) =
2872− [ "fragment_size" .= npFragSize
2873− , "number_of_fragments" .= npNumOfFrags]
2874−
2875−parseNEJSON :: (FromJSON a) => [Value] -> Parser (NonEmpty a)
2876−parseNEJSON [] = fail "Expected non-empty list"
2877−parseNEJSON (x:xs) = DT.mapM parseJSON (x :| xs)
2878−
2879−
2880−instance ToJSON HighlightEncoder where
2881− toJSON DefaultEncoder = String "default"
2882− toJSON HTMLEncoder = String "html"
2883−
2884−highlightTagToPairs :: Maybe HighlightTag -> [Pair]
2885−highlightTagToPairs (Just (TagSchema _)) = [ "scheme" .= String "default"]
2886−highlightTagToPairs (Just (CustomTags (pre, post))) = [ "pre_tags" .= pre
2887− , "post_tags" .= post]
2888−highlightTagToPairs Nothing = []
2889−
2890−instance ToJSON SortSpec where
2891− toJSON (DefaultSortSpec
2892− (DefaultSort (FieldName dsSortFieldName) dsSortOrder dsIgnoreUnmapped
2893− dsSortMode dsMissingSort dsNestedFilter)) =
2894− object [dsSortFieldName .= omitNulls base] where
2895− base = [ "order" .= dsSortOrder
2896− , "ignore_unmapped" .= dsIgnoreUnmapped
2897− , "mode" .= dsSortMode
2898− , "missing" .= dsMissingSort
2899− , "nested_filter" .= dsNestedFilter ]
2900−
2901− toJSON (GeoDistanceSortSpec gdsSortOrder (GeoPoint (FieldName field) gdsLatLon) units) =
2902− object [ "unit" .= units
2903− , field .= gdsLatLon
2904− , "order" .= gdsSortOrder ]
2905−
2906−
2907−instance ToJSON SortOrder where
2908− toJSON Ascending = String "asc"
2909− toJSON Descending = String "desc"
2910−
2911−
2912−instance ToJSON SortMode where
2913− toJSON SortMin = String "min"
2914− toJSON SortMax = String "max"
2915− toJSON SortSum = String "sum"
2916− toJSON SortAvg = String "avg"
2917−
2918−
2919−instance ToJSON Missing where
2920− toJSON LastMissing = String "_last"
2921− toJSON FirstMissing = String "_first"
2922− toJSON (CustomMissing txt) = String txt
2923−
2924−
2925−instance ToJSON ScoreType where
2926− toJSON ScoreTypeMax = "max"
2927− toJSON ScoreTypeAvg = "avg"
2928− toJSON ScoreTypeSum = "sum"
2929− toJSON ScoreTypeNone = "none"
2930−
2931−instance FromJSON ScoreType where
2932− parseJSON = withText "ScoreType" parse
2933− where parse "max" = pure ScoreTypeMax
2934− parse "avg" = pure ScoreTypeAvg
2935− parse "sum" = pure ScoreTypeSum
2936− parse "none" = pure ScoreTypeNone
2937− parse t = fail ("Unexpected ScoreType: " <> show t)
2938−
2939−instance ToJSON Distance where
2940− toJSON (Distance dCoefficient dUnit) =
2941− String boltedTogether where
2942− coefText = showText dCoefficient
2943− (String unitText) = toJSON dUnit
2944− boltedTogether = mappend coefText unitText
2945−
2946−instance FromJSON Distance where
2947− parseJSON = withText "Distance" parse
2948− where parse t = Distance <$> parseCoeff nT
2949− <*> parseJSON (String unitT)
2950− where (nT, unitT) = T.span validForNumber t
2951− -- may be a better way to do this
2952− validForNumber '-' = True
2953− validForNumber '.' = True
2954− validForNumber 'e' = True
2955− validForNumber c = isNumber c
2956− parseCoeff "" = fail "Empty string cannot be parsed as number"
2957− parseCoeff s = return (read (T.unpack s))
2958−
2959−instance ToJSON DistanceUnit where
2960− toJSON Miles = String "mi"
2961− toJSON Yards = String "yd"
2962− toJSON Feet = String "ft"
2963− toJSON Inches = String "in"
2964− toJSON Kilometers = String "km"
2965− toJSON Meters = String "m"
2966− toJSON Centimeters = String "cm"
2967− toJSON Millimeters = String "mm"
2968− toJSON NauticalMiles = String "nmi"
2969−
2970−
2971−instance FromJSON DistanceUnit where
2972− parseJSON = withText "DistanceUnit" parse
2973− where parse "mi" = pure Miles
2974− parse "yd" = pure Yards
2975− parse "ft" = pure Feet
2976− parse "in" = pure Inches
2977− parse "km" = pure Kilometers
2978− parse "m" = pure Meters
2979− parse "cm" = pure Centimeters
2980− parse "mm" = pure Millimeters
2981− parse "nmi" = pure NauticalMiles
2982− parse u = fail ("Unrecognized DistanceUnit: " <> show u)
2983−
2984−instance ToJSON DistanceType where
2985− toJSON Arc = String "arc"
2986− toJSON SloppyArc = String "sloppy_arc"
2987− toJSON Plane = String "plane"
2988−
2989−instance FromJSON DistanceType where
2990− parseJSON = withText "DistanceType" parse
2991− where parse "arc" = pure Arc
2992− parse "sloppy_arc" = pure SloppyArc
2993− parse "plane" = pure Plane
2994− parse t = fail ("Unrecognized DistanceType: " <> show t)
2995−
2996−
2997−instance ToJSON OptimizeBbox where
2998− toJSON NoOptimizeBbox = String "none"
2999− toJSON (OptimizeGeoFilterType gft) = toJSON gft
3000−
3001−instance FromJSON OptimizeBbox where
3002− parseJSON v = withText "NoOptimizeBbox" parseNoOptimize v
3003− <|> parseOptimize v
3004− where parseNoOptimize "none" = pure NoOptimizeBbox
3005− parseNoOptimize _ = mzero
3006− parseOptimize = fmap OptimizeGeoFilterType . parseJSON
3007−
3008−instance ToJSON GeoBoundingBoxConstraint where
3009− toJSON (GeoBoundingBoxConstraint
3010− (FieldName gbbcGeoBBField) gbbcConstraintBox cache type') =
3011− object [gbbcGeoBBField .= gbbcConstraintBox
3012− , "_cache" .= cache
3013− , "type" .= type']
3014−
3015−instance FromJSON GeoBoundingBoxConstraint where
3016− parseJSON = withObject "GeoBoundingBoxConstraint" parse
3017− where parse o = case HM.toList (deleteSeveral ["type", "_cache"] o) of
3018− [(fn, v)] -> GeoBoundingBoxConstraint (FieldName fn)
3019− <$> parseJSON v
3020− <*> o .:? "_cache" .!= defaultCache
3021− <*> o .: "type"
3022− _ -> fail "Could not find field name for GeoBoundingBoxConstraint"
3023−
3024−instance ToJSON GeoFilterType where
3025− toJSON GeoFilterMemory = String "memory"
3026− toJSON GeoFilterIndexed = String "indexed"
3027−
3028−instance FromJSON GeoFilterType where
3029− parseJSON = withText "GeoFilterType" parse
3030− where parse "memory" = pure GeoFilterMemory
3031− parse "indexed" = pure GeoFilterIndexed
3032− parse t = fail ("Unrecognized GeoFilterType: " <> show t)
3033−
3034−instance ToJSON GeoBoundingBox where
3035− toJSON (GeoBoundingBox gbbTopLeft gbbBottomRight) =
3036− object ["top_left" .= gbbTopLeft
3037− , "bottom_right" .= gbbBottomRight]
3038−
3039−instance FromJSON GeoBoundingBox where
3040− parseJSON = withObject "GeoBoundingBox" parse
3041− where parse o = GeoBoundingBox
3042− <$> o .: "top_left"
3043− <*> o .: "bottom_right"
3044−
3045−instance ToJSON LatLon where
3046− toJSON (LatLon lLat lLon) =
3047− object ["lat" .= lLat
3048− , "lon" .= lLon]
3049−
3050−instance FromJSON LatLon where
3051− parseJSON = withObject "LatLon" parse
3052− where parse o = LatLon <$> o .: "lat"
3053− <*> o .: "lon"
3054−
3055−-- index for smaller ranges, fielddata for longer ranges
3056−instance ToJSON RangeExecution where
3057− toJSON RangeExecutionIndex = "index"
3058− toJSON RangeExecutionFielddata = "fielddata"
3059−
3060−
3061−instance FromJSON RangeExecution where
3062− parseJSON = withText "RangeExecution" parse
3063− where parse "index" = pure RangeExecutionIndex
3064− parse "fielddata" = pure RangeExecutionFielddata
3065− parse t = error ("Unrecognized RangeExecution " <> show t)
3066−
3067−instance ToJSON RegexpFlags where
3068− toJSON AllRegexpFlags = String "ALL"
3069− toJSON NoRegexpFlags = String "NONE"
3070− toJSON (SomeRegexpFlags (h :| fs)) = String $ T.intercalate "|" flagStrs
3071− where flagStrs = map flagStr . nub $ h:fs
3072− flagStr AnyString = "ANYSTRING"
3073− flagStr Automaton = "AUTOMATON"
3074− flagStr Complement = "COMPLEMENT"
3075− flagStr Empty = "EMPTY"
3076− flagStr Intersection = "INTERSECTION"
3077− flagStr Interval = "INTERVAL"
3078−
3079−instance FromJSON RegexpFlags where
3080− parseJSON = withText "RegexpFlags" parse
3081− where parse "ALL" = pure AllRegexpFlags
3082− parse "NONE" = pure NoRegexpFlags
3083− parse t = SomeRegexpFlags <$> parseNEJSON (String <$> T.splitOn "|" t)
3084−
3085−instance FromJSON RegexpFlag where
3086− parseJSON = withText "RegexpFlag" parse
3087− where parse "ANYSTRING" = pure AnyString
3088− parse "AUTOMATON" = pure Automaton
3089− parse "COMPLEMENT" = pure Complement
3090− parse "EMPTY" = pure Empty
3091− parse "INTERSECTION" = pure Intersection
3092− parse "INTERVAL" = pure Interval
3093− parse f = fail ("Unknown RegexpFlag: " <> show f)
3094−
3095−instance ToJSON Term where
3096− toJSON (Term field value) = object ["term" .= object
3097− [field .= value]]
3098−
3099−instance FromJSON Term where
3100− parseJSON = withObject "Term" parse
3101− where parse o = do termObj <- o .: "term"
3102− case HM.toList termObj of
3103− [(fn, v)] -> Term fn <$> parseJSON v
3104− _ -> fail "Expected object with 1 field-named key"
3105−
3106−instance ToJSON BoolMatch where
3107− toJSON (MustMatch term cache) = object ["must" .= term,
3108− "_cache" .= cache]
3109− toJSON (MustNotMatch term cache) = object ["must_not" .= term,
3110− "_cache" .= cache]
3111− toJSON (ShouldMatch terms cache) = object ["should" .= fmap toJSON terms,
3112− "_cache" .= cache]
3113−
3114−instance FromJSON BoolMatch where
3115− parseJSON = withObject "BoolMatch" parse
3116− where parse o = mustMatch `taggedWith` "must"
3117− <|> mustNotMatch `taggedWith` "must_not"
3118− <|> shouldMatch `taggedWith` "should"
3119− where taggedWith parser k = parser =<< o .: k
3120− mustMatch t = MustMatch t <$> o .:? "_cache" .!= defaultCache
3121− mustNotMatch t = MustNotMatch t <$> o .:? "_cache" .!= defaultCache
3122− shouldMatch t = ShouldMatch t <$> o .:? "_cache" .!= defaultCache
516+data SearchResult a =
517+ SearchResult { took :: Int
518+ , timedOut :: Bool
519+ , shards :: ShardResult
520+ , searchHits :: SearchHits a
521+ , aggregations :: Maybe AggregationResults
522+ , scrollId :: Maybe ScrollId
523+ -- ^ Only one Suggestion request / response per
524+ -- Search is supported.
525+ , suggest :: Maybe NamedSuggestionResponse
526+ }
527+ deriving (Eq, Show)
3123528
3124529instance (FromJSON a) => FromJSON (SearchResult a) where
3125530 parseJSON (Object v) = SearchResult <$>
@@ -3128,52 +533,10 @@ instance (FromJSON a) => FromJSON (SearchResult a) where
3128533 v .: "_shards" <*>
3129534 v .: "hits" <*>
3130535 v .:? "aggregations" <*>
3131− v .:? "_scroll_id"
3132− parseJSON _ = empty
3133−
3134−instance (FromJSON a) => FromJSON (SearchHits a) where
3135− parseJSON (Object v) = SearchHits <$>
3136− v .: "total" <*>
3137− v .: "max_score" <*>
3138− v .: "hits"
536+ v .:? "_scroll_id" <*>
537+ v .:? "suggest"
3139538 parseJSON _ = empty
3140539
3141−instance (FromJSON a) => FromJSON (Hit a) where
3142− parseJSON (Object v) = Hit <$>
3143− v .: "_index" <*>
3144− v .: "_type" <*>
3145− v .: "_id" <*>
3146− v .: "_score" <*>
3147− v .:? "_source" <*>
3148− v .:? "highlight"
3149− parseJSON _ = empty
3150−
3151−instance FromJSON ShardResult where
3152− parseJSON (Object v) = ShardResult <$>
3153− v .: "total" <*>
3154− v .: "successful" <*>
3155− v .: "failed"
3156− parseJSON _ = empty
3157−
3158−
3159−instance FromJSON DocVersion where
3160− parseJSON v = do
3161− i <- parseJSON v
3162− maybe (fail "DocVersion out of range") return $ mkDocVersion i
3163−
3164−instance Bounded DocVersion where
3165− minBound = DocVersion 1
3166− maxBound = DocVersion 9200000000000000000 -- 9.2e+18
3167−
3168−instance Enum DocVersion where
3169− succ x
3170− | x /= maxBound = DocVersion (succ $ docVersionNumber x)
3171− | otherwise = succError "DocVersion"
3172− pred x
3173− | x /= minBound = DocVersion (pred $ docVersionNumber x)
3174− | otherwise = predError "DocVersion"
3175− toEnum i =
3176− fromMaybe (error $ show i ++ " out of DocVersion range") $ mkDocVersion i
3177− fromEnum = docVersionNumber
3178− enumFrom = boundedEnumFrom
3179− enumFromThen = boundedEnumFromThen
540+newtype ScrollId =
541+ ScrollId Text
542+ deriving (Eq, Show, Ord, ToJSON, FromJSON)