git.iko.soy/typeable/bloodhound
on e2df8ff help sign in
2104 lines 79 kB history raw
1{-# LANGUAGE DeriveGeneric #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE RecordWildCards #-}
5-------------------------------------------------------------------------------
6-- |
7-- Module : Database.Bloodhound.Types
8-- Copyright : (C) 2014 Chris Allen
9-- License : BSD-style (see the file LICENSE)
10-- Maintainer : Chris Allen <cma@bitemyapp.com
11-- Stability : provisional
12-- Portability : DeriveGeneric, RecordWildCards
13--
14-- Data types for describing actions and data structures performed to interact
15-- with Elasticsearch. The two main buckets your queries against Elasticsearch
16-- will fall into are 'Query's and 'Filter's. 'Filter's are more like
17-- traditional database constraints and often have preferable performance
18-- properties. 'Query's support human-written textual queries, such as fuzzy
19-- queries.
20-------------------------------------------------------------------------------
24module Database.Bloodhound.Types
25 ( defaultCache
26 , defaultIndexSettings
27 , mkSort
28 , showText
29 , unpackId
30 , mkMatchQuery
31 , mkMultiMatchQuery
32 , mkBoolQuery
33 , mkRangeQuery
34 , mkQueryStringQuery
35 , mkAggregations
36 , mkTermsAggregation
37 , mkTermsScriptAggregation
38 , mkDateHistogram
39 , toTerms
40 , toDateHistogram
41 , omitNulls
42 , Version(..)
43 , Status(..)
44 , Existence(..)
45 , NullValue(..)
46 , IndexSettings(..)
47 , Server(..)
48 , Reply
49 , EsResult(..)
50 , Query(..)
51 , Search(..)
52 , SearchResult(..)
53 , SearchHits(..)
54 , ShardResult(..)
55 , Hit(..)
56 , Filter(..)
57 , Seminearring(..)
58 , BoolMatch(..)
59 , Term(..)
60 , GeoPoint(..)
61 , GeoBoundingBoxConstraint(..)
62 , GeoBoundingBox(..)
63 , GeoFilterType(..)
64 , Distance(..)
65 , DistanceUnit(..)
66 , DistanceType(..)
67 , DistanceRange(..)
68 , OptimizeBbox(..)
69 , LatLon(..)
70 , RangeValue(..)
71 , RangeExecution(..)
72 , LessThan(..)
73 , LessThanEq(..)
74 , GreaterThan(..)
75 , GreaterThanEq(..)
76 , LessThanD(..)
77 , LessThanEqD(..)
78 , GreaterThanD(..)
79 , GreaterThanEqD(..)
80 , Regexp(..)
81 , RegexpFlags(..)
82 , RegexpFlag(..)
83 , FieldName(..)
84 , IndexName(..)
85 , MappingName(..)
86 , DocId(..)
87 , CacheName(..)
88 , CacheKey(..)
89 , BulkOperation(..)
90 , ReplicaCount(..)
91 , ShardCount(..)
92 , Sort
93 , SortMode(..)
94 , SortOrder(..)
95 , SortSpec(..)
96 , DefaultSort(..)
97 , Missing(..)
98 , OpenCloseIndex(..)
99 , Method
100 , Boost(..)
101 , MatchQuery(..)
102 , MultiMatchQuery(..)
103 , BoolQuery(..)
104 , BoostingQuery(..)
105 , CommonTermsQuery(..)
106 , DisMaxQuery(..)
107 , FilteredQuery(..)
108 , FuzzyLikeThisQuery(..)
109 , FuzzyLikeFieldQuery(..)
110 , FuzzyQuery(..)
111 , HasChildQuery(..)
112 , HasParentQuery(..)
113 , IndicesQuery(..)
114 , MoreLikeThisQuery(..)
115 , MoreLikeThisFieldQuery(..)
116 , NestedQuery(..)
117 , PrefixQuery(..)
118 , QueryStringQuery(..)
119 , SimpleQueryStringQuery(..)
120 , RangeQuery(..)
121 , RegexpQuery(..)
122 , QueryString(..)
123 , BooleanOperator(..)
124 , ZeroTermsQuery(..)
125 , CutoffFrequency(..)
126 , Analyzer(..)
127 , MaxExpansions(..)
128 , Lenient(..)
129 , MatchQueryType(..)
130 , MultiMatchQueryType(..)
131 , Tiebreaker(..)
132 , MinimumMatch(..)
133 , DisableCoord(..)
134 , CommonMinimumMatch(..)
135 , MinimumMatchHighLow(..)
136 , PrefixLength(..)
137 , Fuzziness(..)
138 , IgnoreTermFrequency(..)
139 , MaxQueryTerms(..)
140 , ScoreType(..)
141 , TypeName(..)
142 , BoostTerms(..)
143 , MaxWordLength(..)
144 , MinWordLength(..)
145 , MaxDocFrequency(..)
146 , MinDocFrequency(..)
147 , PhraseSlop(..)
148 , StopWord(..)
149 , QueryPath(..)
150 , MinimumTermFrequency(..)
151 , PercentMatch(..)
152 , FieldDefinition(..)
153 , MappingField(..)
154 , Mapping(..)
155 , AllowLeadingWildcard(..)
156 , LowercaseExpanded(..)
157 , GeneratePhraseQueries(..)
158 , Locale(..)
159 , AnalyzeWildcard(..)
160 , EnablePositionIncrements(..)
161 , SimpleQueryFlag(..)
162 , FieldOrFields(..)
163 , Monoid(..)
164 , ToJSON(..)
165 , Interval(..)
166 , TimeInterval(..)
167 , ExecutionHint(..)
168 , CollectionMode(..)
169 , TermOrder(..)
170 , TermInclusion(..)
172 , Aggregation(..)
173 , Aggregations
174 , AggregationResults
175 , Bucket(..)
176 , BucketAggregation(..)
177 , TermsAggregation(..)
178 , DateHistogramAggregation(..)
180 , Highlights(..)
181 , FieldHighlight(..)
182 , HighlightSettings(..)
183 , PlainHighlight(..)
184 , PostingsHighlight(..)
185 , FastVectorHighlight(..)
186 , CommonHighlight(..)
187 , NonPostings(..)
188 , HighlightEncoder(..)
189 , HighlightTag(..)
190 , HitHighlight
192 , TermsResult(..)
193 , DateHistogramResult(..)
194 ) where
196import Control.Applicative
197import Data.Aeson
198import Data.Aeson.Types (Pair, emptyObject, parseMaybe)
199import qualified Data.ByteString.Lazy.Char8 as L
200import Data.List (nub)
201import Data.List.NonEmpty (NonEmpty(..), toList)
202import qualified Data.Map.Strict as M
203import Data.Monoid
204import Data.Text (Text)
205import qualified Data.Text as T
206import Data.Time.Clock (UTCTime)
207import qualified Data.Vector as V
208import GHC.Generics (Generic)
209import Network.HTTP.Client
210import qualified Network.HTTP.Types.Method as NHTM
212import Database.Bloodhound.Types.Class
214-- $setup
215-- >>> :set -XOverloadedStrings
216-- >>> import Database.Bloodhound
217-- >>> let testServer = (Server "http://localhost:9200")
218-- >>> let testIndex = IndexName "twitter"
219-- >>> let testMapping = MappingName "tweet"
220-- >>> let defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
222-- defaultIndexSettings is exported by Database.Bloodhound as well
223-- no trailing slashes in servers, library handles building the path.
225{-| 'Version' is embedded in 'Status' -}
226data Version = Version { number :: Text
227 , build_hash :: Text
228 , build_timestamp :: UTCTime
229 , build_snapshot :: Bool
230 , lucene_version :: Text } deriving (Eq, Show, Generic)
232{-| 'Status' is a data type for describing the JSON body returned by
233 Elasticsearch when you query its status. This was deprecated in 1.2.0.
235 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-status.html#indices-status>
236-}
238data Status = Status { ok :: Maybe Bool
239 , status :: Int
240 , name :: Text
241 , version :: Version
242 , tagline :: Text } deriving (Eq, Show)
244{-| 'IndexSettings' is used to configure the shards and replicas when you create
245 an Elasticsearch Index.
247 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html>
248-}
250data IndexSettings =
251 IndexSettings { indexShards :: ShardCount
252 , indexReplicas :: ReplicaCount } deriving (Eq, Show)
254{-| 'defaultIndexSettings' is an 'IndexSettings' with 3 shards and 2 replicas. -}
255defaultIndexSettings :: IndexSettings
256defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
258{-| 'Reply' and 'Method' are type synonyms from 'Network.HTTP.Types.Method.Method' -}
259type Reply = Network.HTTP.Client.Response L.ByteString
260type Method = NHTM.Method
262{-| 'OpenCloseIndex' is a sum type for opening and closing indices.
264 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-open-close.html>
265-}
266data OpenCloseIndex = OpenIndex | CloseIndex deriving (Eq, Show)
268data FieldType = GeoPointType
269 | GeoShapeType
270 | FloatType
271 | IntegerType
272 | LongType
273 | ShortType
274 | ByteType deriving (Eq, Show)
276data FieldDefinition =
277 FieldDefinition { fieldType :: FieldType } deriving (Eq, Show)
279data MappingField =
280 MappingField { mappingFieldName :: FieldName
281 , fieldDefinition :: FieldDefinition } deriving (Eq, Show)
283{-| Support for type reification of 'Mapping's is currently incomplete, for
284 now the mapping API verbiage expects a 'ToJSON'able blob.
286 Indexes have mappings, mappings are schemas for the documents contained in the
287 index. I'd recommend having only one mapping per index, always having a mapping,
288 and keeping different kinds of documents separated if possible.
289-}
290data Mapping = Mapping { typeName :: TypeName
291 , mappingFields :: [MappingField] } deriving (Eq, Show)
293{-| 'BulkOperation' is a sum type for expressing the four kinds of bulk
294 operation index, create, delete, and update. 'BulkIndex' behaves like an
295 "upsert", 'BulkCreate' will fail if a document already exists at the DocId.
297 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-bulk.html#docs-bulk>
298-}
299data BulkOperation =
300 BulkIndex IndexName MappingName DocId Value
301 | BulkCreate IndexName MappingName DocId Value
302 | BulkDelete IndexName MappingName DocId
303 | BulkUpdate IndexName MappingName DocId Value deriving (Eq, Show)
305{-| 'EsResult' describes the standard wrapper JSON document that you see in
306 successful Elasticsearch responses.
307-}
308data EsResult a = EsResult { _index :: Text
309 , _type :: Text
310 , _id :: Text
311 , _version :: Int
312 , found :: Maybe Bool
313 , _source :: a } deriving (Eq, Show)
315{-| 'Sort' is a synonym for a list of 'SortSpec's. Sort behavior is order
316 dependent with later sorts acting as tie-breakers for earlier sorts.
317-}
318type Sort = [SortSpec]
320{-| The two main kinds of 'SortSpec' are 'DefaultSortSpec' and
321 'GeoDistanceSortSpec'. The latter takes a 'SortOrder', 'GeoPoint', and
322 'DistanceUnit' to express "nearness" to a single geographical point as a
323 sort specification.
325<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
326-}
327data SortSpec = DefaultSortSpec DefaultSort
328 | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit deriving (Eq, Show)
330{-| 'DefaultSort' is usually the kind of 'SortSpec' you'll want. There's a
331 'mkSort' convenience function for when you want to specify only the most
332 common parameters.
334<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
335-}
336data DefaultSort =
337 DefaultSort { sortFieldName :: FieldName
338 , sortOrder :: SortOrder
339 -- default False
340 , ignoreUnmapped :: Bool
341 , sortMode :: Maybe SortMode
342 , missingSort :: Maybe Missing
343 , nestedFilter :: Maybe Filter } deriving (Eq, Show)
345{-| 'SortOrder' is 'Ascending' or 'Descending', as you might expect. These get
346 encoded into "asc" or "desc" when turned into JSON.
348<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
349-}
350data SortOrder = Ascending
351 | Descending deriving (Eq, Show)
353{-| 'Missing' prescribes how to handle missing fields. A missing field can be
354 sorted last, first, or using a custom value as a substitute.
356<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_missing_values>
357-}
358data Missing = LastMissing
359 | FirstMissing
360 | CustomMissing Text deriving (Eq, Show)
362{-| 'SortMode' prescribes how to handle sorting array/multi-valued fields.
364http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_sort_mode_option
365-}
366data SortMode = SortMin
367 | SortMax
368 | SortSum
369 | SortAvg deriving (Eq, Show)
371{-| 'mkSort' defaults everything but the 'FieldName' and the 'SortOrder' so
372 that you can concisely describe the usual kind of 'SortSpec's you want.
373-}
374mkSort :: FieldName -> SortOrder -> DefaultSort
375mkSort fieldName sOrder = DefaultSort fieldName sOrder False Nothing Nothing Nothing
377{-| 'Cache' is for telling ES whether it should cache a 'Filter' not.
378 'Query's cannot be cached.
379-}
380type Cache = Bool -- caching on/off
381defaultCache :: Cache
382defaultCache = False
384{-| 'PrefixValue' is used in 'PrefixQuery' as the main query component.
385-}
386type PrefixValue = Text
388{-| 'BooleanOperator' is the usual And/Or operators with an ES compatible
389 JSON encoding baked in. Used all over the place.
390-}
391data BooleanOperator = And | Or deriving (Eq, Show)
393{-| 'ShardCount' is part of 'IndexSettings'
394-}
395newtype ShardCount = ShardCount Int deriving (Eq, Show, Generic)
397{-| 'ReplicaCount' is part of 'IndexSettings'
398-}
399newtype ReplicaCount = ReplicaCount Int deriving (Eq, Show, Generic)
401{-| 'Server' is used with the client functions to point at the ES instance
402-}
403newtype Server = Server String deriving (Eq, Show)
405{-| 'IndexName' is used to describe which index to query/create/delete
406-}
407newtype IndexName = IndexName String deriving (Eq, Generic, Show)
409{-| 'MappingName' is part of mappings which are how ES describes and schematizes
410 the data in the indices.
411-}
412newtype MappingName = MappingName String deriving (Eq, Generic, Show)
414{-| 'DocId' is a generic wrapper value for expressing unique Document IDs.
415 Can be set by the user or created by ES itself. Often used in client
416 functions for poking at specific documents.
417-}
418newtype DocId = DocId String deriving (Eq, Generic, Show)
420{-| 'QueryString' is used to wrap query text bodies, be they human written or not.
421-}
422newtype QueryString = QueryString Text deriving (Eq, Generic, Show)
424{-| 'FieldName' is used all over the place wherever a specific field within
425 a document needs to be specified, usually in 'Query's or 'Filter's.
426-}
427newtype FieldName = FieldName Text deriving (Eq, Show)
429{-| 'CacheName' is used in 'RegexpFilter' for describing the
430 'CacheKey' keyed caching behavior.
431-}
432newtype CacheName = CacheName Text deriving (Eq, Show)
434{-| 'CacheKey' is used in 'RegexpFilter' to key regex caching.
435-}
436newtype CacheKey =
437 CacheKey Text deriving (Eq, Show)
438newtype Existence =
439 Existence Bool deriving (Eq, Show)
440newtype NullValue =
441 NullValue Bool deriving (Eq, Show)
442newtype CutoffFrequency =
443 CutoffFrequency Double deriving (Eq, Show, Generic)
444newtype Analyzer =
445 Analyzer Text deriving (Eq, Show, Generic)
446newtype MaxExpansions =
447 MaxExpansions Int deriving (Eq, Show, Generic)
449{-| 'Lenient', if set to true, will cause format based failures to be
450 ignored. I don't know what the bloody default is, Elasticsearch
451 documentation didn't say what it was. Let me know if you figure it out.
452-}
453newtype Lenient =
454 Lenient Bool deriving (Eq, Show, Generic)
455newtype Tiebreaker =
456 Tiebreaker Double deriving (Eq, Show, Generic)
457newtype Boost =
458 Boost Double deriving (Eq, Show, Generic)
459newtype BoostTerms =
460 BoostTerms Double deriving (Eq, Show, Generic)
462{-| 'MinimumMatch' controls how many should clauses in the bool query should
463 match. Can be an absolute value (2) or a percentage (30%) or a
464 combination of both.
465-}
466newtype MinimumMatch =
467 MinimumMatch Int deriving (Eq, Show, Generic)
468newtype MinimumMatchText =
469 MinimumMatchText Text deriving (Eq, Show)
470newtype DisableCoord =
471 DisableCoord Bool deriving (Eq, Show, Generic)
472newtype IgnoreTermFrequency =
473 IgnoreTermFrequency Bool deriving (Eq, Show, Generic)
474newtype MinimumTermFrequency =
475 MinimumTermFrequency Int deriving (Eq, Show, Generic)
476newtype MaxQueryTerms =
477 MaxQueryTerms Int deriving (Eq, Show, Generic)
478newtype Fuzziness =
479 Fuzziness Double deriving (Eq, Show, Generic)
481{-| 'PrefixLength' is the prefix length used in queries, defaults to 0. -}
482newtype PrefixLength =
483 PrefixLength Int deriving (Eq, Show, Generic)
484newtype TypeName =
485 TypeName Text deriving (Eq, Show, Generic)
486newtype PercentMatch =
487 PercentMatch Double deriving (Eq, Show, Generic)
488newtype StopWord =
489 StopWord Text deriving (Eq, Show, Generic)
490newtype QueryPath =
491 QueryPath Text deriving (Eq, Show, Generic)
493{-| Allowing a wildcard at the beginning of a word (eg "*ing") is particularly
494 heavy, because all terms in the index need to be examined, just in case
495 they match. Leading wildcards can be disabled by setting
496 'AllowLeadingWildcard' to false. -}
497newtype AllowLeadingWildcard =
498 AllowLeadingWildcard Bool deriving (Eq, Show, Generic)
499newtype LowercaseExpanded =
500 LowercaseExpanded Bool deriving (Eq, Show, Generic)
501newtype EnablePositionIncrements =
502 EnablePositionIncrements Bool deriving (Eq, Show, Generic)
504{-| By default, wildcard terms in a query are not analyzed.
505 Setting 'AnalyzeWildcard' to true enables best-effort analysis.
506-}
507newtype AnalyzeWildcard = AnalyzeWildcard Bool deriving (Eq, Show, Generic)
509{-| 'GeneratePhraseQueries' defaults to false.
510-}
511newtype GeneratePhraseQueries =
512 GeneratePhraseQueries Bool deriving (Eq, Show, Generic)
514{-| 'Locale' is used for string conversions - defaults to ROOT.
515-}
516newtype Locale = Locale Text deriving (Eq, Show, Generic)
517newtype MaxWordLength = MaxWordLength Int deriving (Eq, Show, Generic)
518newtype MinWordLength = MinWordLength Int deriving (Eq, Show, Generic)
520{-| 'PhraseSlop' sets the default slop for phrases, 0 means exact
521 phrase matches. Default is 0.
522-}
523newtype PhraseSlop = PhraseSlop Int deriving (Eq, Show, Generic)
524newtype MinDocFrequency = MinDocFrequency Int deriving (Eq, Show, Generic)
525newtype MaxDocFrequency = MaxDocFrequency Int deriving (Eq, Show, Generic)
527{-| 'unpackId' is a silly convenience function that gets used once.
528-}
529unpackId :: DocId -> String
530unpackId (DocId docId) = docId
532type TrackSortScores = Bool
533type From = Int
534type Size = Int
536data Search = Search { queryBody :: Maybe Query
537 , filterBody :: Maybe Filter
538 , sortBody :: Maybe Sort
539 , aggBody :: Maybe Aggregations
540 , highlight :: Maybe Highlights
541 -- default False
542 , trackSortScores :: TrackSortScores
543 , from :: From
544 , size :: Size } deriving (Eq, Show)
546data Highlights = Highlights { globalsettings :: Maybe HighlightSettings
547 , highlightFields :: [FieldHighlight]
548 } deriving (Show, Eq)
550data FieldHighlight = FieldHighlight FieldName (Maybe HighlightSettings)
551 deriving (Show, Eq)
554data HighlightSettings = Plain PlainHighlight
555 | Postings PostingsHighlight
556 | FastVector FastVectorHighlight
557 deriving (Show, Eq)
558data PlainHighlight =
559 PlainHighlight { plainCommon :: Maybe CommonHighlight
560 , plainNonPost :: Maybe NonPostings } deriving (Show, Eq)
562 -- This requires that index_options are set to 'offset' in the mapping.
563data PostingsHighlight = PostingsHighlight (Maybe CommonHighlight) deriving (Show, Eq)
565-- This requires that term_vector is set to 'with_positions_offsets' in the mapping.
566data FastVectorHighlight =
567 FastVectorHighlight { fvCommon :: Maybe CommonHighlight
568 , fvNonPostSettings :: Maybe NonPostings
569 , boundaryChars :: Maybe Text
570 , boundaryMaxScan :: Maybe Int
571 , fragmentOffset :: Maybe Int
572 , matchedFields :: [Text]
573 , phraseLimit :: Maybe Int
574 } deriving (Show, Eq)
576data CommonHighlight =
577 CommonHighlight { order :: Maybe Text
578 , forceSource :: Maybe Bool
579 , tag :: Maybe HighlightTag
580 , encoder :: Maybe HighlightEncoder
581 , noMatchSize :: Maybe Int
582 , highlightQuery :: Maybe Query
583 , requireFieldMatch :: Maybe Bool
584 } deriving (Show, Eq)
586-- Settings that are only applicable to FastVector and Plain highlighters.
587data NonPostings =
588 NonPostings { fragmentSize :: Maybe Int
589 , numberOfFragments :: Maybe Int} deriving (Show, Eq)
591data HighlightEncoder = DefaultEncoder
592 | HTMLEncoder
593 deriving (Show, Eq)
595-- NOTE: Should the tags use some kind of HTML type, rather than Text?
596data HighlightTag = TagSchema Text
597 | CustomTags ([Text], [Text]) -- Only uses more than the first value in the lists if fvh
598 deriving (Show, Eq)
601data Query =
602 TermQuery Term (Maybe Boost)
603 | TermsQuery (NonEmpty Term)
604 | QueryMatchQuery MatchQuery
605 | QueryMultiMatchQuery MultiMatchQuery
606 | QueryBoolQuery BoolQuery
607 | QueryBoostingQuery BoostingQuery
608 | QueryCommonTermsQuery CommonTermsQuery
609 | ConstantScoreFilter Filter Boost
610 | ConstantScoreQuery Query Boost
611 | QueryDisMaxQuery DisMaxQuery
612 | QueryFilteredQuery FilteredQuery
613 | QueryFuzzyLikeThisQuery FuzzyLikeThisQuery
614 | QueryFuzzyLikeFieldQuery FuzzyLikeFieldQuery
615 | QueryFuzzyQuery FuzzyQuery
616 | QueryHasChildQuery HasChildQuery
617 | QueryHasParentQuery HasParentQuery
618 | IdsQuery MappingName [DocId]
619 | QueryIndicesQuery IndicesQuery
620 | MatchAllQuery (Maybe Boost)
621 | QueryMoreLikeThisQuery MoreLikeThisQuery
622 | QueryMoreLikeThisFieldQuery MoreLikeThisFieldQuery
623 | QueryNestedQuery NestedQuery
624 | QueryPrefixQuery PrefixQuery
625 | QueryQueryStringQuery QueryStringQuery
626 | QuerySimpleQueryStringQuery SimpleQueryStringQuery
627 | QueryRangeQuery RangeQuery
628 | QueryRegexpQuery RegexpQuery
629 deriving (Eq, Show)
631data RegexpQuery =
632 RegexpQuery { regexpQueryField :: FieldName
633 , regexpQuery :: Regexp
634 , regexpQueryFlags :: RegexpFlags
635 , regexpQueryBoost :: Maybe Boost
636 } deriving (Eq, Show)
638data RangeQuery =
639 RangeQuery { rangeQueryField :: FieldName
640 , rangeQueryRange :: RangeValue
641 , rangeQueryBoost :: Boost } deriving (Eq, Show)
643mkRangeQuery :: FieldName -> RangeValue -> RangeQuery
644mkRangeQuery f r = RangeQuery f r (Boost 1.0)
646data SimpleQueryStringQuery =
647 SimpleQueryStringQuery
648 { simpleQueryStringQuery :: QueryString
649 , simpleQueryStringField :: Maybe FieldOrFields
650 , simpleQueryStringOperator :: Maybe BooleanOperator
651 , simpleQueryStringAnalyzer :: Maybe Analyzer
652 , simpleQueryStringFlags :: Maybe [SimpleQueryFlag]
653 , simpleQueryStringLowercaseExpanded :: Maybe LowercaseExpanded
654 , simpleQueryStringLocale :: Maybe Locale
655 } deriving (Eq, Show)
657data SimpleQueryFlag =
658 SimpleQueryAll
659 | SimpleQueryNone
660 | SimpleQueryAnd
661 | SimpleQueryOr
662 | SimpleQueryPrefix
663 | SimpleQueryPhrase
664 | SimpleQueryPrecedence
665 | SimpleQueryEscape
666 | SimpleQueryWhitespace
667 | SimpleQueryFuzzy
668 | SimpleQueryNear
669 | SimpleQuerySlop deriving (Eq, Show)
671-- use_dis_max and tie_breaker when fields are plural?
672data QueryStringQuery =
673 QueryStringQuery
674 { queryStringQuery :: QueryString
675 , queryStringDefaultField :: Maybe FieldName
676 , queryStringOperator :: Maybe BooleanOperator
677 , queryStringAnalyzer :: Maybe Analyzer
678 , queryStringAllowLeadingWildcard :: Maybe AllowLeadingWildcard
679 , queryStringLowercaseExpanded :: Maybe LowercaseExpanded
680 , queryStringEnablePositionIncrements :: Maybe EnablePositionIncrements
681 , queryStringFuzzyMaxExpansions :: Maybe MaxExpansions
682 , queryStringFuzziness :: Maybe Fuzziness
683 , queryStringFuzzyPrefixLength :: Maybe PrefixLength
684 , queryStringPhraseSlop :: Maybe PhraseSlop
685 , queryStringBoost :: Maybe Boost
686 , queryStringAnalyzeWildcard :: Maybe AnalyzeWildcard
687 , queryStringGeneratePhraseQueries :: Maybe GeneratePhraseQueries
688 , queryStringMinimumShouldMatch :: Maybe MinimumMatch
689 , queryStringLenient :: Maybe Lenient
690 , queryStringLocale :: Maybe Locale
691 } deriving (Eq, Show)
693mkQueryStringQuery :: QueryString -> QueryStringQuery
694mkQueryStringQuery qs =
695 QueryStringQuery qs Nothing Nothing
696 Nothing Nothing Nothing Nothing
697 Nothing Nothing Nothing Nothing
698 Nothing Nothing Nothing Nothing
699 Nothing Nothing
701data FieldOrFields = FofField FieldName
702 | FofFields [FieldName] deriving (Eq, Show)
704data PrefixQuery =
705 PrefixQuery
706 { prefixQueryField :: FieldName
707 , prefixQueryPrefixValue :: Text
708 , prefixQueryBoost :: Maybe Boost } deriving (Eq, Show)
710data NestedQuery =
711 NestedQuery
712 { nestedQueryPath :: QueryPath
713 , nestedQueryScoreType :: ScoreType
714 , nestedQuery :: Query } deriving (Eq, Show)
716data MoreLikeThisFieldQuery =
717 MoreLikeThisFieldQuery
718 { moreLikeThisFieldText :: Text
719 , moreLikeThisFieldFields :: FieldName
720 -- default 0.3 (30%)
721 , moreLikeThisFieldPercentMatch :: Maybe PercentMatch
722 , moreLikeThisFieldMinimumTermFreq :: Maybe MinimumTermFrequency
723 , moreLikeThisFieldMaxQueryTerms :: Maybe MaxQueryTerms
724 , moreLikeThisFieldStopWords :: Maybe [StopWord]
725 , moreLikeThisFieldMinDocFrequency :: Maybe MinDocFrequency
726 , moreLikeThisFieldMaxDocFrequency :: Maybe MaxDocFrequency
727 , moreLikeThisFieldMinWordLength :: Maybe MinWordLength
728 , moreLikeThisFieldMaxWordLength :: Maybe MaxWordLength
729 , moreLikeThisFieldBoostTerms :: Maybe BoostTerms
730 , moreLikeThisFieldBoost :: Maybe Boost
731 , moreLikeThisFieldAnalyzer :: Maybe Analyzer
732 } deriving (Eq, Show)
734data MoreLikeThisQuery =
735 MoreLikeThisQuery
736 { moreLikeThisText :: Text
737 , moreLikeThisFields :: Maybe [FieldName]
738 -- default 0.3 (30%)
739 , moreLikeThisPercentMatch :: Maybe PercentMatch
740 , moreLikeThisMinimumTermFreq :: Maybe MinimumTermFrequency
741 , moreLikeThisMaxQueryTerms :: Maybe MaxQueryTerms
742 , moreLikeThisStopWords :: Maybe [StopWord]
743 , moreLikeThisMinDocFrequency :: Maybe MinDocFrequency
744 , moreLikeThisMaxDocFrequency :: Maybe MaxDocFrequency
745 , moreLikeThisMinWordLength :: Maybe MinWordLength
746 , moreLikeThisMaxWordLength :: Maybe MaxWordLength
747 , moreLikeThisBoostTerms :: Maybe BoostTerms
748 , moreLikeThisBoost :: Maybe Boost
749 , moreLikeThisAnalyzer :: Maybe Analyzer
750 } deriving (Eq, Show)
752data IndicesQuery =
753 IndicesQuery
754 { indicesQueryIndices :: [IndexName]
755 , indicesQuery :: Query
756 -- default "all"
757 , indicesQueryNoMatch :: Maybe Query } deriving (Eq, Show)
759data HasParentQuery =
760 HasParentQuery
761 { hasParentQueryType :: TypeName
762 , hasParentQuery :: Query
763 , hasParentQueryScoreType :: Maybe ScoreType } deriving (Eq, Show)
765data HasChildQuery =
766 HasChildQuery
767 { hasChildQueryType :: TypeName
768 , hasChildQuery :: Query
769 , hasChildQueryScoreType :: Maybe ScoreType } deriving (Eq, Show)
771data ScoreType =
772 ScoreTypeMax
773 | ScoreTypeSum
774 | ScoreTypeAvg
775 | ScoreTypeNone deriving (Eq, Show)
777data FuzzyQuery =
778 FuzzyQuery { fuzzyQueryField :: FieldName
779 , fuzzyQueryValue :: Text
780 , fuzzyQueryPrefixLength :: PrefixLength
781 , fuzzyQueryMaxExpansions :: MaxExpansions
782 , fuzzyQueryFuzziness :: Fuzziness
783 , fuzzyQueryBoost :: Maybe Boost
784 } deriving (Eq, Show)
786data FuzzyLikeFieldQuery =
787 FuzzyLikeFieldQuery
788 { fuzzyLikeField :: FieldName
789 -- anaphora is good for the soul.
790 , fuzzyLikeFieldText :: Text
791 , fuzzyLikeFieldMaxQueryTerms :: MaxQueryTerms
792 , fuzzyLikeFieldIgnoreTermFrequency :: IgnoreTermFrequency
793 , fuzzyLikeFieldFuzziness :: Fuzziness
794 , fuzzyLikeFieldPrefixLength :: PrefixLength
795 , fuzzyLikeFieldBoost :: Boost
796 , fuzzyLikeFieldAnalyzer :: Maybe Analyzer
797 } deriving (Eq, Show)
799data FuzzyLikeThisQuery =
800 FuzzyLikeThisQuery
801 { fuzzyLikeFields :: [FieldName]
802 , fuzzyLikeText :: Text
803 , fuzzyLikeMaxQueryTerms :: MaxQueryTerms
804 , fuzzyLikeIgnoreTermFrequency :: IgnoreTermFrequency
805 , fuzzyLikeFuzziness :: Fuzziness
806 , fuzzyLikePrefixLength :: PrefixLength
807 , fuzzyLikeBoost :: Boost
808 , fuzzyLikeAnalyzer :: Maybe Analyzer
809 } deriving (Eq, Show)
811data FilteredQuery =
812 FilteredQuery
813 { filteredQuery :: Query
814 , filteredFilter :: Filter } deriving (Eq, Show)
816data DisMaxQuery =
817 DisMaxQuery { disMaxQueries :: [Query]
818 -- default 0.0
819 , disMaxTiebreaker :: Tiebreaker
820 , disMaxBoost :: Maybe Boost
821 } deriving (Eq, Show)
823data MatchQuery =
824 MatchQuery { matchQueryField :: FieldName
825 , matchQueryQueryString :: QueryString
826 , matchQueryOperator :: BooleanOperator
827 , matchQueryZeroTerms :: ZeroTermsQuery
828 , matchQueryCutoffFrequency :: Maybe CutoffFrequency
829 , matchQueryMatchType :: Maybe MatchQueryType
830 , matchQueryAnalyzer :: Maybe Analyzer
831 , matchQueryMaxExpansions :: Maybe MaxExpansions
832 , matchQueryLenient :: Maybe Lenient } deriving (Eq, Show)
834{-| 'mkMatchQuery' is a convenience function that defaults the less common parameters,
835 enabling you to provide only the 'FieldName' and 'QueryString' to make a 'MatchQuery'
836-}
837mkMatchQuery :: FieldName -> QueryString -> MatchQuery
838mkMatchQuery field query = MatchQuery field query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing
840data MatchQueryType =
841 MatchPhrase
842 | MatchPhrasePrefix deriving (Eq, Show)
844data MultiMatchQuery =
845 MultiMatchQuery { multiMatchQueryFields :: [FieldName]
846 , multiMatchQueryString :: QueryString
847 , multiMatchQueryOperator :: BooleanOperator
848 , multiMatchQueryZeroTerms :: ZeroTermsQuery
849 , multiMatchQueryTiebreaker :: Maybe Tiebreaker
850 , multiMatchQueryType :: Maybe MultiMatchQueryType
851 , multiMatchQueryCutoffFrequency :: Maybe CutoffFrequency
852 , multiMatchQueryAnalyzer :: Maybe Analyzer
853 , multiMatchQueryMaxExpansions :: Maybe MaxExpansions
854 , multiMatchQueryLenient :: Maybe Lenient } deriving (Eq, Show)
856{-| 'mkMultiMatchQuery' is a convenience function that defaults the less common parameters,
857 enabling you to provide only the list of 'FieldName's and 'QueryString' to
858 make a 'MultiMatchQuery'.
859-}
861mkMultiMatchQuery :: [FieldName] -> QueryString -> MultiMatchQuery
862mkMultiMatchQuery matchFields query =
863 MultiMatchQuery matchFields query
864 Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
866data MultiMatchQueryType =
867 MultiMatchBestFields
868 | MultiMatchMostFields
869 | MultiMatchCrossFields
870 | MultiMatchPhrase
871 | MultiMatchPhrasePrefix deriving (Eq, Show)
873data BoolQuery =
874 BoolQuery { boolQueryMustMatch :: [Query]
875 , boolQueryMustNotMatch :: [Query]
876 , boolQueryShouldMatch :: [Query]
877 , boolQueryMinimumShouldMatch :: Maybe MinimumMatch
878 , boolQueryBoost :: Maybe Boost
879 , boolQueryDisableCoord :: Maybe DisableCoord
880 } deriving (Eq, Show)
882mkBoolQuery :: [Query] -> [Query] -> [Query] -> BoolQuery
883mkBoolQuery must mustNot should =
884 BoolQuery must mustNot should Nothing Nothing Nothing
886data BoostingQuery =
887 BoostingQuery { positiveQuery :: Query
888 , negativeQuery :: Query
889 , negativeBoost :: Boost } deriving (Eq, Show)
891data CommonTermsQuery =
892 CommonTermsQuery { commonField :: FieldName
893 , commonQuery :: QueryString
894 , commonCutoffFrequency :: CutoffFrequency
895 , commonLowFreqOperator :: BooleanOperator
896 , commonHighFreqOperator :: BooleanOperator
897 , commonMinimumShouldMatch :: Maybe CommonMinimumMatch
898 , commonBoost :: Maybe Boost
899 , commonAnalyzer :: Maybe Analyzer
900 , commonDisableCoord :: Maybe DisableCoord
901 } deriving (Eq, Show)
903data CommonMinimumMatch =
904 CommonMinimumMatchHighLow MinimumMatchHighLow
905 | CommonMinimumMatch MinimumMatch
906 deriving (Eq, Show)
908data MinimumMatchHighLow =
909 MinimumMatchHighLow { lowFreq :: MinimumMatch
910 , highFreq :: MinimumMatch } deriving (Eq, Show)
912data Filter = AndFilter [Filter] Cache
913 | OrFilter [Filter] Cache
914 | NotFilter Filter Cache
915 | IdentityFilter
916 | BoolFilter BoolMatch
917 | ExistsFilter FieldName -- always cached
918 | GeoBoundingBoxFilter GeoBoundingBoxConstraint
919 | GeoDistanceFilter GeoPoint Distance DistanceType OptimizeBbox Cache
920 | GeoDistanceRangeFilter GeoPoint DistanceRange
921 | GeoPolygonFilter FieldName [LatLon]
922 | IdsFilter MappingName [DocId]
923 | LimitFilter Int
924 | MissingFilter FieldName Existence NullValue
925 | PrefixFilter FieldName PrefixValue Cache
926 | RangeFilter FieldName RangeValue RangeExecution Cache
927 | RegexpFilter FieldName Regexp RegexpFlags CacheName Cache CacheKey
928 | TermFilter Term Cache
929 deriving (Eq, Show)
931data ZeroTermsQuery = ZeroTermsNone
932 | ZeroTermsAll deriving (Eq, Show)
934data RangeExecution = RangeExecutionIndex
935 | RangeExecutionFielddata deriving (Eq, Show)
937newtype Regexp = Regexp Text deriving (Eq, Show)
939data RegexpFlags = AllRegexpFlags
940 | NoRegexpFlags
941 | SomeRegexpFlags (NonEmpty RegexpFlag) deriving (Eq, Show)
943data RegexpFlag = AnyString
944 | Automaton
945 | Complement
946 | Empty
947 | Intersection
948 | Interval deriving (Eq, Show)
950newtype LessThan = LessThan Double deriving (Eq, Show)
951newtype LessThanEq = LessThanEq Double deriving (Eq, Show)
952newtype GreaterThan = GreaterThan Double deriving (Eq, Show)
953newtype GreaterThanEq = GreaterThanEq Double deriving (Eq, Show)
955newtype LessThanD = LessThanD UTCTime deriving (Eq, Show)
956newtype LessThanEqD = LessThanEqD UTCTime deriving (Eq, Show)
957newtype GreaterThanD = GreaterThanD UTCTime deriving (Eq, Show)
958newtype GreaterThanEqD = GreaterThanEqD UTCTime deriving (Eq, Show)
960data RangeValue = RangeDateLte LessThanEqD
961 | RangeDateLt LessThanD
962 | RangeDateGte GreaterThanEqD
963 | RangeDateGt GreaterThanD
964 | RangeDateGtLt GreaterThanD LessThanD
965 | RangeDateGteLte GreaterThanEqD LessThanEqD
966 | RangeDateGteLt GreaterThanEqD LessThanD
967 | RangeDateGtLte GreaterThanD LessThanEqD
968 | RangeDoubleLte LessThanEq
969 | RangeDoubleLt LessThan
970 | RangeDoubleGte GreaterThanEq
971 | RangeDoubleGt GreaterThan
972 | RangeDoubleGtLt GreaterThan LessThan
973 | RangeDoubleGteLte GreaterThanEq LessThanEq
974 | RangeDoubleGteLt GreaterThanEq LessThan
975 | RangeDoubleGtLte GreaterThan LessThanEq
976 deriving (Eq, Show)
978rangeValueToPair :: RangeValue -> [Pair]
979rangeValueToPair rv = case rv of
980 RangeDateLte (LessThanEqD t) -> ["lte" .= t]
981 RangeDateGte (GreaterThanEqD t) -> ["gte" .= t]
982 RangeDateLt (LessThanD t) -> ["lt" .= t]
983 RangeDateGt (GreaterThanD t) -> ["gt" .= t]
984 RangeDateGteLte (GreaterThanEqD l) (LessThanEqD g) -> ["gte" .= l, "lte" .= g]
985 RangeDateGtLte (GreaterThanD l) (LessThanEqD g) -> ["gt" .= l, "lte" .= g]
986 RangeDateGteLt (GreaterThanEqD l) (LessThanD g) -> ["gte" .= l, "lt" .= g]
987 RangeDateGtLt (GreaterThanD l) (LessThanD g) -> ["gt" .= l, "lt" .= g]
988 RangeDoubleLte (LessThanEq t) -> ["lte" .= t]
989 RangeDoubleGte (GreaterThanEq t) -> ["gte" .= t]
990 RangeDoubleLt (LessThan t) -> ["lt" .= t]
991 RangeDoubleGt (GreaterThan t) -> ["gt" .= t]
992 RangeDoubleGteLte (GreaterThanEq l) (LessThanEq g) -> ["gte" .= l, "lte" .= g]
993 RangeDoubleGtLte (GreaterThan l) (LessThanEq g) -> ["gt" .= l, "lte" .= g]
994 RangeDoubleGteLt (GreaterThanEq l) (LessThan g) -> ["gte" .= l, "lt" .= g]
995 RangeDoubleGtLt (GreaterThan l) (LessThan g) -> ["gt" .= l, "lt" .= g]
997data Term = Term { termField :: Text
998 , termValue :: Text } deriving (Eq, Show)
1000data BoolMatch = MustMatch Term Cache
1001 | MustNotMatch Term Cache
1002 | ShouldMatch [Term] Cache deriving (Eq, Show)
1004-- "memory" or "indexed"
1005data GeoFilterType = GeoFilterMemory
1006 | GeoFilterIndexed deriving (Eq, Show)
1008data LatLon = LatLon { lat :: Double
1009 , lon :: Double } deriving (Eq, Show)
1011data GeoBoundingBox =
1012 GeoBoundingBox { topLeft :: LatLon
1013 , bottomRight :: LatLon } deriving (Eq, Show)
1015data GeoBoundingBoxConstraint =
1016 GeoBoundingBoxConstraint { geoBBField :: FieldName
1017 , constraintBox :: GeoBoundingBox
1018 , bbConstraintcache :: Cache
1019 , geoType :: GeoFilterType
1020 } deriving (Eq, Show)
1022data GeoPoint =
1023 GeoPoint { geoField :: FieldName
1024 , latLon :: LatLon} deriving (Eq, Show)
1026data DistanceUnit = Miles
1027 | Yards
1028 | Feet
1029 | Inches
1030 | Kilometers
1031 | Meters
1032 | Centimeters
1033 | Millimeters
1034 | NauticalMiles deriving (Eq, Show)
1036data DistanceType = Arc
1037 | SloppyArc -- doesn't exist <1.0
1038 | Plane deriving (Eq, Show)
1040data OptimizeBbox = OptimizeGeoFilterType GeoFilterType
1041 | NoOptimizeBbox deriving (Eq, Show)
1043data Distance =
1044 Distance { coefficient :: Double
1045 , unit :: DistanceUnit } deriving (Eq, Show)
1047data DistanceRange =
1048 DistanceRange { distanceFrom :: Distance
1049 , distanceTo :: Distance } deriving (Eq, Show)
1051data SearchResult a =
1052 SearchResult { took :: Int
1053 , timedOut :: Bool
1054 , shards :: ShardResult
1055 , searchHits :: SearchHits a
1056 , aggregations :: Maybe AggregationResults } deriving (Eq, Show)
1058type Score = Double
1060data SearchHits a =
1061 SearchHits { hitsTotal :: Int
1062 , maxScore :: Score
1063 , hits :: [Hit a] } deriving (Eq, Show)
1065data Hit a =
1066 Hit { hitIndex :: IndexName
1067 , hitType :: MappingName
1068 , hitDocId :: DocId
1069 , hitScore :: Score
1070 , hitSource :: a
1071 , hitHighlight :: Maybe HitHighlight } deriving (Eq, Show)
1073data ShardResult =
1074 ShardResult { shardTotal :: Int
1075 , shardsSuccessful :: Int
1076 , shardsFailed :: Int } deriving (Eq, Show, Generic)
1078type HitHighlight = M.Map Text [Text]
1080showText :: Show a => a -> Text
1081showText = T.pack . show
1083type Aggregations = M.Map Text Aggregation
1085emptyAggregations :: Aggregations
1086emptyAggregations = M.empty
1088mkAggregations :: Text -> Aggregation -> Aggregations
1089mkAggregations name aggregation = M.insert name aggregation emptyAggregations
1091data TermOrder = TermOrder{ termSortField :: Text
1092 , termSortOrder :: SortOrder } deriving (Eq, Show)
1094data TermInclusion = TermInclusion Text
1095 | TermPattern Text Text deriving (Eq, Show)
1097data CollectionMode = BreadthFirst
1098 | DepthFirst deriving (Eq, Show)
1100data ExecutionHint = Ordinals
1101 | GlobalOrdinals
1102 | GlobalOrdinalsHash
1103 | GlobalOrdinalsLowCardinality
1104 | Map deriving (Eq, Show)
1106data TimeInterval = Weeks
1107 | Days
1108 | Hours
1109 | Minutes
1110 | Seconds deriving (Eq)
1112data Interval = Year
1113 | Quarter
1114 | Month
1115 | Week
1116 | Day
1117 | Hour
1118 | Minute
1119 | Second
1120 | FractionalInterval Float TimeInterval deriving (Eq, Show)
1122data Aggregation = TermsAgg TermsAggregation
1123 | DateHistogramAgg DateHistogramAggregation deriving (Eq, Show)
1126data TermsAggregation = TermsAggregation { term :: Either Text Text
1127 , termInclude :: Maybe TermInclusion
1128 , termExclude :: Maybe TermInclusion
1129 , termOrder :: Maybe TermOrder
1130 , termMinDocCount :: Maybe Int
1131 , termSize :: Maybe Int
1132 , termShardSize :: Maybe Int
1133 , termCollectMode :: Maybe CollectionMode
1134 , termExecutionHint :: Maybe ExecutionHint
1135 , termAggs :: Maybe Aggregations
1136 } deriving (Eq, Show)
1138data DateHistogramAggregation = DateHistogramAggregation { dateField :: FieldName
1139 , dateInterval :: Interval
1140 , dateFormat :: Maybe Text
1141 , datePreZone :: Maybe Text
1142 , datePostZone :: Maybe Text
1143 , datePreOffset :: Maybe Text
1144 , datePostOffset :: Maybe Text
1145 , dateAggs :: Maybe Aggregations
1146 } deriving (Eq, Show)
1149mkTermsAggregation :: Text -> TermsAggregation
1150mkTermsAggregation t = TermsAggregation (Left t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1152mkTermsScriptAggregation :: Text -> TermsAggregation
1153mkTermsScriptAggregation t = TermsAggregation (Right t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
1155mkDateHistogram :: FieldName -> Interval -> DateHistogramAggregation
1156mkDateHistogram t i = DateHistogramAggregation t i Nothing Nothing Nothing Nothing Nothing Nothing
1158instance ToJSON TermOrder where
1159 toJSON (TermOrder termSortField termSortOrder) = object [termSortField .= termSortOrder]
1161instance ToJSON TermInclusion where
1162 toJSON (TermInclusion x) = toJSON x
1163 toJSON (TermPattern pattern flags) = omitNulls [ "pattern" .= pattern,
1164 "flags" .= flags]
1166instance ToJSON CollectionMode where
1167 toJSON BreadthFirst = "breadth_first"
1168 toJSON DepthFirst = "depth_first"
1170instance ToJSON ExecutionHint where
1171 toJSON Ordinals = "ordinals"
1172 toJSON GlobalOrdinals = "global_ordinals"
1173 toJSON GlobalOrdinalsHash = "global_ordinals_hash"
1174 toJSON GlobalOrdinalsLowCardinality = "global_ordinals_low_cardinality"
1175 toJSON Map = "map"
1177instance ToJSON Interval where
1178 toJSON Year = "year"
1179 toJSON Quarter = "quarter"
1180 toJSON Month = "month"
1181 toJSON Week = "week"
1182 toJSON Day = "day"
1183 toJSON Hour = "hour"
1184 toJSON Minute = "minute"
1185 toJSON Second = "second"
1186 toJSON (FractionalInterval fraction interval) = toJSON $ show fraction ++ show interval
1188instance Show TimeInterval where
1189 show Weeks = "w"
1190 show Days = "d"
1191 show Hours = "h"
1192 show Minutes = "m"
1193 show Seconds = "s"
1195instance ToJSON Aggregation where
1196 toJSON (TermsAgg (TermsAggregation term include exclude order minDocCount size shardSize collectMode executionHint termAggs)) =
1197 omitNulls ["terms" .= omitNulls [ toJSON' term,
1198 "include" .= toJSON include,
1199 "exclude" .= toJSON exclude,
1200 "order" .= toJSON order,
1201 "min_doc_count" .= toJSON minDocCount,
1202 "size" .= toJSON size,
1203 "shard_size" .= toJSON shardSize,
1204 "collect_mode" .= toJSON collectMode,
1205 "execution_hint" .= toJSON executionHint
1206 ],
1207 "aggs" .= toJSON termAggs ]
1208 where
1209 toJSON' x = case x of { Left y -> "field" .= toJSON y; Right y -> "script" .= toJSON y }
1211 toJSON (DateHistogramAgg (DateHistogramAggregation field interval format preZone postZone preOffset postOffset dateHistoAggs)) =
1212 omitNulls ["date_histogram" .= omitNulls [ "field" .= toJSON field,
1213 "interval" .= toJSON interval,
1214 "format" .= toJSON format,
1215 "pre_zone" .= toJSON preZone,
1216 "post_zone" .= toJSON postZone,
1217 "pre_offset" .= toJSON preOffset,
1218 "post_offset" .= toJSON postOffset
1219 ],
1220 "aggs" .= toJSON dateHistoAggs ]
1222type AggregationResults = M.Map Text Value
1224class BucketAggregation a where
1225 key :: a -> Text
1226 docCount :: a -> Int
1227 aggs :: a -> Maybe AggregationResults
1230data Bucket a = Bucket { buckets :: [a]} deriving (Show)
1232data TermsResult = TermsResult { termKey :: Text
1233 , termsDocCount :: Int
1234 , termsAggs :: Maybe AggregationResults } deriving (Show)
1236data DateHistogramResult = DateHistogramResult { dateKey :: Int
1237 , dateKeyStr :: Maybe Text
1238 , dateDocCount :: Int
1239 , dateHistogramAggs :: Maybe AggregationResults } deriving (Show)
1241toTerms :: Text -> AggregationResults -> Maybe (Bucket TermsResult)
1242toTerms t a = M.lookup t a >>= deserialize
1243 where deserialize = parseMaybe parseJSON
1245toDateHistogram :: Text -> AggregationResults -> Maybe (Bucket DateHistogramResult)
1246toDateHistogram t a = M.lookup t a >>= deserialize
1247 where deserialize = parseMaybe parseJSON
1249instance BucketAggregation TermsResult where
1250 key = termKey
1251 docCount = termsDocCount
1252 aggs = termsAggs
1254instance BucketAggregation DateHistogramResult where
1255 key = showText . dateKey
1256 docCount = dateDocCount
1257 aggs = dateHistogramAggs
1259instance (FromJSON a, BucketAggregation a) => FromJSON (Bucket a) where
1260 parseJSON (Object v) = Bucket <$>
1261 v .: "buckets"
1262 parseJSON _ = mempty
1264instance FromJSON TermsResult where
1265 parseJSON (Object v) = TermsResult <$>
1266 v .: "key" <*>
1267 v .: "doc_count" <*>
1268 v .:? "aggregations"
1269 parseJSON _ = mempty
1271instance FromJSON DateHistogramResult where
1272 parseJSON (Object v) = DateHistogramResult <$>
1273 v .: "key" <*>
1274 v .:? "key_as_string" <*>
1275 v .: "doc_count" <*>
1276 v .:? "aggregations"
1277 parseJSON _ = mempty
1279instance Monoid Filter where
1280 mempty = IdentityFilter
1281 mappend a b = AndFilter [a, b] defaultCache
1283instance Seminearring Filter where
1284 a <||> b = OrFilter [a, b] defaultCache
1286instance ToJSON Filter where
1287 toJSON (AndFilter filters cache) =
1288 object ["and" .=
1289 object [ "filters" .= fmap toJSON filters
1290 , "_cache" .= cache]]
1292 toJSON (OrFilter filters cache) =
1293 object ["or" .=
1294 object [ "filters" .= fmap toJSON filters
1295 , "_cache" .= cache]]
1297 toJSON (NotFilter notFilter cache) =
1298 object ["not" .=
1299 object ["filter" .= toJSON notFilter
1300 , "_cache" .= cache]]
1302 toJSON (IdentityFilter) =
1303 object ["match_all" .= object []]
1305 toJSON (TermFilter (Term termFilterField termFilterValue) cache) =
1306 object ["term" .= object base]
1307 where base = [termFilterField .= termFilterValue,
1308 "_cache" .= cache]
1310 toJSON (ExistsFilter (FieldName fieldName)) =
1311 object ["exists" .= object
1312 ["field" .= fieldName]]
1314 toJSON (BoolFilter boolMatch) =
1315 object ["bool" .= toJSON boolMatch]
1317 toJSON (GeoBoundingBoxFilter bbConstraint) =
1318 object ["geo_bounding_box" .= toJSON bbConstraint]
1320 toJSON (GeoDistanceFilter (GeoPoint (FieldName distanceGeoField) geoDistLatLon)
1321 distance distanceType optimizeBbox cache) =
1322 object ["geo_distance" .=
1323 object ["distance" .= toJSON distance
1324 , "distance_type" .= toJSON distanceType
1325 , "optimize_bbox" .= optimizeBbox
1326 , distanceGeoField .= toJSON geoDistLatLon
1327 , "_cache" .= cache]]
1329 toJSON (GeoDistanceRangeFilter (GeoPoint (FieldName gddrField) drLatLon)
1330 (DistanceRange geoDistRangeDistFrom drDistanceTo)) =
1331 object ["geo_distance_range" .=
1332 object ["from" .= toJSON geoDistRangeDistFrom
1333 , "to" .= toJSON drDistanceTo
1334 , gddrField .= toJSON drLatLon]]
1336 toJSON (GeoPolygonFilter (FieldName geoPolygonFilterField) latLons) =
1337 object ["geo_polygon" .=
1338 object [geoPolygonFilterField .=
1339 object ["points" .= fmap toJSON latLons]]]
1341 toJSON (IdsFilter (MappingName mappingName) values) =
1342 object ["ids" .=
1343 object ["type" .= mappingName
1344 , "values" .= fmap (T.pack . unpackId) values]]
1346 toJSON (LimitFilter limit) =
1347 object ["limit" .= object ["value" .= limit]]
1349 toJSON (MissingFilter (FieldName fieldName) (Existence existence) (NullValue nullValue)) =
1350 object ["missing" .=
1351 object ["field" .= fieldName
1352 , "existence" .= existence
1353 , "null_value" .= nullValue]]
1355 toJSON (PrefixFilter (FieldName fieldName) fieldValue cache) =
1356 object ["prefix" .=
1357 object [fieldName .= fieldValue
1358 , "_cache" .= cache]]
1360 toJSON (RangeFilter (FieldName fieldName) rangeValue rangeExecution cache) =
1361 object ["range" .=
1362 object [ fieldName .= object (rangeValueToPair rangeValue)
1363 , "execution" .= toJSON rangeExecution
1364 , "_cache" .= cache]]
1366 toJSON (RegexpFilter (FieldName fieldName)
1367 (Regexp regexText) flags (CacheName cacheName) cache (CacheKey cacheKey)) =
1368 object ["regexp" .=
1369 object [fieldName .=
1370 object ["value" .= regexText
1371 , "flags" .= toJSON flags]
1372 , "_name" .= cacheName
1373 , "_cache" .= cache
1374 , "_cache_key" .= cacheKey]]
1376instance ToJSON GeoPoint where
1377 toJSON (GeoPoint (FieldName geoPointField) geoPointLatLon) =
1378 object [ geoPointField .= toJSON geoPointLatLon ]
1381instance ToJSON Query where
1382 toJSON (TermQuery (Term termQueryField termQueryValue) boost) =
1383 object [ "term" .=
1384 object [termQueryField .= object merged]]
1385 where
1386 base = [ "value" .= termQueryValue ]
1387 boosted = maybe [] (return . ("boost" .=)) boost
1388 merged = mappend base boosted
1390 toJSON (TermsQuery terms) =
1391 object [ "terms" .= object conjoined ]
1392 where conjoined = [ getTermsField terms .=
1393 fmap (toJSON . getTermValue) (toList terms)]
1394 getTermsField ((Term f _ ) :| _) = f
1395 getTermValue (Term _ v) = v
1396 toJSON (IdsQuery idsQueryMappingName docIds) =
1397 object [ "ids" .= object conjoined ]
1398 where conjoined = [ "type" .= toJSON idsQueryMappingName
1399 , "values" .= fmap toJSON docIds ]
1401 toJSON (QueryQueryStringQuery qQueryStringQuery) =
1402 object [ "query_string" .= toJSON qQueryStringQuery ]
1404 toJSON (QueryMatchQuery matchQuery) =
1405 object [ "match" .= toJSON matchQuery ]
1407 toJSON (QueryMultiMatchQuery multiMatchQuery) =
1408 toJSON multiMatchQuery
1410 toJSON (QueryBoolQuery boolQuery) =
1411 object [ "bool" .= toJSON boolQuery ]
1413 toJSON (QueryBoostingQuery boostingQuery) =
1414 object [ "boosting" .= toJSON boostingQuery ]
1416 toJSON (QueryCommonTermsQuery commonTermsQuery) =
1417 object [ "common" .= toJSON commonTermsQuery ]
1419 toJSON (ConstantScoreFilter csFilter boost) =
1420 object [ "constant_score" .= toJSON csFilter
1421 , "boost" .= toJSON boost]
1423 toJSON (ConstantScoreQuery query boost) =
1424 object [ "constant_score" .= toJSON query
1425 , "boost" .= toJSON boost]
1427 toJSON (QueryDisMaxQuery disMaxQuery) =
1428 object [ "dis_max" .= toJSON disMaxQuery ]
1430 toJSON (QueryFilteredQuery qFilteredQuery) =
1431 object [ "filtered" .= toJSON qFilteredQuery ]
1433 toJSON (QueryFuzzyLikeThisQuery fuzzyQuery) =
1434 object [ "fuzzy_like_this" .= toJSON fuzzyQuery ]
1436 toJSON (QueryFuzzyLikeFieldQuery fuzzyFieldQuery) =
1437 object [ "fuzzy_like_this_field" .= toJSON fuzzyFieldQuery ]
1439 toJSON (QueryFuzzyQuery fuzzyQuery) =
1440 object [ "fuzzy" .= toJSON fuzzyQuery ]
1442 toJSON (QueryHasChildQuery childQuery) =
1443 object [ "has_child" .= toJSON childQuery ]
1445 toJSON (QueryHasParentQuery parentQuery) =
1446 object [ "has_parent" .= toJSON parentQuery ]
1448 toJSON (QueryIndicesQuery qIndicesQuery) =
1449 object [ "indices" .= toJSON qIndicesQuery ]
1451 toJSON (MatchAllQuery boost) =
1452 object [ "match_all" .= omitNulls [ "boost" .= boost ] ]
1454 toJSON (QueryMoreLikeThisQuery query) =
1455 object [ "more_like_this" .= toJSON query ]
1457 toJSON (QueryMoreLikeThisFieldQuery query) =
1458 object [ "more_like_this_field" .= toJSON query ]
1460 toJSON (QueryNestedQuery query) =
1461 object [ "nested" .= toJSON query ]
1463 toJSON (QueryPrefixQuery query) =
1464 object [ "prefix" .= toJSON query ]
1466 toJSON (QueryRangeQuery query) =
1467 object [ "range" .= toJSON query ]
1469 toJSON (QueryRegexpQuery query) =
1470 object [ "regexp" .= toJSON query ]
1472 toJSON (QuerySimpleQueryStringQuery query) =
1473 object [ "simple_query_string" .= toJSON query ]
1476omitNulls :: [(Text, Value)] -> Value
1477omitNulls = object . filter notNull where
1478 notNull (_, Null) = False
1479 notNull (_, Array a) = (not . V.null) a
1480 notNull _ = True
1483instance ToJSON SimpleQueryStringQuery where
1484 toJSON SimpleQueryStringQuery {..} =
1485 omitNulls (base ++ maybeAdd)
1486 where base = [ "query" .= toJSON simpleQueryStringQuery ]
1487 maybeAdd = [ "fields" .= simpleQueryStringField
1488 , "default_operator" .= simpleQueryStringOperator
1489 , "analyzer" .= simpleQueryStringAnalyzer
1490 , "flags" .= simpleQueryStringFlags
1491 , "lowercase_expanded_terms" .= simpleQueryStringLowercaseExpanded
1492 , "locale" .= simpleQueryStringLocale ]
1495instance ToJSON FieldOrFields where
1496 toJSON (FofField fieldName) =
1497 toJSON fieldName
1498 toJSON (FofFields fieldNames) =
1499 toJSON fieldNames
1501instance ToJSON SimpleQueryFlag where
1502 toJSON SimpleQueryAll = "ALL"
1503 toJSON SimpleQueryNone = "NONE"
1504 toJSON SimpleQueryAnd = "AND"
1505 toJSON SimpleQueryOr = "OR"
1506 toJSON SimpleQueryPrefix = "PREFIX"
1507 toJSON SimpleQueryPhrase = "PHRASE"
1508 toJSON SimpleQueryPrecedence = "PRECEDENCE"
1509 toJSON SimpleQueryEscape = "ESCAPE"
1510 toJSON SimpleQueryWhitespace = "WHITESPACE"
1511 toJSON SimpleQueryFuzzy = "FUZZY"
1512 toJSON SimpleQueryNear = "NEAR"
1513 toJSON SimpleQuerySlop = "SLOP"
1516instance ToJSON RegexpQuery where
1517 toJSON (RegexpQuery (FieldName rqQueryField)
1518 (Regexp regexpQueryQuery) rqQueryFlags
1519 rqQueryBoost) =
1520 object [ rqQueryField .= omitNulls base ]
1521 where base = [ "value" .= regexpQueryQuery
1522 , "flags" .= toJSON rqQueryFlags
1523 , "boost" .= rqQueryBoost ]
1526instance ToJSON QueryStringQuery where
1527 toJSON (QueryStringQuery qsQueryString
1528 qsDefaultField qsOperator
1529 qsAnalyzer qsAllowWildcard
1530 qsLowercaseExpanded qsEnablePositionIncrements
1531 qsFuzzyMaxExpansions qsFuzziness
1532 qsFuzzyPrefixLength qsPhraseSlop
1533 qsBoost qsAnalyzeWildcard
1534 qsGeneratePhraseQueries qsMinimumShouldMatch
1535 qsLenient qsLocale) =
1536 omitNulls base
1537 where
1538 base = [ "query" .= toJSON qsQueryString
1539 , "default_field" .= qsDefaultField
1540 , "default_operator" .= qsOperator
1541 , "analyzer" .= qsAnalyzer
1542 , "allow_leading_wildcard" .= qsAllowWildcard
1543 , "lowercase_expanded_terms" .= qsLowercaseExpanded
1544 , "enable_position_increments" .= qsEnablePositionIncrements
1545 , "fuzzy_max_expansions" .= qsFuzzyMaxExpansions
1546 , "fuzziness" .= qsFuzziness
1547 , "fuzzy_prefix_length" .= qsFuzzyPrefixLength
1548 , "phrase_slop" .= qsPhraseSlop
1549 , "boost" .= qsBoost
1550 , "analyze_wildcard" .= qsAnalyzeWildcard
1551 , "auto_generate_phrase_queries" .= qsGeneratePhraseQueries
1552 , "minimum_should_match" .= qsMinimumShouldMatch
1553 , "lenient" .= qsLenient
1554 , "locale" .= qsLocale ]
1557instance ToJSON RangeQuery where
1558 toJSON (RangeQuery (FieldName fieldName) range boost) =
1559 object [ fieldName .= conjoined ]
1560 where conjoined = [ "boost" .= toJSON boost ] ++ (rangeValueToPair range)
1563instance ToJSON PrefixQuery where
1564 toJSON (PrefixQuery (FieldName fieldName) queryValue boost) =
1565 object [ fieldName .= omitNulls base ]
1566 where base = [ "value" .= toJSON queryValue
1567 , "boost" .= boost ]
1570instance ToJSON NestedQuery where
1571 toJSON (NestedQuery nqPath nqScoreType nqQuery) =
1572 object [ "path" .= toJSON nqPath
1573 , "score_mode" .= toJSON nqScoreType
1574 , "query" .= toJSON nqQuery ]
1577instance ToJSON MoreLikeThisFieldQuery where
1578 toJSON (MoreLikeThisFieldQuery text (FieldName fieldName)
1579 percent mtf mqt stopwords mindf maxdf
1580 minwl maxwl boostTerms boost analyzer) =
1581 object [ fieldName .= omitNulls base ]
1582 where base = [ "like_text" .= toJSON text
1583 , "percent_terms_to_match" .= percent
1584 , "min_term_freq" .= mtf
1585 , "max_query_terms" .= mqt
1586 , "stop_words" .= stopwords
1587 , "min_doc_freq" .= mindf
1588 , "max_doc_freq" .= maxdf
1589 , "min_word_length" .= minwl
1590 , "max_word_length" .= maxwl
1591 , "boost_terms" .= boostTerms
1592 , "boost" .= boost
1593 , "analyzer" .= analyzer ]
1596instance ToJSON MoreLikeThisQuery where
1597 toJSON (MoreLikeThisQuery text fields percent
1598 mtf mqt stopwords mindf maxdf
1599 minwl maxwl boostTerms boost analyzer) =
1600 omitNulls base
1601 where base = [ "like_text" .= toJSON text
1602 , "fields" .= fields
1603 , "percent_terms_to_match" .= percent
1604 , "min_term_freq" .= mtf
1605 , "max_query_terms" .= mqt
1606 , "stop_words" .= stopwords
1607 , "min_doc_freq" .= mindf
1608 , "max_doc_freq" .= maxdf
1609 , "min_word_length" .= minwl
1610 , "max_word_length" .= maxwl
1611 , "boost_terms" .= boostTerms
1612 , "boost" .= boost
1613 , "analyzer" .= analyzer ]
1616instance ToJSON IndicesQuery where
1617 toJSON (IndicesQuery indices query noMatch) =
1618 omitNulls [ "indices" .= toJSON indices
1619 , "no_match_query" .= toJSON noMatch
1620 , "query" .= toJSON query ]
1623instance ToJSON HasParentQuery where
1624 toJSON (HasParentQuery queryType query scoreType) =
1625 omitNulls [ "parent_type" .= toJSON queryType
1626 , "score_type" .= toJSON scoreType
1627 , "query" .= toJSON query ]
1630instance ToJSON HasChildQuery where
1631 toJSON (HasChildQuery queryType query scoreType) =
1632 omitNulls [ "query" .= toJSON query
1633 , "score_type" .= toJSON scoreType
1634 , "type" .= toJSON queryType ]
1637instance ToJSON FuzzyQuery where
1638 toJSON (FuzzyQuery (FieldName fieldName) queryText
1639 prefixLength maxEx fuzziness boost) =
1640 object [ fieldName .= omitNulls base ]
1641 where base = [ "value" .= toJSON queryText
1642 , "fuzziness" .= toJSON fuzziness
1643 , "prefix_length" .= toJSON prefixLength
1644 , "boost" .= toJSON boost
1645 , "max_expansions" .= toJSON maxEx ]
1648instance ToJSON FuzzyLikeFieldQuery where
1649 toJSON (FuzzyLikeFieldQuery (FieldName fieldName)
1650 fieldText maxTerms ignoreFreq fuzziness prefixLength
1651 boost analyzer) =
1652 object [ fieldName .=
1653 omitNulls [ "like_text" .= toJSON fieldText
1654 , "max_query_terms" .= toJSON maxTerms
1655 , "ignore_tf" .= toJSON ignoreFreq
1656 , "fuzziness" .= toJSON fuzziness
1657 , "prefix_length" .= toJSON prefixLength
1658 , "analyzer" .= toJSON analyzer
1659 , "boost" .= toJSON boost ]]
1662instance ToJSON FuzzyLikeThisQuery where
1663 toJSON (FuzzyLikeThisQuery fields text maxTerms
1664 ignoreFreq fuzziness prefixLength boost analyzer) =
1665 omitNulls base
1666 where base = [ "fields" .= toJSON fields
1667 , "like_text" .= toJSON text
1668 , "max_query_terms" .= toJSON maxTerms
1669 , "ignore_tf" .= toJSON ignoreFreq
1670 , "fuzziness" .= toJSON fuzziness
1671 , "prefix_length" .= toJSON prefixLength
1672 , "analyzer" .= toJSON analyzer
1673 , "boost" .= toJSON boost ]
1676instance ToJSON FilteredQuery where
1677 toJSON (FilteredQuery query fFilter) =
1678 object [ "query" .= toJSON query
1679 , "filter" .= toJSON fFilter ]
1682instance ToJSON DisMaxQuery where
1683 toJSON (DisMaxQuery queries tiebreaker boost) =
1684 omitNulls base
1685 where base = [ "queries" .= toJSON queries
1686 , "boost" .= toJSON boost
1687 , "tie_breaker" .= toJSON tiebreaker ]
1690instance ToJSON CommonTermsQuery where
1691 toJSON (CommonTermsQuery (FieldName fieldName)
1692 (QueryString query) cf lfo hfo msm
1693 boost analyzer disableCoord) =
1694 object [fieldName .= omitNulls base ]
1695 where base = [ "query" .= toJSON query
1696 , "cutoff_frequency" .= toJSON cf
1697 , "low_freq_operator" .= toJSON lfo
1698 , "minimum_should_match" .= toJSON msm
1699 , "boost" .= toJSON boost
1700 , "analyzer" .= toJSON analyzer
1701 , "disable_coord" .= toJSON disableCoord
1702 , "high_freq_operator" .= toJSON hfo ]
1705instance ToJSON CommonMinimumMatch where
1706 toJSON (CommonMinimumMatch mm) = toJSON mm
1707 toJSON (CommonMinimumMatchHighLow (MinimumMatchHighLow lowF highF)) =
1708 object [ "low_freq" .= toJSON lowF
1709 , "high_freq" .= toJSON highF ]
1711instance ToJSON BoostingQuery where
1712 toJSON (BoostingQuery bqPositiveQuery bqNegativeQuery bqNegativeBoost) =
1713 object [ "positive" .= toJSON bqPositiveQuery
1714 , "negative" .= toJSON bqNegativeQuery
1715 , "negative_boost" .= toJSON bqNegativeBoost ]
1718instance ToJSON BoolQuery where
1719 toJSON (BoolQuery mustM notM shouldM bqMin boost disableCoord) =
1720 omitNulls base
1721 where base = [ "must" .= toJSON mustM
1722 , "must_not" .= toJSON notM
1723 , "should" .= toJSON shouldM
1724 , "minimum_should_match" .= toJSON bqMin
1725 , "boost" .= toJSON boost
1726 , "disable_coord" .= toJSON disableCoord ]
1729instance ToJSON MatchQuery where
1730 toJSON (MatchQuery (FieldName fieldName)
1731 (QueryString mqQueryString) booleanOperator
1732 zeroTermsQuery cutoffFrequency matchQueryType
1733 analyzer maxExpansions lenient) =
1734 object [ fieldName .= omitNulls base ]
1735 where base = [ "query" .= mqQueryString
1736 , "operator" .= toJSON booleanOperator
1737 , "zero_terms_query" .= toJSON zeroTermsQuery
1738 , "cutoff_frequency" .= toJSON cutoffFrequency
1739 , "type" .= toJSON matchQueryType
1740 , "analyzer" .= toJSON analyzer
1741 , "max_expansions" .= toJSON maxExpansions
1742 , "lenient" .= toJSON lenient ]
1745instance ToJSON MultiMatchQuery where
1746 toJSON (MultiMatchQuery fields (QueryString query) boolOp
1747 ztQ tb mmqt cf analyzer maxEx lenient) =
1748 object ["multi_match" .= omitNulls base]
1749 where base = [ "fields" .= fmap toJSON fields
1750 , "query" .= query
1751 , "operator" .= toJSON boolOp
1752 , "zero_terms_query" .= toJSON ztQ
1753 , "tiebreaker" .= toJSON tb
1754 , "type" .= toJSON mmqt
1755 , "cutoff_frequency" .= toJSON cf
1756 , "analyzer" .= toJSON analyzer
1757 , "max_expansions" .= toJSON maxEx
1758 , "lenient" .= toJSON lenient ]
1761instance ToJSON MultiMatchQueryType where
1762 toJSON MultiMatchBestFields = "best_fields"
1763 toJSON MultiMatchMostFields = "most_fields"
1764 toJSON MultiMatchCrossFields = "cross_fields"
1765 toJSON MultiMatchPhrase = "phrase"
1766 toJSON MultiMatchPhrasePrefix = "phrase_prefix"
1768instance ToJSON BooleanOperator where
1769 toJSON And = String "and"
1770 toJSON Or = String "or"
1772instance ToJSON ZeroTermsQuery where
1773 toJSON ZeroTermsNone = String "none"
1774 toJSON ZeroTermsAll = String "all"
1776instance ToJSON MatchQueryType where
1777 toJSON MatchPhrase = "phrase"
1778 toJSON MatchPhrasePrefix = "phrase_prefix"
1780instance ToJSON FieldName where
1781 toJSON (FieldName fieldName) = String fieldName
1783instance ToJSON ReplicaCount
1784instance ToJSON ShardCount
1785instance ToJSON CutoffFrequency
1786instance ToJSON Analyzer
1787instance ToJSON MaxExpansions
1788instance ToJSON Lenient
1789instance ToJSON Boost
1790instance ToJSON Version
1791instance ToJSON Tiebreaker
1792instance ToJSON MinimumMatch
1793instance ToJSON DisableCoord
1794instance ToJSON PrefixLength
1795instance ToJSON Fuzziness
1796instance ToJSON IgnoreTermFrequency
1797instance ToJSON MaxQueryTerms
1798instance ToJSON TypeName
1799instance ToJSON IndexName
1800instance ToJSON BoostTerms
1801instance ToJSON MaxWordLength
1802instance ToJSON MinWordLength
1803instance ToJSON MaxDocFrequency
1804instance ToJSON MinDocFrequency
1805instance ToJSON PhraseSlop
1806instance ToJSON StopWord
1807instance ToJSON QueryPath
1808instance ToJSON MinimumTermFrequency
1809instance ToJSON PercentMatch
1810instance ToJSON MappingName
1811instance ToJSON DocId
1812instance ToJSON QueryString
1813instance ToJSON AllowLeadingWildcard
1814instance ToJSON LowercaseExpanded
1815instance ToJSON AnalyzeWildcard
1816instance ToJSON GeneratePhraseQueries
1817instance ToJSON Locale
1818instance ToJSON EnablePositionIncrements
1819instance FromJSON Version
1820instance FromJSON IndexName
1821instance FromJSON MappingName
1822instance FromJSON DocId
1825instance FromJSON Status where
1826 parseJSON (Object v) = Status <$>
1827 v .:? "ok" <*>
1828 v .: "status" <*>
1829 v .: "name" <*>
1830 v .: "version" <*>
1831 v .: "tagline"
1832 parseJSON _ = empty
1835instance ToJSON IndexSettings where
1836 toJSON (IndexSettings s r) = object ["settings" .= object ["shards" .= s, "replicas" .= r]]
1839instance (FromJSON a) => FromJSON (EsResult a) where
1840 parseJSON (Object v) = EsResult <$>
1841 v .: "_index" <*>
1842 v .: "_type" <*>
1843 v .: "_id" <*>
1844 v .: "_version" <*>
1845 v .:? "found" <*>
1846 v .: "_source"
1847 parseJSON _ = empty
1850instance ToJSON Search where
1851 toJSON (Search query sFilter sort searchAggs highlight sTrackSortScores sFrom sSize) =
1852 omitNulls [ "query" .= query
1853 , "filter" .= sFilter
1854 , "sort" .= sort
1855 , "aggregations" .= searchAggs
1856 , "highlight" .= highlight
1857 , "from" .= sFrom
1858 , "size" .= sSize
1859 , "track_scores" .= sTrackSortScores]
1862instance ToJSON FieldHighlight where
1863 toJSON (FieldHighlight (FieldName fName) (Just fSettings)) =
1864 object [ fName .= fSettings ]
1865 toJSON (FieldHighlight (FieldName fName) Nothing) =
1866 object [ fName .= emptyObject ]
1868instance ToJSON Highlights where
1869 toJSON (Highlights global fields) =
1870 omitNulls (("fields" .= toJSON fields)
1871 : highlightSettingsPairs global)
1873instance ToJSON HighlightSettings where
1874 toJSON hs = omitNulls (highlightSettingsPairs (Just hs))
1876highlightSettingsPairs :: Maybe HighlightSettings -> [Pair]
1877highlightSettingsPairs Nothing = []
1878highlightSettingsPairs (Just (Plain plh)) = plainHighPairs (Just plh)
1879highlightSettingsPairs (Just (Postings ph)) = postHighPairs (Just ph)
1880highlightSettingsPairs (Just (FastVector fvh)) = fastVectorHighPairs (Just fvh)
1883plainHighPairs :: Maybe PlainHighlight -> [Pair]
1884plainHighPairs Nothing = []
1885plainHighPairs (Just (PlainHighlight plCom plNonPost)) =
1886 [ "type" .= String "plain"]
1887 ++ commonHighlightPairs plCom
1888 ++ nonPostingsToPairs plNonPost
1890postHighPairs :: Maybe PostingsHighlight -> [Pair]
1891postHighPairs Nothing = []
1892postHighPairs (Just (PostingsHighlight pCom)) =
1893 ("type" .= String "postings")
1894 : commonHighlightPairs pCom
1896fastVectorHighPairs :: Maybe FastVectorHighlight -> [Pair]
1897fastVectorHighPairs Nothing = []
1898fastVectorHighPairs (Just
1899 (FastVectorHighlight fvCom fvNonPostSettings fvBoundChars
1900 fvBoundMaxScan fvFragOff fvMatchedFields
1901 fvPhraseLim)) =
1902 [ "type" .= String "fvh"
1903 , "boundary_chars" .= fvBoundChars
1904 , "boundary_max_scan" .= fvBoundMaxScan
1905 , "fragment_offset" .= fvFragOff
1906 , "matched_fields" .= fvMatchedFields
1907 , "phraseLimit" .= fvPhraseLim]
1908 ++ commonHighlightPairs fvCom
1909 ++ nonPostingsToPairs fvNonPostSettings
1911commonHighlightPairs :: Maybe CommonHighlight -> [Pair]
1912commonHighlightPairs Nothing = []
1913commonHighlightPairs (Just (CommonHighlight chScore chForceSource chTag chEncoder
1914 chNoMatchSize chHighlightQuery
1915 chRequireFieldMatch)) =
1916 [ "order" .= chScore
1917 , "force_source" .= chForceSource
1918 , "encoder" .= chEncoder
1919 , "no_match_size" .= chNoMatchSize
1920 , "highlight_query" .= chHighlightQuery
1921 , "require_fieldMatch" .= chRequireFieldMatch]
1922 ++ highlightTagToPairs chTag
1925nonPostingsToPairs :: Maybe NonPostings -> [Pair]
1926nonPostingsToPairs Nothing = []
1927nonPostingsToPairs (Just (NonPostings npFragSize npNumOfFrags)) =
1928 [ "fragment_size" .= npFragSize
1929 , "number_of_fragments" .= npNumOfFrags]
1933instance ToJSON HighlightEncoder where
1934 toJSON DefaultEncoder = String "default"
1935 toJSON HTMLEncoder = String "html"
1937highlightTagToPairs :: Maybe HighlightTag -> [Pair]
1938highlightTagToPairs (Just (TagSchema _)) = [ "scheme" .= String "default"]
1939highlightTagToPairs (Just (CustomTags (pre, post))) = [ "pre_tags" .= pre
1940 , "post_tags" .= post]
1941highlightTagToPairs Nothing = []
1943instance ToJSON SortSpec where
1944 toJSON (DefaultSortSpec
1945 (DefaultSort (FieldName dsSortFieldName) dsSortOrder dsIgnoreUnmapped
1946 dsSortMode dsMissingSort dsNestedFilter)) =
1947 object [dsSortFieldName .= omitNulls base] where
1948 base = [ "order" .= toJSON dsSortOrder
1949 , "ignore_unmapped" .= dsIgnoreUnmapped
1950 , "mode" .= dsSortMode
1951 , "missing" .= dsMissingSort
1952 , "nested_filter" .= dsNestedFilter ]
1954 toJSON (GeoDistanceSortSpec gdsSortOrder (GeoPoint (FieldName field) gdsLatLon) units) =
1955 object [ "unit" .= toJSON units
1956 , field .= toJSON gdsLatLon
1957 , "order" .= toJSON gdsSortOrder ]
1960instance ToJSON SortOrder where
1961 toJSON Ascending = String "asc"
1962 toJSON Descending = String "desc"
1965instance ToJSON SortMode where
1966 toJSON SortMin = String "min"
1967 toJSON SortMax = String "max"
1968 toJSON SortSum = String "sum"
1969 toJSON SortAvg = String "avg"
1972instance ToJSON Missing where
1973 toJSON LastMissing = String "_last"
1974 toJSON FirstMissing = String "_first"
1975 toJSON (CustomMissing txt) = String txt
1978instance ToJSON ScoreType where
1979 toJSON ScoreTypeMax = "max"
1980 toJSON ScoreTypeAvg = "avg"
1981 toJSON ScoreTypeSum = "sum"
1982 toJSON ScoreTypeNone = "none"
1985instance ToJSON Distance where
1986 toJSON (Distance dCoefficient dUnit) =
1987 String boltedTogether where
1988 coefText = showText dCoefficient
1989 (String unitText) = toJSON dUnit
1990 boltedTogether = mappend coefText unitText
1993instance ToJSON DistanceUnit where
1994 toJSON Miles = String "mi"
1995 toJSON Yards = String "yd"
1996 toJSON Feet = String "ft"
1997 toJSON Inches = String "in"
1998 toJSON Kilometers = String "km"
1999 toJSON Meters = String "m"
2000 toJSON Centimeters = String "cm"
2001 toJSON Millimeters = String "mm"
2002 toJSON NauticalMiles = String "nmi"
2005instance ToJSON DistanceType where
2006 toJSON Arc = String "arc"
2007 toJSON SloppyArc = String "sloppy_arc"
2008 toJSON Plane = String "plane"
2011instance ToJSON OptimizeBbox where
2012 toJSON NoOptimizeBbox = String "none"
2013 toJSON (OptimizeGeoFilterType gft) = toJSON gft
2016instance ToJSON GeoBoundingBoxConstraint where
2017 toJSON (GeoBoundingBoxConstraint
2018 (FieldName gbbcGeoBBField) gbbcConstraintBox cache type') =
2019 object [gbbcGeoBBField .= toJSON gbbcConstraintBox
2020 , "_cache" .= cache
2021 , "type" .= type']
2024instance ToJSON GeoFilterType where
2025 toJSON GeoFilterMemory = String "memory"
2026 toJSON GeoFilterIndexed = String "indexed"
2029instance ToJSON GeoBoundingBox where
2030 toJSON (GeoBoundingBox gbbTopLeft gbbBottomRight) =
2031 object ["top_left" .= toJSON gbbTopLeft
2032 , "bottom_right" .= toJSON gbbBottomRight]
2035instance ToJSON LatLon where
2036 toJSON (LatLon lLat lLon) =
2037 object ["lat" .= lLat
2038 , "lon" .= lLon]
2041-- index for smaller ranges, fielddata for longer ranges
2042instance ToJSON RangeExecution where
2043 toJSON RangeExecutionIndex = "index"
2044 toJSON RangeExecutionFielddata = "fielddata"
2047instance ToJSON RegexpFlags where
2048 toJSON AllRegexpFlags = String "ALL"
2049 toJSON NoRegexpFlags = String "NONE"
2050 toJSON (SomeRegexpFlags (h :| fs)) = String $ T.intercalate "|" flagStrs
2051 where flagStrs = map flagStr . nub $ h:fs
2052 flagStr AnyString = "ANYSTRING"
2053 flagStr Automaton = "AUTOMATON"
2054 flagStr Complement = "COMPLEMENT"
2055 flagStr Empty = "EMPTY"
2056 flagStr Intersection = "INTERSECTION"
2057 flagStr Interval = "INTERVAL"
2059instance ToJSON Term where
2060 toJSON (Term field value) = object ["term" .= object
2061 [field .= value]]
2064instance ToJSON BoolMatch where
2065 toJSON (MustMatch term cache) = object ["must" .= toJSON term,
2066 "_cache" .= cache]
2067 toJSON (MustNotMatch term cache) = object ["must_not" .= toJSON term,
2068 "_cache" .= cache]
2069 toJSON (ShouldMatch terms cache) = object ["should" .= fmap toJSON terms,
2070 "_cache" .= cache]
2073instance (FromJSON a) => FromJSON (SearchResult a) where
2074 parseJSON (Object v) = SearchResult <$>
2075 v .: "took" <*>
2076 v .: "timed_out" <*>
2077 v .: "_shards" <*>
2078 v .: "hits" <*>
2079 v .:? "aggregations"
2080 parseJSON _ = empty
2082instance (FromJSON a) => FromJSON (SearchHits a) where
2083 parseJSON (Object v) = SearchHits <$>
2084 v .: "total" <*>
2085 v .: "max_score" <*>
2086 v .: "hits"
2087 parseJSON _ = empty
2089instance (FromJSON a) => FromJSON (Hit a) where
2090 parseJSON (Object v) = Hit <$>
2091 v .: "_index" <*>
2092 v .: "_type" <*>
2093 v .: "_id" <*>
2094 v .: "_score" <*>
2095 v .: "_source" <*>
2096 v .:? "highlight"
2097 parseJSON _ = empty
2099instance FromJSON ShardResult where
2100 parseJSON (Object v) = ShardResult <$>
2101 v .: "total" <*>
2102 v .: "successful" <*>
2103 v .: "failed"
2104 parseJSON _ = empty