@@ -74,6 +74,7 @@ module Database.V5.Bloodhound.Types
7474 , UpdatableIndexSetting(..)
7575 , IndexSettingsSummary(..)
7676 , AllocationPolicy(..)
77+ , Compression(..)
7778 , ReplicaBounds(..)
7879 , Bytes(..)
7980 , gigabytes
@@ -202,6 +203,7 @@ module Database.V5.Bloodhound.Types
202203 , ZeroTermsQuery(..)
203204 , CutoffFrequency(..)
204205 , Analyzer(..)
206+ , Tokenizer(..)
205207 , MaxExpansions(..)
206208 , Lenient(..)
207209 , MatchQueryType(..)
@@ -376,6 +378,12 @@ module Database.V5.Bloodhound.Types
376378
377379 , EsUsername(..)
378380 , EsPassword(..)
381+
382+ , Analysis(..)
383+ , AnalyzerDefinition(..)
384+ , TokenizerDefinition(..)
385+ , Ngram(..)
386+ , TokenChar(..)
379387 ) where
380388
381389import Control.Applicative as A
@@ -579,12 +587,94 @@ data UpdatableIndexSetting = NumberOfReplicas ReplicaCount
579587 | TTLDisablePurge Bool
580588 -- ^ Disables temporarily the purge of expired docs.
581589 | TranslogFSType FSType
590+ | CompressionSetting Compression
582591 | IndexCompoundFormat CompoundFormat
583592 | IndexCompoundOnFlush Bool
584593 | WarmerEnabled Bool
585594 | MappingTotalFieldsLimit Int
595+ | AnalysisSetting Analysis
596+ -- ^ Analysis is not a dynamic setting and can only be performed on a closed index.
586597 deriving (Eq, Show, Generic, Typeable)
587598
599+data Analysis = Analysis
600+ { analysisAnalyzer :: M.Map Text AnalyzerDefinition
601+ , analysisTokenizer :: M.Map Text TokenizerDefinition
602+ } deriving (Eq,Show,Generic,Typeable)
603+
604+instance ToJSON Analysis where
605+ toJSON (Analysis analyzer tokenizer) = object
606+ [ "analyzer" .= analyzer
607+ , "tokenizer" .= tokenizer
608+ ]
609+
610+instance FromJSON Analysis where
611+ parseJSON = withObject "Analysis" $ \m -> Analysis
612+ <$> m .: "analyzer"
613+ <*> m .: "tokenizer"
614+
615+data AnalyzerDefinition = AnalyzerDefinition
616+ { analyzerDefinitionTokenizer :: Maybe Tokenizer
617+ } deriving (Eq,Show,Generic,Typeable)
618+
619+instance ToJSON AnalyzerDefinition where
620+ toJSON (AnalyzerDefinition tokenizer) = object $ catMaybes
621+ [ fmap ("tokenizer" .=) tokenizer
622+ ]
623+
624+instance FromJSON AnalyzerDefinition where
625+ parseJSON = withObject "AnalyzerDefinition" $ \m -> AnalyzerDefinition
626+ <$> m .:? "tokenizer"
627+
628+
629+data TokenizerDefinition
630+ = TokenizerDefinitionNgram Ngram
631+ deriving (Eq,Show,Generic,Typeable)
632+
633+instance ToJSON TokenizerDefinition where
634+ toJSON x = case x of
635+ TokenizerDefinitionNgram (Ngram minGram maxGram tokenChars) -> object
636+ [ "type" .= ("ngram" :: Text)
637+ , "min_gram" .= minGram
638+ , "max_gram" .= maxGram
639+ , "token_chars" .= tokenChars
640+ ]
641+
642+instance FromJSON TokenizerDefinition where
643+ parseJSON = withObject "TokenizerDefinition" $ \m -> do
644+ typ <- m .: "type" :: Parser Text
645+ case typ of
646+ "ngram" -> fmap TokenizerDefinitionNgram $ Ngram
647+ <$> (fmap unStringlyTypedInt (m .: "min_gram"))
648+ <*> (fmap unStringlyTypedInt (m .: "max_gram"))
649+ <*> m .: "token_chars"
650+ _ -> fail "invalid TokenizerDefinition"
651+
652+data Ngram = Ngram
653+ { ngramMinGram :: Int
654+ , ngramMaxGram :: Int
655+ , ngramTokenChars :: [TokenChar]
656+ } deriving (Eq,Show,Generic,Typeable)
657+
658+data TokenChar = TokenLetter | TokenDigit | TokenWhitespace | TokenPunctuation | TokenSymbol
659+ deriving (Eq,Read,Show,Generic,Typeable)
660+
661+instance ToJSON TokenChar where
662+ toJSON t = String $ case t of
663+ TokenLetter -> "letter"
664+ TokenDigit -> "digit"
665+ TokenWhitespace -> "whitespace"
666+ TokenPunctuation -> "punctuation"
667+ TokenSymbol -> "symbol"
668+
669+instance FromJSON TokenChar where
670+ parseJSON = withText "TokenChar" $ \t -> case t of
671+ "letter" -> return TokenLetter
672+ "digit" -> return TokenDigit
673+ "whitespace" -> return TokenWhitespace
674+ "punctuation" -> return TokenPunctuation
675+ "symbol" -> return TokenSymbol
676+ _ -> fail "invalid TokenChar"
677+
588678data AllocationPolicy = AllocAll
589679 -- ^ Allows shard allocation for all shards.
590680 | AllocPrimaries
@@ -600,6 +690,26 @@ data ReplicaBounds = ReplicasBounded Int Int
600690 | ReplicasUnbounded
601691 deriving (Eq, Read, Show, Generic, Typeable)
602692
693+data Compression
694+ = CompressionDefault
695+ -- ^ Compress with LZ4
696+ | CompressionBest
697+ -- ^ Compress with DEFLATE. Elastic
698+ -- <https://www.elastic.co/blog/elasticsearch-storage-the-true-story-2.0 blogs>
699+ -- that this can reduce disk use by 15%-25%.
700+ deriving (Eq,Show,Generic,Typeable)
701+
702+instance ToJSON Compression where
703+ toJSON x = case x of
704+ CompressionDefault -> toJSON ("default" :: Text)
705+ CompressionBest -> toJSON ("best_compression" :: Text)
706+
707+instance FromJSON Compression where
708+ parseJSON = withText "Compression" $ \t -> case t of
709+ "default" -> return CompressionDefault
710+ "best_compression" -> return CompressionBest
711+ _ -> fail "invalid compression codec"
712+
603713-- | A measure of bytes used for various configurations. You may want
604714-- to use smart constructors like 'gigabytes' for larger values.
605715--
@@ -1020,6 +1130,8 @@ newtype CutoffFrequency =
10201130 CutoffFrequency Double deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
10211131newtype Analyzer =
10221132 Analyzer Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
1133+newtype Tokenizer =
1134+ Tokenizer Text deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
10231135newtype MaxExpansions =
10241136 MaxExpansions Int deriving (Eq, Read, Show, Generic, ToJSON, FromJSON, Typeable)
10251137
@@ -1438,13 +1550,15 @@ data MatchQuery =
14381550 , matchQueryAnalyzer :: Maybe Analyzer
14391551 , matchQueryMaxExpansions :: Maybe MaxExpansions
14401552 , matchQueryLenient :: Maybe Lenient
1441− , matchQueryBoost :: Maybe Boost } deriving (Eq, Read, Show, Generic, Typeable)
1553+ , matchQueryBoost :: Maybe Boost
1554+ , matchQueryMinimumShouldMatch :: Maybe Text
1555+ } deriving (Eq, Read, Show, Generic, Typeable)
14421556
14431557{-| 'mkMatchQuery' is a convenience function that defaults the less common parameters,
14441558 enabling you to provide only the 'FieldName' and 'QueryString' to make a 'MatchQuery'
14451559-}
14461560mkMatchQuery :: FieldName -> QueryString -> MatchQuery
1447−mkMatchQuery field query = MatchQuery field query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
1561+mkMatchQuery field query = MatchQuery field query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing Nothing
14481562
14491563data MatchQueryType =
14501564 MatchPhrase
@@ -2834,7 +2948,9 @@ instance ToJSON MatchQuery where
28342948 toJSON (MatchQuery (FieldName fieldName)
28352949 (QueryString mqQueryString) booleanOperator
28362950 zeroTermsQuery cutoffFrequency matchQueryType
2837− analyzer maxExpansions lenient boost) =
2951+ analyzer maxExpansions lenient boost
2952+ minShouldMatch
2953+ ) =
28382954 object [ fieldName .= omitNulls base ]
28392955 where base = [ "query" .= mqQueryString
28402956 , "operator" .= booleanOperator
@@ -2844,7 +2960,9 @@ instance ToJSON MatchQuery where
28442960 , "analyzer" .= analyzer
28452961 , "max_expansions" .= maxExpansions
28462962 , "lenient" .= lenient
2847− , "boost" .= boost ]
2963+ , "boost" .= boost
2964+ , "minimum_should_match" .= minShouldMatch
2965+ ]
28482966
28492967instance FromJSON MatchQuery where
28502968 parseJSON = withObject "MatchQuery" parse
@@ -2859,6 +2977,7 @@ instance FromJSON MatchQuery where
28592977 <*> o .:? "max_expansions"
28602978 <*> o .:? "lenient"
28612979 <*> o .:? "boost"
2980+ <*> o .:? "minimum_should_match"
28622981
28632982instance ToJSON MultiMatchQuery where
28642983 toJSON (MultiMatchQuery fields (QueryString query) boolOp
@@ -2982,6 +3101,7 @@ instance ToJSON UpdatableIndexSetting where
29823101 toJSON (GCDeletes x) = oPath ("index" :| ["gc_deletes"]) (NominalDiffTimeJSON x)
29833102 toJSON (TTLDisablePurge x) = oPath ("index" :| ["ttl", "disable_purge"]) x
29843103 toJSON (TranslogFSType x) = oPath ("index" :| ["translog", "fs", "type"]) x
3104+ toJSON (CompressionSetting x) = oPath ("index" :| ["codec"]) x
29853105 toJSON (IndexCompoundFormat x) = oPath ("index" :| ["compound_format"]) x
29863106 toJSON (IndexCompoundOnFlush x) = oPath ("index" :| ["compound_on_flush"]) x
29873107 toJSON (WarmerEnabled x) = oPath ("index" :| ["warmer", "enabled"]) x
@@ -2990,6 +3110,7 @@ instance ToJSON UpdatableIndexSetting where
29903110 toJSON (BlocksWrite x) = oPath ("blocks" :| ["write"]) x
29913111 toJSON (BlocksMetaData x) = oPath ("blocks" :| ["metadata"]) x
29923112 toJSON (MappingTotalFieldsLimit x) = oPath ("index" :| ["mapping","total_fields","limit"]) x
3113+ toJSON (AnalysisSetting x) = oPath ("index" :| ["analysis"]) x
29933114
29943115instance FromJSON UpdatableIndexSetting where
29953116 parseJSON = withObject "UpdatableIndexSetting" parse
@@ -3014,6 +3135,7 @@ instance FromJSON UpdatableIndexSetting where
30143135 <|> gcDeletes `taggedAt` ["index", "gc_deletes"]
30153136 <|> ttlDisablePurge `taggedAt` ["index", "ttl", "disable_purge"]
30163137 <|> translogFSType `taggedAt` ["index", "translog", "fs", "type"]
3138+ <|> compressionSetting `taggedAt` ["index", "codec"]
30173139 <|> compoundFormat `taggedAt` ["index", "compound_format"]
30183140 <|> compoundOnFlush `taggedAt` ["index", "compound_on_flush"]
30193141 <|> warmerEnabled `taggedAt` ["index", "warmer", "enabled"]
@@ -3022,6 +3144,7 @@ instance FromJSON UpdatableIndexSetting where
30223144 <|> blocksWrite `taggedAt` ["blocks", "write"]
30233145 <|> blocksMetaData `taggedAt` ["blocks", "metadata"]
30243146 <|> mappingTotalFieldsLimit `taggedAt` ["index", "mapping", "total_fields", "limit"]
3147+ <|> analysisSetting `taggedAt` ["index", "analysis"]
30253148 where taggedAt f ks = taggedAt' f (Object o) ks
30263149 taggedAt' f v [] = f =<< (parseJSON v <|> (parseJSON (unStringlyTypeJSON v)))
30273150 taggedAt' f v (k:ks) = withObject "Object" (\o -> do v' <- o .: k
@@ -3047,6 +3170,7 @@ instance FromJSON UpdatableIndexSetting where
30473170 gcDeletes = pure . GCDeletes . ndtJSON
30483171 ttlDisablePurge = pure . TTLDisablePurge
30493172 translogFSType = pure . TranslogFSType
3173+ compressionSetting = pure . CompressionSetting
30503174 compoundFormat = pure . IndexCompoundFormat
30513175 compoundOnFlush = pure . IndexCompoundOnFlush
30523176 warmerEnabled = pure . WarmerEnabled
@@ -3055,6 +3179,7 @@ instance FromJSON UpdatableIndexSetting where
30553179 blocksWrite = pure . BlocksWrite
30563180 blocksMetaData = pure . BlocksMetaData
30573181 mappingTotalFieldsLimit = pure . MappingTotalFieldsLimit
3182+ analysisSetting = pure . AnalysisSetting
30583183
30593184instance FromJSON IndexSettingsSummary where
30603185 parseJSON = withObject "IndexSettingsSummary" parse
@@ -4643,10 +4768,13 @@ instance FromJSON NodeDataPathStats where
46434768
46444769newtype StringlyTypedDouble = StringlyTypedDouble { unStringlyTypedDouble :: Double }
46454770
4646−
46474771instance FromJSON StringlyTypedDouble where
46484772 parseJSON = fmap StringlyTypedDouble . parseJSON . unStringlyTypeJSON
46494773
4774+newtype StringlyTypedInt = StringlyTypedInt { unStringlyTypedInt :: Int }
4775+
4776+instance FromJSON StringlyTypedInt where
4777+ parseJSON = fmap StringlyTypedInt . parseJSON . unStringlyTypeJSON
46504778
46514779instance FromJSON NodeFSTotalStats where
46524780 parseJSON = withObject "NodeFSTotalStats" parse