@@ -56,6 +56,7 @@ module Database.Bloodhound.Types
5656 , Existence(..)
5757 , NullValue(..)
5858 , IndexSettings(..)
59+ , IndexTemplate(..)
5960 , Server(..)
6061 , Reply
6162 , EsResult(..)
@@ -101,6 +102,8 @@ module Database.Bloodhound.Types
101102 , RegexpFlag(..)
102103 , FieldName(..)
103104 , IndexName(..)
105+ , TemplateName(..)
106+ , TemplatePattern(..)
104107 , MappingName(..)
105108 , DocId(..)
106109 , CacheName(..)
@@ -222,8 +225,9 @@ import Control.Monad.Writer
222225import Data.Aeson
223226import Data.Aeson.Types (Pair, emptyObject, parseMaybe)
224227import qualified Data.ByteString.Lazy.Char8 as L
225−import Data.List (nub)
228+import Data.List (nub, foldl')
226229import Data.List.NonEmpty (NonEmpty (..), toList)
230+import qualified Data.HashMap.Strict as HM (union)
227231import qualified Data.Map.Strict as M
228232import Data.Maybe
229233import Data.Text (Text)
@@ -348,6 +352,20 @@ data FieldType = GeoPointType
348352data FieldDefinition =
349353 FieldDefinition { fieldType :: FieldType } deriving (Eq, Show)
350354
355+{-| An 'IndexTemplate' defines a template that will automatically be
356+ applied to new indices created. The templates include both
357+ 'IndexSettings' and mappings, and a simple 'TemplatePattern' that
358+ controls if the template will be applied to the index created.
359+ Specify mappings as follows: @[toJSON TweetMapping, ...]@
360+
361+ https://www.elastic.co/guide/en/elasticsearch/reference/1.7/indices-templates.html
362+-}
363+data IndexTemplate =
364+ IndexTemplate { templatePattern :: TemplatePattern
365+ , templateSettings :: Maybe IndexSettings
366+ , templateMappings :: [Value]
367+ }
368+
351369data MappingField =
352370 MappingField { mappingFieldName :: FieldName
353371 , fieldDefinition :: FieldDefinition } deriving (Eq, Show)
@@ -546,6 +564,14 @@ newtype Server = Server Text deriving (Eq, Show)
546564-}
547565newtype IndexName = IndexName Text deriving (Eq, Generic, Show)
548566
567+{-| 'TemplateName' is used to describe which template to query/create/delete
568+-}
569+newtype TemplateName = TemplateName Text deriving (Eq, Show, Generic)
570+
571+{-| 'TemplatePattern' represents a pattern which is matched against index names
572+-}
573+newtype TemplatePattern = TemplatePattern Text deriving (Eq, Show, Generic)
574+
549575{-| 'MappingName' is part of mappings which are how ES describes and schematizes
550576 the data in the indices.
551577-}
@@ -1953,6 +1979,8 @@ instance ToJSON IgnoreTermFrequency
19531979instance ToJSON MaxQueryTerms
19541980instance ToJSON TypeName
19551981instance ToJSON IndexName
1982+instance ToJSON TemplateName
1983+instance ToJSON TemplatePattern
19561984instance ToJSON BoostTerms
19571985instance ToJSON MaxWordLength
19581986instance ToJSON MinWordLength
@@ -1991,6 +2019,16 @@ instance FromJSON Status where
19912019instance ToJSON IndexSettings where
19922020 toJSON (IndexSettings s r) = object ["settings" .= object ["shards" .= s, "replicas" .= r]]
19932021
2022+instance ToJSON IndexTemplate where
2023+ toJSON (IndexTemplate p s m) =
2024+ objectNoNulls [ "template" .= p
2025+ , "settings" .= s
2026+ , "mappings" .= foldl' merge (object []) m
2027+ ]
2028+ where
2029+ objectNoNulls = object . filter (\(_, v) -> v /= Null)
2030+ merge (Object o1) (Object o2) = toJSON $ HM.union o1 o2
2031+ merge _ _ = undefined
19942032
19952033instance (FromJSON a) => FromJSON (EsResult a) where
19962034 parseJSON (Object v) = EsResult <$>