git.iko.soy/typeable/bloodhound
on master help sign in
GeoPolygonFilter, positive and negative validation
commita800719f53d69f763db0c0d579d0abe0b948eb12 authorChris Allen <cma@bitemyapp.com> dateThu 10 Apr 2014, 19:54 (13 years ago) parent0c84e67
2 files changed+41−9
Database/Bloodhound/Client.hs+6 tests/tests.hs+35−9
Database/Bloodhound/Client.hs+6
@@ -374,6 +374,7 @@ data Filter = AndFilter [Filter] Cache
374374 | GeoBoundingBoxFilter GeoBoundingBoxConstraint GeoFilterType
375375 | GeoDistanceFilter GeoPoint Distance DistanceType OptimizeBbox Cache
376376 | GeoDistanceRangeFilter GeoPoint DistanceRange
377+ | GeoPolygonFilter FieldName [LatLon]
377378 deriving (Eq, Show)
378379
379380class Monoid a => Seminearring a where
@@ -431,6 +432,11 @@ instance ToJSON Filter where
431432 , "to" .= toJSON distanceTo
432433 , geoField .= toJSON latLon]]
433434
435+ toJSON (GeoPolygonFilter geoField latLons) =
436+ object ["geo_polygon" .=
437+ object [geoField .=
438+ object ["points" .= fmap toJSON latLons]]]
439+
434440instance ToJSON GeoPoint where
435441 toJSON (GeoPoint geoField latLon) =
436442 object [geoField .= toJSON latLon]
tests/tests.hs+35−9
@@ -15,11 +15,14 @@ import Network.HTTP.Conduit
1515import qualified Network.HTTP.Types.Status as NHTS
1616import Test.Hspec
1717
18−
1918testServer = Server "http://localhost:9200"
2019testIndex = "twitter"
2120testMapping = "tweet"
22−validateStatus resp expected = (NHTS.statusCode $ responseStatus resp) `shouldBe` (expected :: Int)
21+
22+validateStatus resp expected =
23+ (NHTS.statusCode $ responseStatus resp)
24+ `shouldBe` (expected :: Int)
25+
2326createExampleIndex = createIndex testServer defaultIndexSettings testIndex
2427deleteExampleIndex = deleteIndex testServer testIndex
2528
@@ -78,6 +81,7 @@ searchExpectNoResults search = do
7881
7982main :: IO ()
8083main = hspec $ do
84+
8185 describe "index create/delete API" $ do
8286 it "creates and then deletes the requested index" $ do
8387 -- priming state.
@@ -91,7 +95,8 @@ main = hspec $ do
9195 it "indexes, gets, and then deletes the generated document" $ do
9296 _ <- insertData
9397 docInserted <- getDocument testServer testIndex testMapping "1"
94− let newTweet = eitherDecode (responseBody docInserted) :: Either String (EsResult Tweet)
98+ let newTweet = eitherDecode
99+ (responseBody docInserted) :: Either String (EsResult Tweet)
95100 fmap _source newTweet `shouldBe` Right exampleTweet
96101
97102 describe "filtering API" $ do
@@ -103,13 +108,13 @@ main = hspec $ do
103108 myTweet <- searchTweet search
104109 myTweet `shouldBe` Right exampleTweet
105110
106− it "returns document for existential query" $ do
111+ it "returns document for existential filter" $ do
107112 _ <- insertData
108113 let search = Search Nothing (Just (ExistsFilter "user"))
109114 myTweet <- searchTweet search
110115 myTweet `shouldBe` Right exampleTweet
111116
112− it "returns document for geo boundingbox query" $ do
117+ it "returns document for geo boundingbox filter" $ do
113118 _ <- insertData
114119 let box = GeoBoundingBox (LatLon 40.73 (-74.1)) (LatLon 40.10 (-71.12))
115120 let bbConstraint = GeoBoundingBoxConstraint "tweet.location" box False
@@ -118,7 +123,7 @@ main = hspec $ do
118123 myTweet <- searchTweet search
119124 myTweet `shouldBe` Right exampleTweet
120125
121− it "doesn't return document for nonsensical boundingbox query" $ do
126+ it "doesn't return document for nonsensical boundingbox filter" $ do
122127 _ <- insertData
123128 let box = GeoBoundingBox (LatLon 0.73 (-4.1)) (LatLon 0.10 (-1.12))
124129 let bbConstraint = GeoBoundingBoxConstraint "tweet.location" box False
@@ -126,7 +131,7 @@ main = hspec $ do
126131 let search = Search Nothing (Just geoFilter)
127132 searchExpectNoResults search
128133
129− it "returns document for geo distance query" $ do
134+ it "returns document for geo distance filter" $ do
130135 _ <- insertData
131136 let geoPoint = GeoPoint "tweet.location" (LatLon 40.12 (-71.34))
132137 let distance = Distance 10.0 Miles
@@ -136,7 +141,7 @@ main = hspec $ do
136141 myTweet <- searchTweet search
137142 myTweet `shouldBe` Right exampleTweet
138143
139− it "returns document for geo distance range query" $ do
144+ it "returns document for geo distance range filter" $ do
140145 _ <- insertData
141146 let geoPoint = GeoPoint "tweet.location" (LatLon 40.12 (-71.34))
142147 let distanceRange = DistanceRange (Distance 0.0 Miles) (Distance 10.0 Miles)
@@ -145,10 +150,31 @@ main = hspec $ do
145150 myTweet <- searchTweet search
146151 myTweet `shouldBe` Right exampleTweet
147152
148− it "doesn't return document for wild geo distance range query" $ do
153+ it "doesn't return document for wild geo distance range filter" $ do
149154 _ <- insertData
150155 let geoPoint = GeoPoint "tweet.location" (LatLon 40.12 (-71.34))
151156 let distanceRange = DistanceRange (Distance 100.0 Miles) (Distance 1000.0 Miles)
152157 let geoFilter = GeoDistanceRangeFilter geoPoint distanceRange
153158 let search = Search Nothing (Just geoFilter)
154159 searchExpectNoResults search
160+
161+ it "returns document for geo polygon filter" $ do
162+ _ <- insertData
163+ let points = [LatLon 40.0 (-70.00),
164+ LatLon 40.0 (-72.00),
165+ LatLon 41.0 (-70.00),
166+ LatLon 41.0 (-72.00)]
167+ let geoFilter = GeoPolygonFilter "tweet.location" points
168+ let search = Search Nothing (Just geoFilter)
169+ myTweet <- searchTweet search
170+ myTweet `shouldBe` Right exampleTweet
171+
172+ it "doesn't return document for bad geo polygon filter" $ do
173+ _ <- insertData
174+ let points = [LatLon 40.0 (-70.00),
175+ LatLon 40.0 (-71.00),
176+ LatLon 41.0 (-70.00),
177+ LatLon 41.0 (-71.00)]
178+ let geoFilter = GeoPolygonFilter "tweet.location" points
179+ let search = Search Nothing (Just geoFilter)
180+ searchExpectNoResults search