git.iko.soy/typeable/bloodhound
on master help sign in
Add value_count aggregation support

This also adds a newtype for script. I would recommend the "Either Text Text" for TermsAggregation be instead Either FieldName Script, but that isn't directly related to this PR.

commit463fdc80279926a4cab985277ca184ec7c5f2ff1 authorMichael Xavier <michael@michaelxavier.net> dateTue 28 Jul 2015, 09:17 (11 years ago) parent85bbc62
2 files changed+37−9
src/Database/Bloodhound/Types.hs+16−1 tests/tests.hs+21−8
src/Database/Bloodhound/Types.hs+16−1
@@ -103,6 +103,7 @@ module Database.Bloodhound.Types
103103 , RegexpFlags(..)
104104 , RegexpFlag(..)
105105 , FieldName(..)
106+ , Script(..)
106107 , IndexName(..)
107108 , TemplateName(..)
108109 , TemplatePattern(..)
@@ -201,6 +202,7 @@ module Database.Bloodhound.Types
201202 , Bucket(..)
202203 , BucketAggregation(..)
203204 , TermsAggregation(..)
205+ , ValueCountAggregation(..)
204206 , DateHistogramAggregation(..)
205207
206208 , Highlights(..)
@@ -607,6 +609,12 @@ newtype QueryString = QueryString Text deriving (Eq, Generic, Show)
607609-}
608610newtype FieldName = FieldName Text deriving (Eq, Show)
609611
612+
613+{-| 'Script' is often used in place of 'FieldName' to specify more
614+complex ways of extracting a value from a document.
615+-}
616+newtype Script = Script { scriptText :: Text } deriving (Eq, Show)
617+
610618{-| 'CacheName' is used in 'RegexpFilter' for describing the
611619 'CacheKey' keyed caching behavior.
612620-}
@@ -1310,7 +1318,8 @@ data Interval = Year
13101318 | FractionalInterval Float TimeInterval deriving (Eq, Show)
13111319
13121320data Aggregation = TermsAgg TermsAggregation
1313− | DateHistogramAgg DateHistogramAggregation deriving (Eq, Show)
1321+ | DateHistogramAgg DateHistogramAggregation
1322+ | ValueCountAgg ValueCountAggregation deriving (Eq, Show)
13141323
13151324
13161325data TermsAggregation = TermsAggregation { term :: Either Text Text
@@ -1336,6 +1345,8 @@ data DateHistogramAggregation = DateHistogramAggregation { dateField :: Fie
13361345 , dateAggs :: Maybe Aggregations
13371346 } deriving (Eq, Show)
13381347
1348+data ValueCountAggregation = FieldValueCount FieldName
1349+ | ScriptValueCount Script deriving (Eq, Show)
13391350
13401351mkTermsAggregation :: Text -> TermsAggregation
13411352mkTermsAggregation t = TermsAggregation (Left t) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
@@ -1409,6 +1420,10 @@ instance ToJSON Aggregation where
14091420 "post_offset" .= postOffset
14101421 ],
14111422 "aggs" .= dateHistoAggs ]
1423+ toJSON (ValueCountAgg a) = object ["value_count" .= v]
1424+ where v = case a of
1425+ (FieldValueCount (FieldName n)) -> object ["field" .= n]
1426+ (ScriptValueCount (Script s)) -> object ["script" .= s]
14121427
14131428type AggregationResults = M.Map Text Value
14141429
tests/tests.hs+21−8
@@ -14,6 +14,7 @@ import Data.List (nub)
1414import Data.List.NonEmpty (NonEmpty (..))
1515import qualified Data.List.NonEmpty as NE
1616import qualified Data.Map.Strict as M
17+import Data.Monoid
1718import Data.Text (Text)
1819import qualified Data.Text as T
1920import Data.Time.Calendar (Day (..))
@@ -174,15 +175,16 @@ insertOther = do
174175
175176searchTweet :: Search -> BH IO (Either String Tweet)
176177searchTweet search = do
177− reply <- searchByIndex testIndex search
178− let result = eitherDecode (responseBody reply) :: Either String (SearchResult Tweet)
178+ result <- searchTweets search
179179 let myTweet = fmap (hitSource . head . hits . searchHits) result
180180 return myTweet
181181
182+searchTweets :: Search -> BH IO (Either String (SearchResult Tweet))
183+searchTweets search = eitherDecode . responseBody <$> searchByIndex testIndex search
184+
182185searchExpectNoResults :: Search -> BH IO ()
183186searchExpectNoResults search = do
184− reply <- searchByIndex testIndex search
185− let result = eitherDecode (responseBody reply) :: Either String (SearchResult Tweet)
187+ result <- searchTweets search
186188 let emptyHits = fmap (hits . searchHits) result
187189 liftIO $
188190 emptyHits `shouldBe` Right []
@@ -214,8 +216,7 @@ searchTermsAggHint hints = do
214216
215217searchTweetHighlight :: Search -> BH IO (Either String (Maybe HitHighlight))
216218searchTweetHighlight search = do
217− reply <- searchByIndex testIndex search
218− let result = eitherDecode (responseBody reply) :: Either String (SearchResult Tweet)
219+ result <- searchTweets search
219220 let myHighlight = fmap (hitHighlight . head . hits . searchHits) result
220221 return myHighlight
221222
@@ -435,8 +436,7 @@ main = hspec $ do
435436 let search = Search Nothing
436437 (Just IdentityFilter) (Just [sortSpec]) Nothing Nothing
437438 False (From 0) (Size 10) Nothing
438− reply <- searchByIndex testIndex search
439− let result = eitherDecode (responseBody reply) :: Either String (SearchResult Tweet)
439+ result <- searchTweets search
440440 let myTweet = fmap (hitSource . head . hits . searchHits) result
441441 liftIO $
442442 myTweet `shouldBe` Right otherTweet
@@ -628,6 +628,19 @@ main = hspec $ do
628628 _ <- insertData
629629 searchTermsAggHint [GlobalOrdinals, GlobalOrdinalsHash, GlobalOrdinalsLowCardinality, Map]
630630
631+
632+ it "can execute value_count aggregations" $ withTestEnv $ do
633+ _ <- insertData
634+ _ <- insertOther
635+ let ags = mkAggregations "user_count" (ValueCountAgg (FieldValueCount (FieldName "user"))) <>
636+ mkAggregations "bogus_count" (ValueCountAgg (FieldValueCount (FieldName "bogus")))
637+ let search = mkAggregateSearch Nothing ags
638+ let countPair k n = (k, object ["value" .= Number n])
639+ res <- searchTweets search
640+ liftIO $
641+ fmap aggregations res `shouldBe` Right (Just (M.fromList [ countPair "user_count" 2
642+ , countPair "bogus_count" 0
643+ ]))
631644 -- Interaction of date serialization and date histogram aggregation is broken.
632645 -- it "returns date histogram aggregation results" $ withTestEnv $ do
633646 -- _ <- insertData