bloodhound-0.20.0.0: src/Database/Bloodhound/Internal/Sort.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Database.Bloodhound.Internal.Sort where
import Bloodhound.Import
import Database.Bloodhound.Internal.Newtypes
import Database.Bloodhound.Internal.Query
-- | 'SortMode' prescribes how to handle sorting array/multi-valued fields.
--
-- http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html#_sort_mode_option
data SortMode
= SortMin
| SortMax
| SortSum
| SortAvg
deriving (Eq, Show)
instance ToJSON SortMode where
toJSON SortMin = String "min"
toJSON SortMax = String "max"
toJSON SortSum = String "sum"
toJSON SortAvg = String "avg"
-- | 'mkSort' defaults everything but the 'FieldName' and the 'SortOrder' so
-- that you can concisely describe the usual kind of 'SortSpec's you want.
mkSort :: FieldName -> SortOrder -> DefaultSort
mkSort fieldName sOrder = DefaultSort fieldName sOrder Nothing Nothing Nothing Nothing
-- | 'Sort' is a synonym for a list of 'SortSpec's. Sort behavior is order
-- dependent with later sorts acting as tie-breakers for earlier sorts.
type Sort = [SortSpec]
-- | The two main kinds of 'SortSpec' are 'DefaultSortSpec' and
-- 'GeoDistanceSortSpec'. The latter takes a 'SortOrder', 'GeoPoint', and
-- 'DistanceUnit' to express "nearness" to a single geographical point as a
-- sort specification.
--
-- <http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
data SortSpec
= DefaultSortSpec DefaultSort
| GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit
deriving (Eq, Show)
instance ToJSON SortSpec where
toJSON
( DefaultSortSpec
( DefaultSort
(FieldName dsSortFieldName)
dsSortOrder
dsIgnoreUnmapped
dsSortMode
dsMissingSort
dsNestedFilter
)
) =
object [fromText dsSortFieldName .= omitNulls base]
where
base =
[ "order" .= dsSortOrder,
"unmapped_type" .= dsIgnoreUnmapped,
"mode" .= dsSortMode,
"missing" .= dsMissingSort,
"nested_filter" .= dsNestedFilter
]
toJSON (GeoDistanceSortSpec gdsSortOrder (GeoPoint (FieldName field) gdsLatLon) units) =
object
[ "unit" .= units,
fromText field .= gdsLatLon,
"order" .= gdsSortOrder
]
-- | 'DefaultSort' is usually the kind of 'SortSpec' you'll want. There's a
-- 'mkSort' convenience function for when you want to specify only the most
-- common parameters.
--
-- The `ignoreUnmapped`, when `Just` field is used to set the elastic 'unmapped_type'
--
-- <http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
data DefaultSort = DefaultSort
{ sortFieldName :: FieldName,
sortOrder :: SortOrder,
-- default False
ignoreUnmapped :: Maybe Text,
sortMode :: Maybe SortMode,
missingSort :: Maybe Missing,
nestedFilter :: Maybe Filter
}
deriving (Eq, Show)
-- | 'SortOrder' is 'Ascending' or 'Descending', as you might expect. These get
-- encoded into "asc" or "desc" when turned into JSON.
--
-- <http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html#search-request-sort>
data SortOrder
= Ascending
| Descending
deriving (Eq, Show)
instance ToJSON SortOrder where
toJSON Ascending = String "asc"
toJSON Descending = String "desc"
-- | 'Missing' prescribes how to handle missing fields. A missing field can be
-- sorted last, first, or using a custom value as a substitute.
--
-- <http://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html#_missing_values>
data Missing
= LastMissing
| FirstMissing
| CustomMissing Text
deriving (Eq, Show)
instance ToJSON Missing where
toJSON LastMissing = String "_last"
toJSON FirstMissing = String "_first"
toJSON (CustomMissing txt) = String txt