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