Skip to content

Commit

Permalink
test: add geoWithin examples
Browse files Browse the repository at this point in the history
  • Loading branch information
jbl428 committed Sep 28, 2023
1 parent fe3b145 commit 52b2eab
Show file tree
Hide file tree
Showing 2 changed files with 234 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package com.github.inflab.example.spring.data.mongodb.repository

import com.github.inflab.example.spring.data.mongodb.entity.airbnb.ListingsAndReviews
import com.github.inflab.example.spring.data.mongodb.entity.airbnb.ListingsAndReviewsAddress
import com.github.inflab.spring.data.mongodb.core.aggregation.aggregation
import com.github.inflab.spring.data.mongodb.core.mapping.rangeTo
import org.springframework.data.geo.Point
import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.data.mongodb.core.aggregate
import org.springframework.data.mongodb.core.aggregation.AggregationResults
import org.springframework.data.mongodb.core.geo.GeoJsonMultiPolygon
import org.springframework.data.mongodb.core.geo.GeoJsonPoint
import org.springframework.data.mongodb.core.geo.GeoJsonPolygon
import org.springframework.stereotype.Repository

@Repository
class GeoWithinSearchRepository(
private val mongoTemplate: MongoTemplate,
) {

data class NameAndAddress(val name: String, val address: ListingsAndReviewsAddress)

/**
* @see <a href="https://www.mongodb.com/docs/atlas/atlas-search/geoWithin/#box-example">Box Example</a>
*/
fun findByBox(): AggregationResults<NameAndAddress> {
val aggregation = aggregation {
search {
geoWithin {
path(ListingsAndReviews::address..ListingsAndReviewsAddress::location)
box(
bottomLeft = GeoJsonPoint(112.467, -55.050),
topRight = GeoJsonPoint(168.000, -9.133),
)
}
}

// TODO: add $limit stage

project {
excludeId()
+ListingsAndReviews::name
+ListingsAndReviews::address
}
}

return mongoTemplate.aggregate<ListingsAndReviews, NameAndAddress>(aggregation)
}

/**
* @see <a href="https://www.mongodb.com/docs/atlas/atlas-search/geoWithin/#circle-example">Circle Example</a>
*/
fun findByCircle(): AggregationResults<NameAndAddress> {
val aggregation = aggregation {
search {
geoWithin {
circle(
center = GeoJsonPoint(-73.54, 45.54),
radius = 1600,
)
path(ListingsAndReviews::address..ListingsAndReviewsAddress::location)
}
}

// TODO: add $limit stage

project {
excludeId()
+ListingsAndReviews::name
+ListingsAndReviews::address
}
}

return mongoTemplate.aggregate<ListingsAndReviews, NameAndAddress>(aggregation)
}

/**
* @see <a href="https://www.mongodb.com/docs/atlas/atlas-search/geoWithin/#geometry-examples">Polygon Example</a>
*/
fun findByPolygon(): AggregationResults<NameAndAddress> {
val aggregation = aggregation {
search {
geoWithin {
polygon(
GeoJsonPolygon(
Point(-161.323242, 22.512557),
Point(-152.446289, 22.065278),
Point(-156.09375, 17.811456),
Point(-161.323242, 22.512557),
),
)
path(ListingsAndReviews::address..ListingsAndReviewsAddress::location)
}
}

// TODO: add $limit stage

project {
excludeId()
+ListingsAndReviews::name
+ListingsAndReviews::address
}
}

return mongoTemplate.aggregate<ListingsAndReviews, NameAndAddress>(aggregation)
}

/**
* @see <a href="https://www.mongodb.com/docs/atlas/atlas-search/geoWithin/#geometry-examples">MultiPolygon Example</a>
*/
fun findByMultiPolygon(): AggregationResults<NameAndAddress> {
val aggregation = aggregation {
search {
geoWithin {
multiPolygon(
GeoJsonMultiPolygon(
listOf(
GeoJsonPolygon(
Point(-157.8412413882, 21.2882235819),
Point(-157.8607925468, 21.2962046205),
Point(-157.8646640634, 21.3077019651),
Point(-157.862776699, 21.320776283),
Point(-157.8341758705, 21.3133826738),
Point(-157.8349985678, 21.3000822569),
Point(-157.8412413882, 21.2882235819),
),
GeoJsonPolygon(
Point(-157.852898124, 21.301208833),
Point(-157.8580050499, 21.3050871833),
Point(-157.8587346108, 21.3098050385),
Point(-157.8508811028, 21.3119240258),
Point(-157.8454308541, 21.30396767),
Point(-157.852898124, 21.301208833),
),
),
),
)
path(ListingsAndReviews::address..ListingsAndReviewsAddress::location)
}
}

// TODO: add $limit stage

project {
excludeId()
+ListingsAndReviews::name
+ListingsAndReviews::address
}
}

return mongoTemplate.aggregate<ListingsAndReviews, NameAndAddress>(aggregation)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.github.inflab.example.spring.data.mongodb.repository

import com.github.inflab.example.spring.data.mongodb.extension.AtlasTest
import io.kotest.core.annotation.Ignored
import io.kotest.core.spec.style.FreeSpec
import io.kotest.matchers.shouldBe

@Ignored
@AtlasTest(database = "sample_airbnb")
internal class GeoWithinSearchRepositoryTest(
private val geoWithinSearchRepository: GeoWithinSearchRepository,
) : FreeSpec({

"findByBox" {
// when
val result = geoWithinSearchRepository.findByBox()

// then
result.mappedResults.take(3).map { it.name } shouldBe listOf(
"Surry Hills Studio - Your Perfect Base in Sydney",
"Sydney Hyde Park City Apartment (checkin from 6am)",
"THE Place to See Sydney's FIREWORKS",
)
result.mappedResults.take(3).map { it.address.location.coordinates } shouldBe listOf(
listOf(151.21554, -33.88029),
listOf(151.21346, -33.87603),
listOf(151.17956, -33.86296),
)
}

"findByCircle" {
// when
val result = geoWithinSearchRepository.findByCircle()

// then
result.mappedResults.take(3).map { it.name } shouldBe listOf(
"Ligne verte - à 15 min de métro du centre ville.",
"Belle chambre à côté Metro Papineau",
"L'IDÉAL, ( à 2 min du métro Pie-IX ).",
)
result.mappedResults.take(3).map { it.address.location.coordinates } shouldBe listOf(
listOf(-73.54949, 45.54548),
listOf(-73.54985, 45.52797),
listOf(-73.55208, 45.55157),
)
}

"findByPolygon" {
// when
val result = geoWithinSearchRepository.findByPolygon()

// then
result.mappedResults.take(3).map { it.name } shouldBe listOf(
"Ocean View Waikiki Marina w/prkg",
"Kailua-Kona, Kona Coast II 2b condo",
"LAHAINA, MAUI! RESORT/CONDO BEACHFRONT!! SLEEPS 4!",
)
result.mappedResults.take(3).map { it.address.location.coordinates } shouldBe listOf(
listOf(-157.83919, 21.28634),
listOf(-155.96445, 19.5702),
listOf(-156.68012, 20.96996),
)
}

"findByMultiPolygon" {
// when
val result = geoWithinSearchRepository.findByMultiPolygon()

// then
result.mappedResults.take(3).map { it.name } shouldBe listOf(
"Heart of Honolulu, 2BD gem! Free Garage Parking!",
"Private Studio closed to town w/ compact parking",
"Comfortable Room (2) at Affordable Rates",
)
result.mappedResults.take(3).map { it.address.location.coordinates } shouldBe listOf(
listOf(-157.84343, 21.30852),
listOf(-157.85228, 21.31184),
listOf(-157.83889, 21.29776),
)
}
})

0 comments on commit 52b2eab

Please sign in to comment.