git.iko.soy/typeable/bloodhound
on master help sign in
MultiMatchQueryType implemented
aef9e08Chris Allen
Database/Bloodhound/Types.hs+13−3
@@ -11,6 +11,7 @@ module Database.Bloodhound.Types
11 , showText
11 , showText
12 , unpackId
12 , unpackId
13 , mkMatchQuery
13 , mkMatchQuery
14+ , mkMultiMatchQuery
14 , Version(..)
15 , Version(..)
15 , Status(..)
16 , Status(..)
16 , Existence(..)
17 , Existence(..)
@@ -95,6 +96,8 @@ module Database.Bloodhound.Types
95 , MaxExpansions(..)
96 , MaxExpansions(..)
96 , Lenient(..)
97 , Lenient(..)
97 , MatchQueryType(..)
98 , MatchQueryType(..)
99+ , MultiMatchQueryType(..)
100+ , Tiebreaker(..)
98 ) where
101 ) where
99
102
100import Data.Aeson
103import Data.Aeson
@@ -167,7 +170,7 @@ data EsResult a = EsResult { _index :: Text
167type Sort = [SortSpec]
170type Sort = [SortSpec]
168
171
169data SortSpec = DefaultSortSpec DefaultSort
172data SortSpec = DefaultSortSpec DefaultSort
170− | GeoDistanceSortSpec SortOrder GeoPoint deriving (Eq, Show)
173+ | GeoDistanceSortSpec SortOrder GeoPoint DistanceUnit deriving (Eq, Show)
171
174
172data DefaultSort =
175data DefaultSort =
173 DefaultSort { sortFieldName :: FieldName
176 DefaultSort { sortFieldName :: FieldName
@@ -216,7 +219,7 @@ newtype CutoffFrequency = CutoffFrequency Double deriving (Eq, Show, Ge
216newtype Analyzer = Analyzer Text deriving (Eq, Show, Generic)
219newtype Analyzer = Analyzer Text deriving (Eq, Show, Generic)
217newtype MaxExpansions = MaxExpansions Int deriving (Eq, Show, Generic)
220newtype MaxExpansions = MaxExpansions Int deriving (Eq, Show, Generic)
218newtype Lenient = Lenient Bool deriving (Eq, Show, Generic)
221newtype Lenient = Lenient Bool deriving (Eq, Show, Generic)
219−newtype Tiebreaker = Tiebreaker Double deriving (Eq, Show)
222+newtype Tiebreaker = Tiebreaker Double deriving (Eq, Show, Generic)
220newtype Boost = Boost Double deriving (Eq, Show, Generic)
223newtype Boost = Boost Double deriving (Eq, Show, Generic)
221newtype BoostTerms = BoostTerms Double deriving (Eq, Show)
224newtype BoostTerms = BoostTerms Double deriving (Eq, Show)
222newtype MinimumMatch = MinimumMatch Int deriving (Eq, Show)
225newtype MinimumMatch = MinimumMatch Int deriving (Eq, Show)
@@ -494,6 +497,10 @@ data MultiMatchQuery =
494 , multiMatchQueryMaxExpansions :: Maybe MaxExpansions
497 , multiMatchQueryMaxExpansions :: Maybe MaxExpansions
495 , multiMatchQueryLenient :: Maybe Lenient } deriving (Eq, Show)
498 , multiMatchQueryLenient :: Maybe Lenient } deriving (Eq, Show)
496
499
500+mkMultiMatchQuery :: [FieldName] -> QueryString -> MultiMatchQuery
501+mkMultiMatchQuery fields query =
502+ MultiMatchQuery fields query Or ZeroTermsNone Nothing Nothing Nothing Nothing Nothing Nothing
503+
497data MultiMatchQueryType = MultiMatchBestFields
504data MultiMatchQueryType = MultiMatchBestFields
498 | MultiMatchMostFields
505 | MultiMatchMostFields
499 | MultiMatchCrossFields
506 | MultiMatchCrossFields
@@ -666,9 +673,12 @@ data ShardResult =
666 , shardsSuccessful :: Int
673 , shardsSuccessful :: Int
667 , shardsFailed :: Int } deriving (Eq, Show, Generic)
674 , shardsFailed :: Int } deriving (Eq, Show, Generic)
668
675
669−-- defaultFieldMaybeJSON :: Text -> Maybe a ->
676+maybeJson ToJSON a => Text -> Maybe a -> [Data.Aeson.Types.Internal.Pair]
670maybeJson field (Just value) = [field .= toJSON value]
677maybeJson field (Just value) = [field .= toJSON value]
671maybeJson _ _ = []
678maybeJson _ _ = []
679+
680+maybeJsonF :: (ToJSON (f Value), ToJSON a, Functor f) =>
681+ Text -> Maybe (f a) -> [Data.Aeson.Types.Internal.Pair]
672maybeJsonF field (Just value) = [field .= fmap toJSON value]
682maybeJsonF field (Just value) = [field .= fmap toJSON value]
673maybeJsonF _ _ = []
683maybeJsonF _ _ = []
674
684
Database/Bloodhound/Types/Instances.hs+34
@@ -137,6 +137,8 @@ instance ToJSON Query where
137 toJSON (QueryMatchQuery matchQuery) =
137 toJSON (QueryMatchQuery matchQuery) =
138 object ["match" .= toJSON matchQuery]
138 object ["match" .= toJSON matchQuery]
139
139
140+ toJSON (QueryMultiMatchQuery multiMatchQuery) =
141+ object ["multi_match" .= toJSON multiMatchQuery]
140
142
141instance ToJSON MatchQuery where
143instance ToJSON MatchQuery where
142 toJSON (MatchQuery (FieldName fieldName)
144 toJSON (MatchQuery (FieldName fieldName)
@@ -155,6 +157,29 @@ instance ToJSON MatchQuery where
155 , f "max_expansions" maxExpansions
157 , f "max_expansions" maxExpansions
156 , f "lenient" lenient ]
158 , f "lenient" lenient ]
157
159
160+instance ToJSON MultiMatchQuery where
161+ toJSON (MultiMatchQuery fields (QueryString query) boolOp
162+ ztQ tb mmqt cf analyzer maxEx lenient) =
163+ object ["multi_match" .= object conjoined]
164+ where baseQuery = [ "fields" .= fmap toJSON fields
165+ , "query" .= query
166+ , "operator" .= toJSON boolOp
167+ , "zero_terms_query" .= toJSON ztQ ]
168+ f field = fmap ((field .=) . toJSON)
169+ maybeAdd = catMaybes [ f "tiebreaker" tb
170+ , f "type" mmqt
171+ , f "cutoff_frequency" cf
172+ , f "analyzer" analyzer
173+ , f "max_expansions" maxEx
174+ , f "lenient" lenient ]
175+ conjoined = baseQuery ++ maybeAdd
176+
177+instance ToJSON MultiMatchQueryType where
178+ toJSON MultiMatchBestFields = "best_fields"
179+ toJSON MultiMatchMostFields = "most_fields"
180+ toJSON MultiMatchCrossFields = "cross_fields"
181+ toJSON MultiMatchPhrase = "phrase"
182+ toJSON MultiMatchPhrasePrefix = "phrase_prefix"
158
183
159instance ToJSON BooleanOperator where
184instance ToJSON BooleanOperator where
160 toJSON And = String "and"
185 toJSON And = String "and"
@@ -168,6 +193,9 @@ instance ToJSON MatchQueryType where
168 toJSON MatchPhrase = "phrase"
193 toJSON MatchPhrase = "phrase"
169 toJSON MatchPhrasePrefix = "phrase_prefix"
194 toJSON MatchPhrasePrefix = "phrase_prefix"
170
195
196+instance ToJSON FieldName where
197+ toJSON (FieldName fieldName) = String fieldName
198+
171instance ToJSON ReplicaCount
199instance ToJSON ReplicaCount
172instance ToJSON ShardCount
200instance ToJSON ShardCount
173instance ToJSON CutoffFrequency
201instance ToJSON CutoffFrequency
@@ -176,6 +204,7 @@ instance ToJSON MaxExpansions
176instance ToJSON Lenient
204instance ToJSON Lenient
177instance ToJSON Boost
205instance ToJSON Boost
178instance ToJSON Version
206instance ToJSON Version
207+instance ToJSON Tiebreaker
179instance FromJSON Version
208instance FromJSON Version
180instance FromJSON IndexName
209instance FromJSON IndexName
181instance FromJSON MappingName
210instance FromJSON MappingName
@@ -233,6 +262,11 @@ instance ToJSON SortSpec where
233 lNestedFilter = maybeJson "nested_filter" nestedFilter
262 lNestedFilter = maybeJson "nested_filter" nestedFilter
234 merged = mconcat [base, lSortMode, lMissingSort, lNestedFilter]
263 merged = mconcat [base, lSortMode, lMissingSort, lNestedFilter]
235
264
265+ toJSON (GeoDistanceSortSpec sortOrder (GeoPoint (FieldName field) latLon) units) =
266+ object [ "unit" .= toJSON units
267+ , field .= toJSON latLon
268+ , "order" .= toJSON sortOrder ]
269+
236
270
237instance ToJSON SortOrder where
271instance ToJSON SortOrder where
238 toJSON Ascending = String "asc"
272 toJSON Ascending = String "asc"
tests/tests.hs+8
@@ -164,6 +164,14 @@ main = hspec $ do
164 myTweet <- searchTweet search
164 myTweet <- searchTweet search
165 myTweet `shouldBe` Right exampleTweet
165 myTweet `shouldBe` Right exampleTweet
166
166
167+ it "returns document for multi-match query" $ do
168+ _ <- insertData
169+ let fields = [FieldName "user", FieldName "message"]
170+ let query = QueryMultiMatchQuery $ mkMultiMatchQuery fields (QueryString "bitemyapp")
171+ let search = mkSearch (Just query) Nothing
172+ myTweet <- searchTweet search
173+ myTweet `shouldBe` Right exampleTweet
174+
167 describe "sorting" $ do
175 describe "sorting" $ do
168 it "returns documents in the right order" $ do
176 it "returns documents in the right order" $ do
169 _ <- insertData
177 _ <- insertData