git.iko.soy/typeable/bloodhound
on 5558959 help sign in
931 lines 35 kB history raw
1{-# LANGUAGE DeriveGeneric #-}
3{-| Data types for describing actions and data structures performed to interact
4 with Elasticsearch. The two main buckets your queries against Elasticsearch
5 will fall into are 'Query's and 'Filter's. 'Filter's are more like
6 traditional database constraints and often have preferable performance
7 properties. 'Query's support human-written textual queries, such as fuzzy
8 queries.
9-}
11module Database.Bloodhound.Types
12 ( defaultCache
13 , defaultIndexSettings
14 , halfRangeToKV
15 , maybeJson
16 , maybeJsonF
17 , mkSort
18 , rangeToKV
19 , showText
20 , unpackId
21 , mkMatchQuery
22 , mkMultiMatchQuery
23 , mkBoolQuery
24 , mkRangeQuery
25 , mkQueryStringQuery
26 , Version(..)
27 , Status(..)
28 , Existence(..)
29 , NullValue(..)
30 , IndexSettings(..)
31 , Server(..)
32 , Reply
33 , EsResult(..)
34 , Query(..)
35 , Search(..)
36 , SearchResult(..)
37 , SearchHits(..)
38 , ShardResult(..)
39 , Hit(..)
40 , Filter(..)
41 , Seminearring(..)
42 , BoolMatch(..)
43 , Term(..)
44 , GeoPoint(..)
45 , GeoBoundingBoxConstraint(..)
46 , GeoBoundingBox(..)
47 , GeoFilterType(..)
48 , Distance(..)
49 , DistanceUnit(..)
50 , DistanceType(..)
51 , DistanceRange(..)
52 , OptimizeBbox(..)
53 , LatLon(..)
54 , Range(..)
55 , HalfRange(..)
56 , RangeExecution(..)
57 , LessThan(..)
58 , LessThanEq(..)
59 , GreaterThan(..)
60 , GreaterThanEq(..)
61 , Regexp(..)
62 , RegexpFlags(..)
63 , FieldName(..)
64 , IndexName(..)
65 , MappingName(..)
66 , DocId(..)
67 , CacheName(..)
68 , CacheKey(..)
69 , BulkOperation(..)
70 , ReplicaCount(..)
71 , ShardCount(..)
72 , Sort
73 , SortMode(..)
74 , SortOrder(..)
75 , SortSpec(..)
76 , DefaultSort(..)
77 , Missing(..)
78 , OpenCloseIndex(..)
79 , Method
80 , Boost(..)
81 , MatchQuery(..)
82 , MultiMatchQuery(..)
83 , BoolQuery(..)
84 , BoostingQuery(..)
85 , CommonTermsQuery(..)
86 , DisMaxQuery(..)
87 , FilteredQuery(..)
88 , FuzzyLikeThisQuery(..)
89 , FuzzyLikeFieldQuery(..)
90 , FuzzyQuery(..)
91 , HasChildQuery(..)
92 , HasParentQuery(..)
93 , IndicesQuery(..)
94 , MoreLikeThisQuery(..)
95 , MoreLikeThisFieldQuery(..)
96 , NestedQuery(..)
97 , PrefixQuery(..)
98 , QueryStringQuery(..)
99 , SimpleQueryStringQuery(..)
100 , RangeQuery(..)
101 , RegexpQuery(..)
102 , QueryString(..)
103 , BooleanOperator(..)
104 , ZeroTermsQuery(..)
105 , CutoffFrequency(..)
106 , Analyzer(..)
107 , MaxExpansions(..)
108 , Lenient(..)
109 , MatchQueryType(..)
110 , MultiMatchQueryType(..)
111 , Tiebreaker(..)
112 , MinimumMatch(..)
113 , DisableCoord(..)
114 , CommonMinimumMatch(..)
115 , MinimumMatchHighLow(..)
116 , PrefixLength(..)
117 , Fuzziness(..)
118 , IgnoreTermFrequency(..)
119 , MaxQueryTerms(..)
120 , ScoreType(..)
121 , TypeName(..)
122 , BoostTerms(..)
123 , MaxWordLength(..)
124 , MinWordLength(..)
125 , MaxDocFrequency(..)
126 , MinDocFrequency(..)
127 , PhraseSlop(..)
128 , StopWord(..)
129 , QueryPath(..)
130 , MinimumTermFrequency(..)
131 , PercentMatch(..)
132 , FieldDefinition(..)
133 , MappingField(..)
134 , Mapping(..)
135 , AllowLeadingWildcard(..)
136 , LowercaseExpanded(..)
137 , GeneratePhraseQueries(..)
138 , Locale(..)
139 , AnalyzeWildcard(..)
140 , EnablePositionIncrements(..)
141 , SimpleQueryFlag(..)
142 , FieldOrFields(..)
143 ) where
145import Data.Aeson
146import qualified Data.ByteString.Lazy.Char8 as L
147import Data.Text (Text)
148import qualified Data.Text as T
149import Data.Time.Clock (UTCTime)
150import Database.Bloodhound.Types.Class
151import GHC.Generics (Generic)
152import Network.HTTP.Client
153import qualified Network.HTTP.Types.Method as NHTM
156{-| 'Version' is embedded in 'Status' -}
157data Version = Version { number :: Text
158 , build_hash :: Text
159 , build_timestamp :: UTCTime
160 , build_snapshot :: Bool
161 , lucene_version :: Text } deriving (Eq, Show, Generic)
163{-| 'Status' is a data type for describing the JSON body returned by
164 Elasticsearch when you query its status. This was deprecated in 1.2.0.
166 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-status.html#indices-status>
167-}
169data Status = Status { ok :: Bool
170 , status :: Int
171 , name :: Text
172 , version :: Version
173 , tagline :: Text } deriving (Eq, Show)
175{-| 'IndexSettings' is used to configure the shards and replicas when you create
176 an Elasticsearch Index.
178 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html>
179-}
181data IndexSettings =
182 IndexSettings { indexShards :: ShardCount
183 , indexReplicas :: ReplicaCount } deriving (Eq, Show)
185{-| 'defaultIndexSettings' is an 'IndexSettings' with 3 shards and 2 replicas. -}
186defaultIndexSettings :: IndexSettings
187defaultIndexSettings = IndexSettings (ShardCount 3) (ReplicaCount 2)
189{-| 'Reply' and 'Method' are type synonyms from 'Network.HTTP.Types.Method.Method' -}
190type Reply = Network.HTTP.Client.Response L.ByteString
191type Method = NHTM.Method
193{-| 'OpenCloseIndex' is a sum type for opening and closing indices.
195 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-open-close.html>
196-}
197data OpenCloseIndex = OpenIndex | CloseIndex deriving (Eq, Show)
199data FieldType = GeoPointType
200 | GeoShapeType
201 | FloatType
202 | IntegerType
203 | LongType
204 | ShortType
205 | ByteType deriving (Eq, Show)
207data FieldDefinition =
208 FieldDefinition { fieldType :: FieldType } deriving (Eq, Show)
210data MappingField =
211 MappingField { mappingFieldName :: FieldName
212 , fieldDefinition :: FieldDefinition } deriving (Eq, Show)
214{-| Support for type reification of 'Mapping's is currently incomplete, for
215 now the mapping API verbiage expects a 'ToJSON'able blob.
217 Indexes have mappings, mappings are schemas for the documents contained in the
218 index. I'd recommend having only one mapping per index, always having a mapping,
219 and keeping different kinds of documents separated if possible.
220-}
221data Mapping = Mapping { typeName :: TypeName
222 , mappingFields :: [MappingField] } deriving (Eq, Show)
224{-| 'BulkOperation' is a sum type for expressing the four kinds of bulk
225 operation index, create, delete, and update. 'BulkIndex' behaves like an
226 "upsert", 'BulkCreate' will fail if a document already exists at the DocId.
228 <http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-bulk.html#docs-bulk>
229-}
230data BulkOperation =
231 BulkIndex IndexName MappingName DocId Value
232 | BulkCreate IndexName MappingName DocId Value
233 | BulkDelete IndexName MappingName DocId
234 | BulkUpdate IndexName MappingName DocId Value deriving (Eq, Show)
236{-| 'EsResult' describes the standard wrapper JSON document that you see in
237 successful Elasticsearch responses.
238-}
239data EsResult a = EsResult { _index :: Text
240 , _type :: Text
241 , _id :: Text
242 , _version :: Int
243 , found :: Maybe Bool
244 , _source :: a } deriving (Eq, Show)
246{-| 'Sort' is a synonym for a list of 'SortSpec's. Sort behavior is order
247 dependent with later sorts acting as tie-breakers for earlier sorts.
248-}
249type Sort = [SortSpec]
251{-| The two main kinds of 'SortSpec' are 'DefaultSortSpec' and
252 'GeoDistanceSortSpec'. The latter takes a 'SortOrder', 'GeoPoint', and
253 'DistanceUnit' to express "nearness" to a single geographical point as a
254 sort specification.
256<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
257-}
258data SortSpec = DefaultSortSpec DefaultSort
259 | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit deriving (Eq, Show)
261{-| 'DefaultSort' is usually the kind of 'SortSpec' you'll want. There's a
262 'mkSort' convenience function for when you want to specify only the most
263 common parameters.
265<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
266-}
267data DefaultSort =
268 DefaultSort { sortFieldName :: FieldName
269 , sortOrder :: SortOrder
270 -- default False
271 , ignoreUnmapped :: Bool
272 , sortMode :: Maybe SortMode
273 , missingSort :: Maybe Missing
274 , nestedFilter :: Maybe Filter } deriving (Eq, Show)
276{-| 'SortOrder' is 'Ascending' or 'Descending', as you might expect. These get
277 encoded into "asc" or "desc" when turned into JSON.
279<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
280-}
281data SortOrder = Ascending
282 | Descending deriving (Eq, Show)
284{-| 'Missing' prescribes how to handle missing fields. A missing field can be
285 sorted last, first, or using a custom value as a substitute.
287<http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_missing_values>
288-}
289data Missing = LastMissing
290 | FirstMissing
291 | CustomMissing Text deriving (Eq, Show)
293{-| 'SortMode' prescribes how to handle sorting array/multi-valued fields.
295http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-sort.html#_sort_mode_option
296-}
297data SortMode = SortMin
298 | SortMax
299 | SortSum
300 | SortAvg deriving (Eq, Show)
302{-| 'mkSort' defaults everything but the 'FieldName' and the 'SortOrder' so
303 that you can concisely describe the usual kind of 'SortSpec's you want.
304-}
305mkSort :: FieldName -> SortOrder -> DefaultSort
306mkSort fieldName sOrder = DefaultSort fieldName sOrder False Nothing Nothing Nothing
308{-| 'Cache' is for telling ES whether it should cache a 'Filter' not.
309 'Query's cannot be cached.
310-}
311type Cache = Bool -- caching on/off
312defaultCache :: Cache
313defaultCache = False
315{-| 'PrefixValue' is used in 'PrefixQuery' as the main query component.
316-}
317type PrefixValue = Text
319{-| 'BooleanOperator' is the usual And/Or operators with an ES compatible
320 JSON encoding baked in. Used all over the place.
321-}
322data BooleanOperator = And | Or deriving (Eq, Show)
324{-| 'ShardCount' is part of 'IndexSettings'
325-}
326newtype ShardCount = ShardCount Int deriving (Eq, Show, Generic)
328{-| 'ReplicaCount' is part of 'IndexSettings'
329-}
330newtype ReplicaCount = ReplicaCount Int deriving (Eq, Show, Generic)
332{-| 'Server' is used with the client functions to point at the ES instance
333-}
334newtype Server = Server String deriving (Eq, Show)
336{-| 'IndexName' is used to describe which index to query/create/delete
337-}
338newtype IndexName = IndexName String deriving (Eq, Generic, Show)
340{-| 'MappingName' is part of mappings which are how ES describes and schematizes
341 the data in the indices.
342-}
343newtype MappingName = MappingName String deriving (Eq, Generic, Show)
345{-| 'DocId' is a generic wrapper value for expressing unique Document IDs.
346 Can be set by the user or created by ES itself. Often used in client
347 functions for poking at specific documents.
348-}
349newtype DocId = DocId String deriving (Eq, Generic, Show)
351{-| 'QueryString' is used to wrap query text bodies, be they human written or not.
352-}
353newtype QueryString = QueryString Text deriving (Eq, Generic, Show)
355{-| 'FieldName' is used all over the place wherever a specific field within
356 a document needs to be specified, usually in 'Query's or 'Filter's.
357-}
358newtype FieldName = FieldName Text deriving (Eq, Show)
360{-| 'CacheName' is used in 'RegexpFilter' for describing the
361 'CacheKey' keyed caching behavior.
362-}
363newtype CacheName = CacheName Text deriving (Eq, Show)
365{-| 'CacheKey' is used in 'RegexpFilter' to key regex caching.
366-}
367newtype CacheKey =
368 CacheKey Text deriving (Eq, Show)
369newtype Existence =
370 Existence Bool deriving (Eq, Show)
371newtype NullValue =
372 NullValue Bool deriving (Eq, Show)
373newtype CutoffFrequency =
374 CutoffFrequency Double deriving (Eq, Show, Generic)
375newtype Analyzer =
376 Analyzer Text deriving (Eq, Show, Generic)
377newtype MaxExpansions =
378 MaxExpansions Int deriving (Eq, Show, Generic)
380{-| 'Lenient', if set to true, will cause format based failures to be
381 ignored. I don't know what the bloody default is, Elasticsearch
382 documentation didn't say what it was. Let me know if you figure it out.
383-}
384newtype Lenient =
385 Lenient Bool deriving (Eq, Show, Generic)
386newtype Tiebreaker =
387 Tiebreaker Double deriving (Eq, Show, Generic)
388newtype Boost =
389 Boost Double deriving (Eq, Show, Generic)
390newtype BoostTerms =
391 BoostTerms Double deriving (Eq, Show, Generic)
393{-| 'MinimumMatch' controls how many should clauses in the bool query should
394 match. Can be an absolute value (2) or a percentage (30%) or a
395 combination of both.
396-}
397newtype MinimumMatch =
398 MinimumMatch Int deriving (Eq, Show, Generic)
399newtype MinimumMatchText =
400 MinimumMatchText Text deriving (Eq, Show)
401newtype DisableCoord =
402 DisableCoord Bool deriving (Eq, Show, Generic)
403newtype IgnoreTermFrequency =
404 IgnoreTermFrequency Bool deriving (Eq, Show, Generic)
405newtype MinimumTermFrequency =
406 MinimumTermFrequency Int deriving (Eq, Show, Generic)
407newtype MaxQueryTerms =
408 MaxQueryTerms Int deriving (Eq, Show, Generic)
409newtype Fuzziness =
410 Fuzziness Double deriving (Eq, Show, Generic)
412{-| 'PrefixLength' is the prefix length used in queries, defaults to 0. -}
413newtype PrefixLength =
414 PrefixLength Int deriving (Eq, Show, Generic)
415newtype TypeName =
416 TypeName Text deriving (Eq, Show, Generic)
417newtype PercentMatch =
418 PercentMatch Double deriving (Eq, Show, Generic)
419newtype StopWord =
420 StopWord Text deriving (Eq, Show, Generic)
421newtype QueryPath =
422 QueryPath Text deriving (Eq, Show, Generic)
424{-| Allowing a wildcard at the beginning of a word (eg "*ing") is particularly
425 heavy, because all terms in the index need to be examined, just in case
426 they match. Leading wildcards can be disabled by setting
427 'AllowLeadingWildcard' to false. -}
428newtype AllowLeadingWildcard =
429 AllowLeadingWildcard Bool deriving (Eq, Show, Generic)
430newtype LowercaseExpanded =
431 LowercaseExpanded Bool deriving (Eq, Show, Generic)
432newtype EnablePositionIncrements =
433 EnablePositionIncrements Bool deriving (Eq, Show, Generic)
435{-| By default, wildcard terms in a query are not analyzed.
436 Setting 'AnalyzeWildcard' to true enables best-effort analysis.
437-}
438newtype AnalyzeWildcard = AnalyzeWildcard Bool deriving (Eq, Show, Generic)
440{-| 'GeneratePhraseQueries' defaults to false.
441-}
442newtype GeneratePhraseQueries =
443 GeneratePhraseQueries Bool deriving (Eq, Show, Generic)
445{-| 'Locale' is used for string conversions - defaults to ROOT.
446-}
447newtype Locale = Locale Text deriving (Eq, Show, Generic)
448newtype MaxWordLength = MaxWordLength Int deriving (Eq, Show, Generic)
449newtype MinWordLength = MinWordLength Int deriving (Eq, Show, Generic)
451{-| 'PhraseSlop' sets the default slop for phrases, 0 means exact
452 phrase matches. Default is 0.
453-}
454newtype PhraseSlop = PhraseSlop Int deriving (Eq, Show, Generic)
455newtype MinDocFrequency = MinDocFrequency Int deriving (Eq, Show, Generic)
456newtype MaxDocFrequency = MaxDocFrequency Int deriving (Eq, Show, Generic)
458{-| 'unpackId' is a silly convenience function that gets used once.
459-}
460unpackId :: DocId -> String
461unpackId (DocId docId) = docId
463type TrackSortScores = Bool
464type From = Int
465type Size = Int
467data Search = Search { queryBody :: Maybe Query
468 , filterBody :: Maybe Filter
469 , sortBody :: Maybe Sort
470 -- default False
471 , trackSortScores :: TrackSortScores
472 , from :: From
473 , size :: Size } deriving (Eq, Show)
475data Query =
476 TermQuery Term (Maybe Boost)
477 | TermsQuery [Term] MinimumMatch
478 | QueryMatchQuery MatchQuery
479 | QueryMultiMatchQuery MultiMatchQuery
480 | QueryBoolQuery BoolQuery
481 | QueryBoostingQuery BoostingQuery
482 | QueryCommonTermsQuery CommonTermsQuery
483 | ConstantScoreFilter Filter Boost
484 | ConstantScoreQuery Query Boost
485 | QueryDisMaxQuery DisMaxQuery
486 | QueryFilteredQuery FilteredQuery
487 | QueryFuzzyLikeThisQuery FuzzyLikeThisQuery
488 | QueryFuzzyLikeFieldQuery FuzzyLikeFieldQuery
489 | QueryFuzzyQuery FuzzyQuery
490 | QueryHasChildQuery HasChildQuery
491 | QueryHasParentQuery HasParentQuery
492 | IdsQuery MappingName [DocId]
493 | QueryIndicesQuery IndicesQuery
494 | MatchAllQuery (Maybe Boost)
495 | QueryMoreLikeThisQuery MoreLikeThisQuery
496 | QueryMoreLikeThisFieldQuery MoreLikeThisFieldQuery
497 | QueryNestedQuery NestedQuery
498 | QueryPrefixQuery PrefixQuery
499 | QueryQueryStringQuery QueryStringQuery
500 | QuerySimpleQueryStringQuery SimpleQueryStringQuery
501 | QueryRangeQuery RangeQuery
502 | QueryRegexpQuery RegexpQuery
503 deriving (Eq, Show)
505data RegexpQuery =
506 RegexpQuery { regexpQueryField :: FieldName
507 , regexpQuery :: Regexp
508 , regexpQueryFlags :: RegexpFlags
509 , regexpQueryBoost :: Maybe Boost
510 } deriving (Eq, Show)
512data RangeQuery =
513 RangeQuery { rangeQueryField :: FieldName
514 , rangeQueryRange :: Either HalfRange Range
515 , rangeQueryBoost :: Boost } deriving (Eq, Show)
517mkRangeQuery :: FieldName -> Either HalfRange Range -> RangeQuery
518mkRangeQuery f r = RangeQuery f r (Boost 1.0)
520data SimpleQueryStringQuery =
521 SimpleQueryStringQuery
522 { simpleQueryStringQuery :: QueryString
523 , simpleQueryStringField :: Maybe FieldOrFields
524 , simpleQueryStringOperator :: Maybe BooleanOperator
525 , simpleQueryStringAnalyzer :: Maybe Analyzer
526 , simpleQueryStringFlags :: Maybe [SimpleQueryFlag]
527 , simpleQueryStringLowercaseExpanded :: Maybe LowercaseExpanded
528 , simpleQueryStringLocale :: Maybe Locale
529 } deriving (Eq, Show)
531data SimpleQueryFlag =
532 SimpleQueryAll
533 | SimpleQueryNone
534 | SimpleQueryAnd
535 | SimpleQueryOr
536 | SimpleQueryPrefix
537 | SimpleQueryPhrase
538 | SimpleQueryPrecedence
539 | SimpleQueryEscape
540 | SimpleQueryWhitespace
541 | SimpleQueryFuzzy
542 | SimpleQueryNear
543 | SimpleQuerySlop deriving (Eq, Show)
545-- use_dis_max and tie_breaker when fields are plural?
546data QueryStringQuery =
547 QueryStringQuery
548 { queryStringQuery :: QueryString
549 , queryStringDefaultField :: Maybe FieldName
550 , queryStringOperator :: Maybe BooleanOperator
551 , queryStringAnalyzer :: Maybe Analyzer
552 , queryStringAllowLeadingWildcard :: Maybe AllowLeadingWildcard
553 , queryStringLowercaseExpanded :: Maybe LowercaseExpanded
554 , queryStringEnablePositionIncrements :: Maybe EnablePositionIncrements
555 , queryStringFuzzyMaxExpansions :: Maybe MaxExpansions
556 , queryStringFuzziness :: Maybe Fuzziness
557 , queryStringFuzzyPrefixLength :: Maybe PrefixLength
558 , queryStringPhraseSlop :: Maybe PhraseSlop
559 , queryStringBoost :: Maybe Boost
560 , queryStringAnalyzeWildcard :: Maybe AnalyzeWildcard
561 , queryStringGeneratePhraseQueries :: Maybe GeneratePhraseQueries
562 , queryStringMinimumShouldMatch :: Maybe MinimumMatch
563 , queryStringLenient :: Maybe Lenient
564 , queryStringLocale :: Maybe Locale
565 } deriving (Eq, Show)
567mkQueryStringQuery :: QueryString -> QueryStringQuery
568mkQueryStringQuery qs =
569 QueryStringQuery qs Nothing Nothing
570 Nothing Nothing Nothing Nothing
571 Nothing Nothing Nothing Nothing
572 Nothing Nothing Nothing Nothing
573 Nothing Nothing
575data FieldOrFields = FofField FieldName
576 | FofFields [FieldName] deriving (Eq, Show)
578data PrefixQuery =
579 PrefixQuery
580 { prefixQueryField :: FieldName
581 , prefixQueryPrefixValue :: Text
582 , prefixQueryBoost :: Maybe Boost } deriving (Eq, Show)
584data NestedQuery =
585 NestedQuery
586 { nestedQueryPath :: QueryPath
587 , nestedQueryScoreType :: ScoreType
588 , nestedQuery :: Query } deriving (Eq, Show)
590data MoreLikeThisFieldQuery =
591 MoreLikeThisFieldQuery
592 { moreLikeThisFieldText :: Text
593 , moreLikeThisFieldFields :: FieldName
594 -- default 0.3 (30%)
595 , moreLikeThisFieldPercentMatch :: Maybe PercentMatch
596 , moreLikeThisFieldMinimumTermFreq :: Maybe MinimumTermFrequency
597 , moreLikeThisFieldMaxQueryTerms :: Maybe MaxQueryTerms
598 , moreLikeThisFieldStopWords :: Maybe [StopWord]
599 , moreLikeThisFieldMinDocFrequency :: Maybe MinDocFrequency
600 , moreLikeThisFieldMaxDocFrequency :: Maybe MaxDocFrequency
601 , moreLikeThisFieldMinWordLength :: Maybe MinWordLength
602 , moreLikeThisFieldMaxWordLength :: Maybe MaxWordLength
603 , moreLikeThisFieldBoostTerms :: Maybe BoostTerms
604 , moreLikeThisFieldBoost :: Maybe Boost
605 , moreLikeThisFieldAnalyzer :: Maybe Analyzer
606 } deriving (Eq, Show)
608data MoreLikeThisQuery =
609 MoreLikeThisQuery
610 { moreLikeThisText :: Text
611 , moreLikeThisFields :: Maybe [FieldName]
612 -- default 0.3 (30%)
613 , moreLikeThisPercentMatch :: Maybe PercentMatch
614 , moreLikeThisMinimumTermFreq :: Maybe MinimumTermFrequency
615 , moreLikeThisMaxQueryTerms :: Maybe MaxQueryTerms
616 , moreLikeThisStopWords :: Maybe [StopWord]
617 , moreLikeThisMinDocFrequency :: Maybe MinDocFrequency
618 , moreLikeThisMaxDocFrequency :: Maybe MaxDocFrequency
619 , moreLikeThisMinWordLength :: Maybe MinWordLength
620 , moreLikeThisMaxWordLength :: Maybe MaxWordLength
621 , moreLikeThisBoostTerms :: Maybe BoostTerms
622 , moreLikeThisBoost :: Maybe Boost
623 , moreLikeThisAnalyzer :: Maybe Analyzer
624 } deriving (Eq, Show)
626data IndicesQuery =
627 IndicesQuery
628 { indicesQueryIndices :: [IndexName]
629 , indicesQuery :: Query
630 -- default "all"
631 , indicesQueryNoMatch :: Maybe Query } deriving (Eq, Show)
633data HasParentQuery =
634 HasParentQuery
635 { hasParentQueryType :: TypeName
636 , hasParentQuery :: Query
637 , hasParentQueryScoreType :: Maybe ScoreType } deriving (Eq, Show)
639data HasChildQuery =
640 HasChildQuery
641 { hasChildQueryType :: TypeName
642 , hasChildQuery :: Query
643 , hasChildQueryScoreType :: Maybe ScoreType } deriving (Eq, Show)
645data ScoreType =
646 ScoreTypeMax
647 | ScoreTypeSum
648 | ScoreTypeAvg
649 | ScoreTypeNone deriving (Eq, Show)
651data FuzzyQuery =
652 FuzzyQuery { fuzzyQueryField :: FieldName
653 , fuzzyQueryValue :: Text
654 , fuzzyQueryPrefixLength :: PrefixLength
655 , fuzzyQueryMaxExpansions :: MaxExpansions
656 , fuzzyQueryFuzziness :: Fuzziness
657 , fuzzyQueryBoost :: Maybe Boost
658 } deriving (Eq, Show)
660data FuzzyLikeFieldQuery =
661 FuzzyLikeFieldQuery
662 { fuzzyLikeField :: FieldName
663 -- anaphora is good for the soul.
664 , fuzzyLikeFieldText :: Text
665 , fuzzyLikeFieldMaxQueryTerms :: MaxQueryTerms
666 , fuzzyLikeFieldIgnoreTermFrequency :: IgnoreTermFrequency
667 , fuzzyLikeFieldFuzziness :: Fuzziness
668 , fuzzyLikeFieldPrefixLength :: PrefixLength
669 , fuzzyLikeFieldBoost :: Boost
670 , fuzzyLikeFieldAnalyzer :: Maybe Analyzer
671 } deriving (Eq, Show)
673data FuzzyLikeThisQuery =
674 FuzzyLikeThisQuery
675 { fuzzyLikeFields :: [FieldName]
676 , fuzzyLikeText :: Text
677 , fuzzyLikeMaxQueryTerms :: MaxQueryTerms
678 , fuzzyLikeIgnoreTermFrequency :: IgnoreTermFrequency
679 , fuzzyLikeFuzziness :: Fuzziness
680 , fuzzyLikePrefixLength :: PrefixLength
681 , fuzzyLikeBoost :: Boost
682 , fuzzyLikeAnalyzer :: Maybe Analyzer
683 } deriving (Eq, Show)
685data FilteredQuery =
686 FilteredQuery
687 { filteredQuery :: Query
688 , filteredFilter :: Filter } deriving (Eq, Show)
690data DisMaxQuery =
691 DisMaxQuery { disMaxQueries :: [Query]
692 -- default 0.0
693 , disMaxTiebreaker :: Tiebreaker
694 , disMaxBoost :: Maybe Boost
695 } deriving (Eq, Show)
697data MatchQuery =
698 MatchQuery { matchQueryField :: FieldName
699 , matchQueryQueryString :: QueryString
700 , matchQueryOperator :: BooleanOperator
701 , matchQueryZeroTerms :: ZeroTermsQuery
702 , matchQueryCutoffFrequency :: Maybe CutoffFrequency
703 , matchQueryMatchType :: Maybe MatchQueryType
704 , matchQueryAnalyzer :: Maybe Analyzer
705 , matchQueryMaxExpansions :: Maybe MaxExpansions
706 , matchQueryLenient :: Maybe Lenient } deriving (Eq, Show)
708{-| 'mkMatchQuery' is a convenience function that defaults the less common parameters,
709 enabling you to provide only the 'FieldName' and 'QueryString' to make a 'MatchQuery'
710-}
711mkMatchQuery :: FieldName -> QueryString -> MatchQuery
712mkMatchQuery field query = MatchQuery field query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing
714data MatchQueryType =
715 MatchPhrase
716 | MatchPhrasePrefix deriving (Eq, Show)
718data MultiMatchQuery =
719 MultiMatchQuery { multiMatchQueryFields :: [FieldName]
720 , multiMatchQueryString :: QueryString
721 , multiMatchQueryOperator :: BooleanOperator
722 , multiMatchQueryZeroTerms :: ZeroTermsQuery
723 , multiMatchQueryTiebreaker :: Maybe Tiebreaker
724 , multiMatchQueryType :: Maybe MultiMatchQueryType
725 , multiMatchQueryCutoffFrequency :: Maybe CutoffFrequency
726 , multiMatchQueryAnalyzer :: Maybe Analyzer
727 , multiMatchQueryMaxExpansions :: Maybe MaxExpansions
728 , multiMatchQueryLenient :: Maybe Lenient } deriving (Eq, Show)
730{-| 'mkMultiMatchQuery' is a convenience function that defaults the less common parameters,
731 enabling you to provide only the list of 'FieldName's and 'QueryString' to
732 make a 'MultiMatchQuery'.
733-}
735mkMultiMatchQuery :: [FieldName] -> QueryString -> MultiMatchQuery
736mkMultiMatchQuery matchFields query =
737 MultiMatchQuery matchFields query
738 Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
740data MultiMatchQueryType =
741 MultiMatchBestFields
742 | MultiMatchMostFields
743 | MultiMatchCrossFields
744 | MultiMatchPhrase
745 | MultiMatchPhrasePrefix deriving (Eq, Show)
747data BoolQuery =
748 BoolQuery { boolQueryMustMatch :: Maybe Query
749 , boolQueryMustNotMatch :: Maybe Query
750 , boolQueryShouldMatch :: Maybe [Query]
751 , boolQueryMinimumShouldMatch :: Maybe MinimumMatch
752 , boolQueryBoost :: Maybe Boost
753 , boolQueryDisableCoord :: Maybe DisableCoord
754 } deriving (Eq, Show)
756mkBoolQuery :: Maybe Query -> Maybe Query -> Maybe [Query] -> BoolQuery
757mkBoolQuery must mustNot should =
758 BoolQuery must mustNot should Nothing Nothing Nothing
760data BoostingQuery =
761 BoostingQuery { positiveQuery :: Query
762 , negativeQuery :: Query
763 , negativeBoost :: Boost } deriving (Eq, Show)
765data CommonTermsQuery =
766 CommonTermsQuery { commonField :: FieldName
767 , commonQuery :: QueryString
768 , commonCutoffFrequency :: CutoffFrequency
769 , commonLowFreqOperator :: BooleanOperator
770 , commonHighFreqOperator :: BooleanOperator
771 , commonMinimumShouldMatch :: Maybe CommonMinimumMatch
772 , commonBoost :: Maybe Boost
773 , commonAnalyzer :: Maybe Analyzer
774 , commonDisableCoord :: Maybe DisableCoord
775 } deriving (Eq, Show)
777data CommonMinimumMatch =
778 CommonMinimumMatchHighLow MinimumMatchHighLow
779 | CommonMinimumMatch MinimumMatch
780 deriving (Eq, Show)
782data MinimumMatchHighLow =
783 MinimumMatchHighLow { lowFreq :: MinimumMatch
784 , highFreq :: MinimumMatch } deriving (Eq, Show)
786data Filter = AndFilter [Filter] Cache
787 | OrFilter [Filter] Cache
788 | NotFilter Filter Cache
789 | IdentityFilter
790 | BoolFilter BoolMatch
791 | ExistsFilter FieldName -- always cached
792 | GeoBoundingBoxFilter GeoBoundingBoxConstraint GeoFilterType
793 | GeoDistanceFilter GeoPoint Distance DistanceType OptimizeBbox Cache
794 | GeoDistanceRangeFilter GeoPoint DistanceRange
795 | GeoPolygonFilter FieldName [LatLon]
796 | IdsFilter MappingName [DocId]
797 | LimitFilter Int
798 | MissingFilter FieldName Existence NullValue
799 | PrefixFilter FieldName PrefixValue Cache
800 | RangeFilter FieldName (Either HalfRange Range) RangeExecution Cache
801 | RegexpFilter FieldName Regexp RegexpFlags CacheName Cache CacheKey
802 deriving (Eq, Show)
804data ZeroTermsQuery = ZeroTermsNone
805 | ZeroTermsAll deriving (Eq, Show)
807-- lt, lte | gt, gte
808newtype LessThan = LessThan Double deriving (Eq, Show)
809newtype LessThanEq = LessThanEq Double deriving (Eq, Show)
810newtype GreaterThan = GreaterThan Double deriving (Eq, Show)
811newtype GreaterThanEq = GreaterThanEq Double deriving (Eq, Show)
813data HalfRange = HalfRangeLt LessThan
814 | HalfRangeLte LessThanEq
815 | HalfRangeGt GreaterThan
816 | HalfRangeGte GreaterThanEq deriving (Eq, Show)
818data Range = RangeLtGt LessThan GreaterThan
819 | RangeLtGte LessThan GreaterThanEq
820 | RangeLteGt LessThanEq GreaterThan
821 | RangeLteGte LessThanEq GreaterThanEq deriving (Eq, Show)
823data RangeExecution = RangeExecutionIndex
824 | RangeExecutionFielddata deriving (Eq, Show)
826newtype Regexp = Regexp Text deriving (Eq, Show)
827newtype RegexpFlags = RegexpFlags Text deriving (Eq, Show)
829halfRangeToKV :: HalfRange -> (Text, Double)
830halfRangeToKV (HalfRangeLt (LessThan n)) = ("lt", n)
831halfRangeToKV (HalfRangeLte (LessThanEq n)) = ("lte", n)
832halfRangeToKV (HalfRangeGt (GreaterThan n)) = ("gt", n)
833halfRangeToKV (HalfRangeGte (GreaterThanEq n)) = ("gte", n)
835rangeToKV :: Range -> (Text, Double, Text, Double)
836rangeToKV (RangeLtGt (LessThan m) (GreaterThan n)) = ("lt", m, "gt", n)
837rangeToKV (RangeLtGte (LessThan m) (GreaterThanEq n)) = ("lt", m, "gte", n)
838rangeToKV (RangeLteGt (LessThanEq m) (GreaterThan n)) = ("lte", m, "gt", n)
839rangeToKV (RangeLteGte (LessThanEq m) (GreaterThanEq n)) = ("lte", m, "gte", n)
841-- phew. Coulda used Agda style case breaking there but, you know, whatever. :)
843data Term = Term { termField :: Text
844 , termValue :: Text } deriving (Eq, Show)
846data BoolMatch = MustMatch Term Cache
847 | MustNotMatch Term Cache
848 | ShouldMatch [Term] Cache deriving (Eq, Show)
850-- "memory" or "indexed"
851data GeoFilterType = GeoFilterMemory
852 | GeoFilterIndexed deriving (Eq, Show)
854data LatLon = LatLon { lat :: Double
855 , lon :: Double } deriving (Eq, Show)
857data GeoBoundingBox =
858 GeoBoundingBox { topLeft :: LatLon
859 , bottomRight :: LatLon } deriving (Eq, Show)
861data GeoBoundingBoxConstraint =
862 GeoBoundingBoxConstraint { geoBBField :: FieldName
863 , constraintBox :: GeoBoundingBox
864 , bbConstraintcache :: Cache
865 } deriving (Eq, Show)
867data GeoPoint =
868 GeoPoint { geoField :: FieldName
869 , latLon :: LatLon} deriving (Eq, Show)
871data DistanceUnit = Miles
872 | Yards
873 | Feet
874 | Inches
875 | Kilometers
876 | Meters
877 | Centimeters
878 | Millimeters
879 | NauticalMiles deriving (Eq, Show)
881data DistanceType = Arc
882 | SloppyArc -- doesn't exist <1.0
883 | Plane deriving (Eq, Show)
885data OptimizeBbox = OptimizeGeoFilterType GeoFilterType
886 | NoOptimizeBbox deriving (Eq, Show)
888data Distance =
889 Distance { coefficient :: Double
890 , unit :: DistanceUnit } deriving (Eq, Show)
892data DistanceRange =
893 DistanceRange { distanceFrom :: Distance
894 , distanceTo :: Distance } deriving (Eq, Show)
896data FromJSON a => SearchResult a =
897 SearchResult { took :: Int
898 , timedOut :: Bool
899 , shards :: ShardResult
900 , searchHits :: SearchHits a } deriving (Eq, Show)
902type Score = Double
904data FromJSON a => SearchHits a =
905 SearchHits { hitsTotal :: Int
906 , maxScore :: Score
907 , hits :: [Hit a] } deriving (Eq, Show)
909data FromJSON a => Hit a =
910 Hit { hitIndex :: IndexName
911 , hitType :: MappingName
912 , hitDocId :: DocId
913 , hitScore :: Score
914 , hitSource :: a } deriving (Eq, Show)
916data ShardResult =
917 ShardResult { shardTotal :: Int
918 , shardsSuccessful :: Int
919 , shardsFailed :: Int } deriving (Eq, Show, Generic)
921maybeJson :: ToJSON a => Text -> Maybe a -> [(Text, Value)]
922maybeJson field (Just value) = [field .= toJSON value]
923maybeJson _ _ = []
925maybeJsonF :: (ToJSON (f Value), ToJSON a, Functor f) =>
926 Text -> Maybe (f a) -> [(Text, Value)]
927maybeJsonF field (Just value) = [field .= fmap toJSON value]
928maybeJsonF _ _ = []
930showText :: Show a => a -> Text
931showText = T.pack . show