Skip to content

Commit

Permalink
test: add geoShape examples
Browse files Browse the repository at this point in the history
  • Loading branch information
jbl428 committed Sep 28, 2023
1 parent 68da804 commit ba493f7
Show file tree
Hide file tree
Showing 2 changed files with 203 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
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.aggregation.search.GeoShapeRelation
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.GeoJsonPolygon
import org.springframework.stereotype.Repository

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

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

/**
* @see <a href="https://www.mongodb.com/docs/atlas/atlas-search/geoShape/#disjoint-example">Disjoint Example</a>
*/
fun findByDisjoint(): AggregationResults<NameAndAddress> {
val aggregation = aggregation {
search {
geoShape {
relation = GeoShapeRelation.DISJOINT
geometry(
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
searchScore()
}
}

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

/**
* @see <a href="https://www.mongodb.com/docs/atlas/atlas-search/geoShape/#intersects-example">Intersects Example</a>
*/
fun findByIntersects(): AggregationResults<NameAndAddress> {
val aggregation = aggregation {
search {
geoShape {
relation = GeoShapeRelation.INTERSECTS
geometry(
GeoJsonMultiPolygon(
listOf(
GeoJsonPolygon(
Point(2.16942, 41.40082),
Point(2.17963, 41.40087),
Point(2.18146, 41.39716),
Point(2.15533, 41.40686),
Point(2.14596, 41.38475),
Point(2.17519, 41.41035),
Point(2.16942, 41.40082),
),
GeoJsonPolygon(
Point(2.16365, 41.39416),
Point(2.16963, 41.39726),
Point(2.15395, 41.38005),
Point(2.17935, 41.43038),
Point(2.16365, 41.39416),
),
),
),
)
path(ListingsAndReviews::address..ListingsAndReviewsAddress::location)
}
}

// TODO: add $limit stage

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

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

/**
* @see <a href="https://www.mongodb.com/docs/atlas/atlas-search/geoShape/#within-example">Within Example</a>
*/
fun findByWithin(): AggregationResults<NameAndAddress> {
val aggregation = aggregation {
search {
geoShape {
relation = GeoShapeRelation.WITHIN
geometry(
GeoJsonPolygon(
Point(-74.3994140625, 40.5305017757),
Point(-74.7290039063, 40.5805846641),
Point(-74.7729492188, 40.9467136651),
Point(-74.0698242188, 41.1290213475),
Point(-73.65234375, 40.9964840144),
Point(-72.6416015625, 40.9467136651),
Point(-72.3559570313, 40.7971774152),
Point(-74.3994140625, 40.5305017757),
),
)
path(ListingsAndReviews::address..ListingsAndReviewsAddress::location)
}
}

// TODO: add $limit stage

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

return mongoTemplate.aggregate<ListingsAndReviews, NameAndAddress>(aggregation)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
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 GeoShapeSearchRepositoryTest(
private val geoShapeSearchRepository: GeoShapeSearchRepository,
) : FreeSpec({

"findByDisjoint" {
// when
val result = geoShapeSearchRepository.findByDisjoint()

// then
result.mappedResults.take(3).map { it.name } shouldBe listOf(
"Ribeira Charming Duplex",
"Horto flat with small garden",
"Private Room in Bushwick",
)
result.mappedResults.take(3).map { it.address.location.coordinates } shouldBe listOf(
listOf(-8.61308, 41.1413),
listOf(-43.23074991429229, -22.966253551739655),
listOf(-73.93615, 40.69791),
)
}

"findByIntersects" {
// when
val result = geoShapeSearchRepository.findByIntersects()

// then
result.mappedResults.take(3).map { it.name } shouldBe listOf(
"Cozy bedroom Sagrada Familia",
"",
"SPACIOUS RAMBLA CATALUÑA",
)
result.mappedResults.take(3).map { it.address.location.coordinates } shouldBe listOf(
listOf(2.17963, 41.40087),
listOf(2.15759, 41.40349),
listOf(2.15255, 41.39193),
)
}

"findByWithin" {
// when
val result = geoShapeSearchRepository.findByWithin()

// then
result.mappedResults.take(3).map { it.name } shouldBe listOf(
"Private Room in Bushwick",
"New York City - Upper West Side Apt",
"Deluxe Loft Suite",
)
result.mappedResults.take(3).map { it.address.location.coordinates } shouldBe listOf(
listOf(-73.93615, 40.69791),
listOf(-73.96523, 40.79962),
listOf(-73.94472, 40.72778),
)
}
})

0 comments on commit ba493f7

Please sign in to comment.