git.iko.soy/typeable/bloodhound
on master help sign in
BoolQuery
e484d55Chris Allen
Database/Bloodhound/Types.hs+11−8
@@ -12,6 +12,7 @@ module Database.Bloodhound.Types
12 , unpackId
12 , unpackId
13 , mkMatchQuery
13 , mkMatchQuery
14 , mkMultiMatchQuery
14 , mkMultiMatchQuery
15+ , mkBoolQuery
15 , Version(..)
16 , Version(..)
16 , Status(..)
17 , Status(..)
17 , Existence(..)
18 , Existence(..)
@@ -98,6 +99,8 @@ module Database.Bloodhound.Types
98 , MatchQueryType(..)
99 , MatchQueryType(..)
99 , MultiMatchQueryType(..)
100 , MultiMatchQueryType(..)
100 , Tiebreaker(..)
101 , Tiebreaker(..)
102+ , MinimumMatch(..)
103+ , DisableCoord(..)
101 ) where
104 ) where
102
105
103import Data.Aeson
106import Data.Aeson
@@ -222,9 +225,9 @@ newtype Lenient = Lenient Bool deriving (Eq, Show, Generic)
222newtype Tiebreaker = Tiebreaker Double deriving (Eq, Show, Generic)
225newtype Tiebreaker = Tiebreaker Double deriving (Eq, Show, Generic)
223newtype Boost = Boost Double deriving (Eq, Show, Generic)
226newtype Boost = Boost Double deriving (Eq, Show, Generic)
224newtype BoostTerms = BoostTerms Double deriving (Eq, Show)
227newtype BoostTerms = BoostTerms Double deriving (Eq, Show)
225−newtype MinimumMatch = MinimumMatch Int deriving (Eq, Show)
228+newtype MinimumMatch = MinimumMatch Int deriving (Eq, Show, Generic)
226newtype MinimumMatchText = MinimumMatchText Text deriving (Eq, Show)
229newtype MinimumMatchText = MinimumMatchText Text deriving (Eq, Show)
227−newtype DisableCoord = DisableCoord Bool deriving (Eq, Show)
230+newtype DisableCoord = DisableCoord Bool deriving (Eq, Show, Generic)
228newtype IgnoreTermFrequency = IgnoreTermFrequency Bool deriving (Eq, Show)
231newtype IgnoreTermFrequency = IgnoreTermFrequency Bool deriving (Eq, Show)
229newtype MinimumTermFrequency = MinimumTermFrequency Int deriving (Eq, Show)
232newtype MinimumTermFrequency = MinimumTermFrequency Int deriving (Eq, Show)
230newtype MaxQueryTerms = MaxQueryTerms Int deriving (Eq, Show)
233newtype MaxQueryTerms = MaxQueryTerms Int deriving (Eq, Show)
@@ -290,9 +293,6 @@ data Query = TermQuery Term (Maybe Boost)
290 | QueryRegexpQuery RegexpQuery
293 | QueryRegexpQuery RegexpQuery
291 deriving (Eq, Show)
294 deriving (Eq, Show)
292
295
293−-- Possible flags are ALL, ANYSTRING, AUTOMATON, COMPLEMENT,
294−-- EMPTY, INTERSECTION, INTERVAL, or NONE. huh?
295−
296data RegexpQuery =
296data RegexpQuery =
297 RegexpQuery { regexpQueryField :: FieldName
297 RegexpQuery { regexpQueryField :: FieldName
298 , regexpQuery :: Regexp
298 , regexpQuery :: Regexp
@@ -515,6 +515,9 @@ data BoolQuery = BoolQuery { boolQueryMustMatch :: Maybe Query
515 , boolQueryDisableCoord :: Maybe DisableCoord
515 , boolQueryDisableCoord :: Maybe DisableCoord
516 } deriving (Eq, Show)
516 } deriving (Eq, Show)
517
517
518+mkBoolQuery :: Maybe Query -> Maybe Query -> Maybe [Query] -> BoolQuery
519+mkBoolQuery must mustNot should = BoolQuery must mustNot should Nothing Nothing Nothing
520+
518data BoostingQuery = BoostingQuery { positiveQuery :: Maybe Query
521data BoostingQuery = BoostingQuery { positiveQuery :: Maybe Query
519 , negativeQuery :: Maybe Query
522 , negativeQuery :: Maybe Query
520 , positiveBoost :: Maybe Boost
523 , positiveBoost :: Maybe Boost
@@ -673,12 +676,12 @@ data ShardResult =
673 , shardsSuccessful :: Int
676 , shardsSuccessful :: Int
674 , shardsFailed :: Int } deriving (Eq, Show, Generic)
677 , shardsFailed :: Int } deriving (Eq, Show, Generic)
675
678
676−maybeJson ToJSON a => Text -> Maybe a -> [Data.Aeson.Types.Internal.Pair]
679+maybeJson :: ToJSON a => Text -> Maybe a -> [(Text, Value)]
677maybeJson field (Just value) = [field .= toJSON value]
680maybeJson field (Just value) = [field .= toJSON value]
678maybeJson _ _ = []
681maybeJson _ _ = []
679
682
680−maybeJsonF :: (ToJSON (f Value), ToJSON a, Functor f) =>
683+-- maybeJsonF :: (ToJSON (f Value), ToJSON a, Functor f) =>
681− Text -> Maybe (f a) -> [Data.Aeson.Types.Internal.Pair]
684+-- Text -> Maybe (f a) -> [(Text, Value)]
682maybeJsonF field (Just value) = [field .= fmap toJSON value]
685maybeJsonF field (Just value) = [field .= fmap toJSON value]
683maybeJsonF _ _ = []
686maybeJsonF _ _ = []
684
687
Database/Bloodhound/Types/Instances.hs+43−20
@@ -120,25 +120,46 @@ instance ToJSON Filter where
120
120
121instance ToJSON GeoPoint where
121instance ToJSON GeoPoint where
122 toJSON (GeoPoint (FieldName geoField) latLon) =
122 toJSON (GeoPoint (FieldName geoField) latLon) =
123− object [geoField .= toJSON latLon]
123+ object [ geoField .= toJSON latLon ]
124
124
125
125
126instance ToJSON Query where
126instance ToJSON Query where
127 toJSON (TermQuery (Term termField termValue) boost) =
127 toJSON (TermQuery (Term termField termValue) boost) =
128− object ["term" .=
128+ object [ "term" .=
129− object [termField .= object merged]]
129+ object [termField .= object merged]]
130 where
130 where
131− base = ["value" .= termValue]
131+ base = [ "value" .= termValue ]
132 boosted = case boost of
132 boosted = case boost of
133− (Just boostValue) -> ["boost" .= boostValue]
133+ (Just boostValue) -> [ "boost" .= boostValue ]
134 Nothing -> []
134 Nothing -> []
135 merged = mappend base boosted
135 merged = mappend base boosted
136
136
137 toJSON (QueryMatchQuery matchQuery) =
137 toJSON (QueryMatchQuery matchQuery) =
138− object ["match" .= toJSON matchQuery]
138+ object [ "match" .= toJSON matchQuery ]
139
139
140 toJSON (QueryMultiMatchQuery multiMatchQuery) =
140 toJSON (QueryMultiMatchQuery multiMatchQuery) =
141− object ["multi_match" .= toJSON multiMatchQuery]
141+ object [ "multi_match" .= toJSON multiMatchQuery ]
142+
143+ toJSON (QueryBoolQuery boolQuery) =
144+ object [ "bool" .= toJSON boolQuery ]
145+
146+
147+mField :: (ToJSON a, Functor f) => T.Text -> f a -> f (T.Text, Value)
148+mField field = fmap ((field .=) . toJSON)
149+
150+
151+instance ToJSON BoolQuery where
152+ toJSON (BoolQuery mustM notM shouldM min boost disableCoord) =
153+ object filtered
154+ where f field = fmap ((field .=) . toJSON)
155+ filtered = catMaybes
156+ [ mField "must" mustM
157+ , mField "must_not" notM
158+ , mField "should" shouldM
159+ , mField "minimum_should_match" min
160+ , mField "boost" boost
161+ , mField "disable_coord" disableCoord ]
162+
142
163
143instance ToJSON MatchQuery where
164instance ToJSON MatchQuery where
144 toJSON (MatchQuery (FieldName fieldName)
165 toJSON (MatchQuery (FieldName fieldName)
@@ -150,12 +171,12 @@ instance ToJSON MatchQuery where
150 , "operator" .= toJSON booleanOperator
171 , "operator" .= toJSON booleanOperator
151 , "zero_terms_query" .= toJSON zeroTermsQuery]
172 , "zero_terms_query" .= toJSON zeroTermsQuery]
152 ++ maybeAdd
173 ++ maybeAdd
153− f field = fmap ((field .=) . toJSON)
154− maybeAdd = catMaybes [ f "cutoff_frequency" cutoffFrequency
174+ maybeAdd = catMaybes [ mField "cutoff_frequency" cutoffFrequency
155− , f "type" matchQueryType
175+ , mField "type" matchQueryType
156− , f "analyzer" analyzer
176+ , mField "analyzer" analyzer
157− , f "max_expansions" maxExpansions
177+ , mField "max_expansions" maxExpansions
158− , f "lenient" lenient ]
178+ , mField "lenient" lenient ]
179+
159
180
160instance ToJSON MultiMatchQuery where
181instance ToJSON MultiMatchQuery where
161 toJSON (MultiMatchQuery fields (QueryString query) boolOp
182 toJSON (MultiMatchQuery fields (QueryString query) boolOp
@@ -165,15 +186,15 @@ instance ToJSON MultiMatchQuery where
165 , "query" .= query
186 , "query" .= query
166 , "operator" .= toJSON boolOp
187 , "operator" .= toJSON boolOp
167 , "zero_terms_query" .= toJSON ztQ ]
188 , "zero_terms_query" .= toJSON ztQ ]
168− f field = fmap ((field .=) . toJSON)
169− maybeAdd = catMaybes [ f "tiebreaker" tb
189+ maybeAdd = catMaybes [ mField "tiebreaker" tb
170− , f "type" mmqt
190+ , mField "type" mmqt
171− , f "cutoff_frequency" cf
191+ , mField "cutoff_frequency" cf
172− , f "analyzer" analyzer
192+ , mField "analyzer" analyzer
173− , f "max_expansions" maxEx
193+ , mField "max_expansions" maxEx
174− , f "lenient" lenient ]
194+ , mField "lenient" lenient ]
175 conjoined = baseQuery ++ maybeAdd
195 conjoined = baseQuery ++ maybeAdd
176
196
197+
177instance ToJSON MultiMatchQueryType where
198instance ToJSON MultiMatchQueryType where
178 toJSON MultiMatchBestFields = "best_fields"
199 toJSON MultiMatchBestFields = "best_fields"
179 toJSON MultiMatchMostFields = "most_fields"
200 toJSON MultiMatchMostFields = "most_fields"
@@ -205,6 +226,8 @@ instance ToJSON Lenient
205instance ToJSON Boost
226instance ToJSON Boost
206instance ToJSON Version
227instance ToJSON Version
207instance ToJSON Tiebreaker
228instance ToJSON Tiebreaker
229+instance ToJSON MinimumMatch
230+instance ToJSON DisableCoord
208instance FromJSON Version
231instance FromJSON Version
209instance FromJSON IndexName
232instance FromJSON IndexName
210instance FromJSON MappingName
233instance FromJSON MappingName
tests/tests.hs+10
@@ -172,6 +172,16 @@ main = hspec $ do
172 myTweet <- searchTweet search
172 myTweet <- searchTweet search
173 myTweet `shouldBe` Right exampleTweet
173 myTweet `shouldBe` Right exampleTweet
174
174
175+ it "returns document for bool query" $ do
176+ _ <- insertData
177+ let innerQuery = QueryMatchQuery $
178+ mkMatchQuery (FieldName "user") (QueryString "bitemyapp")
179+ let query = QueryBoolQuery $
180+ mkBoolQuery (Just innerQuery) Nothing Nothing
181+ let search = mkSearch (Just query) Nothing
182+ myTweet <- searchTweet search
183+ myTweet `shouldBe` Right exampleTweet
184+
175 describe "sorting" $ do
185 describe "sorting" $ do
176 it "returns documents in the right order" $ do
186 it "returns documents in the right order" $ do
177 _ <- insertData
187 _ <- insertData