mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-07-03 17:22:10 +00:00
DATAES-734 - Add Sort implementation that allows geo distance sorts.
Original PR: #382
This commit is contained in:
parent
bf13ed919f
commit
37f15853c0
@ -80,3 +80,17 @@ while (stream.hasNext()) {
|
|||||||
}
|
}
|
||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
||||||
|
[[elasticsearch.misc.sorts]]
|
||||||
|
== Sort options
|
||||||
|
|
||||||
|
In addition to the default sort options described <<repositories.paging-and-sorting>> Spring Data Elasticsearch has a `GeoDistanceOrder` class which can be used to have the result of a search operation ordered by geographical distance.
|
||||||
|
|
||||||
|
If the class to be retrieved has a `GeoPoint` property named _location_, the following `Sort` would sort the results by distance to the given point:
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
Sort.by(new GeoDistanceOrder("location", new GeoPoint(48.137154, 11.5761247)))
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
* Cleanup of the API in the `*Operations` interfaces, grouping and renaming methods so that they match the Elasticsearch API, deprecating the old methods, aligning with other Spring Data modules.
|
* Cleanup of the API in the `*Operations` interfaces, grouping and renaming methods so that they match the Elasticsearch API, deprecating the old methods, aligning with other Spring Data modules.
|
||||||
* Introduction of `SearchHit<T>` class to represent a found document together with the relevant result metadata for this document (i.e. _sortValues_).
|
* Introduction of `SearchHit<T>` class to represent a found document together with the relevant result metadata for this document (i.e. _sortValues_).
|
||||||
* Introduction of the `SearchHits<T>` class to represent a whole search result together with the metadata for the complete search result (i.e. _max_score_).
|
* Introduction of the `SearchHits<T>` class to represent a whole search result together with the metadata for the complete search result (i.e. _max_score_).
|
||||||
|
* Introduction of the `GeoDistanceOrder` class to be able to create sorting by geographical distance
|
||||||
|
|
||||||
[[new-features.3-2-0]]
|
[[new-features.3-2-0]]
|
||||||
== New in Spring Data Elasticsearch 3.2
|
== New in Spring Data Elasticsearch 3.2
|
||||||
|
@ -41,6 +41,8 @@ import org.elasticsearch.client.Client;
|
|||||||
import org.elasticsearch.client.Requests;
|
import org.elasticsearch.client.Requests;
|
||||||
import org.elasticsearch.client.indices.CreateIndexRequest;
|
import org.elasticsearch.client.indices.CreateIndexRequest;
|
||||||
import org.elasticsearch.client.indices.PutMappingRequest;
|
import org.elasticsearch.client.indices.PutMappingRequest;
|
||||||
|
import org.elasticsearch.common.geo.GeoDistance;
|
||||||
|
import org.elasticsearch.common.unit.DistanceUnit;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentType;
|
import org.elasticsearch.common.xcontent.XContentType;
|
||||||
@ -56,9 +58,11 @@ import org.elasticsearch.search.builder.SearchSourceBuilder;
|
|||||||
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
||||||
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
||||||
import org.elasticsearch.search.sort.FieldSortBuilder;
|
import org.elasticsearch.search.sort.FieldSortBuilder;
|
||||||
|
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
|
||||||
import org.elasticsearch.search.sort.ScoreSortBuilder;
|
import org.elasticsearch.search.sort.ScoreSortBuilder;
|
||||||
import org.elasticsearch.search.sort.SortBuilder;
|
import org.elasticsearch.search.sort.SortBuilder;
|
||||||
import org.elasticsearch.search.sort.SortBuilders;
|
import org.elasticsearch.search.sort.SortBuilders;
|
||||||
|
import org.elasticsearch.search.sort.SortMode;
|
||||||
import org.elasticsearch.search.sort.SortOrder;
|
import org.elasticsearch.search.sort.SortOrder;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.data.elasticsearch.ElasticsearchException;
|
import org.springframework.data.elasticsearch.ElasticsearchException;
|
||||||
@ -771,6 +775,18 @@ class RequestFactory {
|
|||||||
: null;
|
: null;
|
||||||
String fieldName = property != null ? property.getFieldName() : order.getProperty();
|
String fieldName = property != null ? property.getFieldName() : order.getProperty();
|
||||||
|
|
||||||
|
if (order instanceof GeoDistanceOrder) {
|
||||||
|
GeoDistanceOrder geoDistanceOrder = (GeoDistanceOrder) order;
|
||||||
|
|
||||||
|
GeoDistanceSortBuilder sort = SortBuilders.geoDistanceSort(fieldName, geoDistanceOrder.getGeoPoint().getLat(),
|
||||||
|
geoDistanceOrder.getGeoPoint().getLon());
|
||||||
|
|
||||||
|
sort.geoDistance(GeoDistance.fromString(geoDistanceOrder.getDistanceType().name()));
|
||||||
|
sort.ignoreUnmapped(geoDistanceOrder.getIgnoreUnmapped());
|
||||||
|
sort.sortMode(SortMode.fromString(geoDistanceOrder.getMode().name()));
|
||||||
|
sort.unit(DistanceUnit.fromString(geoDistanceOrder.getUnit()));
|
||||||
|
return sort;
|
||||||
|
} else {
|
||||||
FieldSortBuilder sort = SortBuilders //
|
FieldSortBuilder sort = SortBuilders //
|
||||||
.fieldSort(fieldName) //
|
.fieldSort(fieldName) //
|
||||||
.order(sortOrder);
|
.order(sortOrder);
|
||||||
@ -780,10 +796,10 @@ class RequestFactory {
|
|||||||
} else if (order.getNullHandling() == Sort.NullHandling.NULLS_LAST) {
|
} else if (order.getNullHandling() == Sort.NullHandling.NULLS_LAST) {
|
||||||
sort.missing("_last");
|
sort.missing("_last");
|
||||||
}
|
}
|
||||||
|
|
||||||
return sort;
|
return sort;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private QueryBuilder getQuery(Query query) {
|
private QueryBuilder getQuery(Query query) {
|
||||||
QueryBuilder elasticsearchQuery;
|
QueryBuilder elasticsearchQuery;
|
||||||
|
@ -22,6 +22,7 @@ import org.springframework.data.geo.Point;
|
|||||||
*
|
*
|
||||||
* @author Franck Marchand
|
* @author Franck Marchand
|
||||||
* @author Mohsin Husen
|
* @author Mohsin Husen
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
*/
|
*/
|
||||||
public class GeoPoint {
|
public class GeoPoint {
|
||||||
|
|
||||||
@ -58,6 +59,14 @@ public class GeoPoint {
|
|||||||
public static Point toPoint(GeoPoint point) {
|
public static Point toPoint(GeoPoint point) {
|
||||||
return new Point(point.getLat(), point.getLon());
|
return new Point(point.getLat(), point.getLon());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GeoPoint{" +
|
||||||
|
"lat=" + lat +
|
||||||
|
", lon=" + lon +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.data.elasticsearch.core.query;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link org.springframework.data.domain.Sort.Order} derived class to be able to define a _geo_distance order for a
|
||||||
|
* search.
|
||||||
|
*
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
public class GeoDistanceOrder extends Sort.Order {
|
||||||
|
|
||||||
|
private static final DistanceType DEFAULT_DISTANCE_TYPE = DistanceType.arc;
|
||||||
|
private static final Mode DEFAULT_MODE = Mode.min;
|
||||||
|
private static final String DEFAULT_UNIT = "m";
|
||||||
|
private static final Boolean DEFAULT_IGNORE_UNMAPPED = false;
|
||||||
|
|
||||||
|
private final GeoPoint geoPoint;
|
||||||
|
private final DistanceType distanceType;
|
||||||
|
private final Mode mode;
|
||||||
|
private final String unit;
|
||||||
|
private final Boolean ignoreUnmapped;
|
||||||
|
|
||||||
|
public GeoDistanceOrder(String property, GeoPoint geoPoint) {
|
||||||
|
this(property, geoPoint, Sort.Direction.ASC, DEFAULT_DISTANCE_TYPE, DEFAULT_MODE, DEFAULT_UNIT,
|
||||||
|
DEFAULT_IGNORE_UNMAPPED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GeoDistanceOrder(String property, GeoPoint geoPoint, Sort.Direction direction, DistanceType distanceType,
|
||||||
|
Mode mode, String unit, Boolean ignoreUnmapped) {
|
||||||
|
super(direction, property);
|
||||||
|
this.geoPoint = geoPoint;
|
||||||
|
this.distanceType = distanceType;
|
||||||
|
this.mode = mode;
|
||||||
|
this.unit = unit;
|
||||||
|
this.ignoreUnmapped = ignoreUnmapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GeoPoint getGeoPoint() {
|
||||||
|
return geoPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DistanceType getDistanceType() {
|
||||||
|
return distanceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mode getMode() {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUnit() {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getIgnoreUnmapped() {
|
||||||
|
return ignoreUnmapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GeoDistanceOrder withProperty(String property) {
|
||||||
|
return new GeoDistanceOrder(property, getGeoPoint(), getDirection(), getDistanceType(), getMode(), getUnit(),
|
||||||
|
getIgnoreUnmapped());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GeoDistanceOrder with(Sort.Direction direction) {
|
||||||
|
return new GeoDistanceOrder(getProperty(), getGeoPoint(), direction, getDistanceType(), getMode(), getUnit(),
|
||||||
|
getIgnoreUnmapped());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GeoDistanceOrder with(Sort.NullHandling nullHandling) {
|
||||||
|
throw new UnsupportedOperationException("null handling is not supported for _geo_distance sorts");
|
||||||
|
}
|
||||||
|
|
||||||
|
public GeoDistanceOrder with(DistanceType distanceType) {
|
||||||
|
return new GeoDistanceOrder(getProperty(), getGeoPoint(), getDirection(), distanceType, getMode(), getUnit(),
|
||||||
|
getIgnoreUnmapped());
|
||||||
|
}
|
||||||
|
|
||||||
|
public GeoDistanceOrder with(Mode mode) {
|
||||||
|
return new GeoDistanceOrder(getProperty(), getGeoPoint(), getDirection(), getDistanceType(), mode, getUnit(),
|
||||||
|
getIgnoreUnmapped());
|
||||||
|
}
|
||||||
|
|
||||||
|
public GeoDistanceOrder withUnit(String unit) {
|
||||||
|
return new GeoDistanceOrder(getProperty(), getGeoPoint(), getDirection(), getDistanceType(), getMode(), unit,
|
||||||
|
getIgnoreUnmapped());
|
||||||
|
}
|
||||||
|
|
||||||
|
public GeoDistanceOrder withIgnoreUnmapped(Boolean ignoreUnmapped) {
|
||||||
|
return new GeoDistanceOrder(getProperty(), getGeoPoint(), getDirection(), getDistanceType(), getMode(), getUnit(),
|
||||||
|
ignoreUnmapped);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "GeoDistanceOrder{" + "geoPoint=" + geoPoint + ", distanceType=" + distanceType + ", mode=" + mode
|
||||||
|
+ ", unit='" + unit + '\'' + ", ignoreUnmapped=" + ignoreUnmapped + "} " + super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DistanceType {
|
||||||
|
arc, plane
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Mode {
|
||||||
|
min, max, median, avg
|
||||||
|
}
|
||||||
|
}
|
@ -36,7 +36,7 @@ import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
|
|||||||
/**
|
/**
|
||||||
* Tests for the mapping of {@link CriteriaQuery} by a
|
* Tests for the mapping of {@link CriteriaQuery} by a
|
||||||
* {@link org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter}. In the same package as
|
* {@link org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter}. In the same package as
|
||||||
* {@link CriteriaQueryProcessor} as this is needed to get the String represenation to assert.
|
* {@link CriteriaQueryProcessor} as this is needed to get the String representation to assert.
|
||||||
*
|
*
|
||||||
* @author Peter-Josef Meisch
|
* @author Peter-Josef Meisch
|
||||||
*/
|
*/
|
||||||
@ -59,8 +59,8 @@ public class CriteriaQueryMappingTests {
|
|||||||
void shouldMapNamesAndConvertValuesInCriteriaQuery() throws JSONException {
|
void shouldMapNamesAndConvertValuesInCriteriaQuery() throws JSONException {
|
||||||
|
|
||||||
// use POJO properties and types in the query building
|
// use POJO properties and types in the query building
|
||||||
CriteriaQuery criteriaQuery = new CriteriaQuery(
|
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("birthDate")
|
||||||
new Criteria("birthDate").between(LocalDate.of(1989, 11, 9), LocalDate.of(1990, 11, 9)).or("birthDate").is(LocalDate.of(2019, 12, 28)));
|
.between(LocalDate.of(1989, 11, 9), LocalDate.of(1990, 11, 9)).or("birthDate").is(LocalDate.of(2019, 12, 28)));
|
||||||
|
|
||||||
// mapped field name and converted parameter
|
// mapped field name and converted parameter
|
||||||
String expected = '{' + //
|
String expected = '{' + //
|
||||||
|
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.data.elasticsearch.core;
|
||||||
|
|
||||||
|
import static org.skyscreamer.jsonassert.JSONAssert.*;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.core.convert.support.GenericConversionService;
|
||||||
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.Field;
|
||||||
|
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
||||||
|
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||||
|
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
||||||
|
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.Criteria;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.GeoDistanceOrder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Peter-Josef Meisch
|
||||||
|
*/
|
||||||
|
class RequestFactoryTest {
|
||||||
|
|
||||||
|
private static RequestFactory requestFactory;
|
||||||
|
private static MappingElasticsearchConverter converter;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
|
||||||
|
static void setUpAll() {
|
||||||
|
SimpleElasticsearchMappingContext mappingContext = new SimpleElasticsearchMappingContext();
|
||||||
|
mappingContext.setInitialEntitySet(Collections.singleton(Person.class));
|
||||||
|
mappingContext.afterPropertiesSet();
|
||||||
|
|
||||||
|
converter = new MappingElasticsearchConverter(mappingContext, new GenericConversionService());
|
||||||
|
converter.afterPropertiesSet();
|
||||||
|
|
||||||
|
requestFactory = new RequestFactory((converter));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // FPI-734
|
||||||
|
void shouldBuildSearchWithGeoSortSort() throws JSONException {
|
||||||
|
CriteriaQuery query = new CriteriaQuery(new Criteria("lastName").is("Smith"));
|
||||||
|
Sort sort = Sort.by(new GeoDistanceOrder("location", new GeoPoint(49.0, 8.4)));
|
||||||
|
query.addSort(sort);
|
||||||
|
|
||||||
|
converter.updateQuery(query, Person.class);
|
||||||
|
|
||||||
|
String expected = '{' + //
|
||||||
|
" \"query\": {" + //
|
||||||
|
" \"bool\": {" + //
|
||||||
|
" \"must\": [" + //
|
||||||
|
" {" + //
|
||||||
|
" \"query_string\": {" + //
|
||||||
|
" \"query\": \"Smith\"," + //
|
||||||
|
" \"fields\": [" + //
|
||||||
|
" \"first-name^1.0\"" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
" }" + //
|
||||||
|
" ]" + //
|
||||||
|
" }" + //
|
||||||
|
" }," + //
|
||||||
|
" \"sort\": [" + //
|
||||||
|
" {" + //
|
||||||
|
" \"_geo_distance\": {" + //
|
||||||
|
" \"current-location\": [" + //
|
||||||
|
" {" + //
|
||||||
|
" \"lat\": 49.0," + //
|
||||||
|
" \"lon\": 8.4" + //
|
||||||
|
" }" + //
|
||||||
|
" ]," + //
|
||||||
|
" \"unit\": \"m\"," + //
|
||||||
|
" \"distance_type\": \"arc\"," + //
|
||||||
|
" \"order\": \"asc\"," + //
|
||||||
|
" \"mode\": \"min\"," + //
|
||||||
|
" \"ignore_unmapped\": false" + //
|
||||||
|
" }" + //
|
||||||
|
" }" + //
|
||||||
|
" ]" + //
|
||||||
|
'}';
|
||||||
|
|
||||||
|
String searchRequest = requestFactory.searchRequest(query, Person.class, IndexCoordinates.of("persons")).source()
|
||||||
|
.toString();
|
||||||
|
|
||||||
|
assertEquals(expected, searchRequest, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Person {
|
||||||
|
@Id String id;
|
||||||
|
@Field(name = "last-name") String lastName;
|
||||||
|
@Field(name = "current-location") GeoPoint location;
|
||||||
|
}
|
||||||
|
}
|
@ -54,6 +54,7 @@ import org.springframework.data.elasticsearch.core.SearchHit;
|
|||||||
import org.springframework.data.elasticsearch.core.SearchHits;
|
import org.springframework.data.elasticsearch.core.SearchHits;
|
||||||
import org.springframework.data.elasticsearch.core.geo.GeoBox;
|
import org.springframework.data.elasticsearch.core.geo.GeoBox;
|
||||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||||
|
import org.springframework.data.elasticsearch.core.query.GeoDistanceOrder;
|
||||||
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
|
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
|
||||||
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||||
import org.springframework.data.elasticsearch.utils.IndexInitializer;
|
import org.springframework.data.elasticsearch.utils.IndexInitializer;
|
||||||
@ -1441,6 +1442,40 @@ public abstract class CustomMethodRepositoryBaseTests {
|
|||||||
assertThat(searchHit.getHighlightField("type")).hasSize(1).contains("<em>abc</em>");
|
assertThat(searchHit.getHighlightField("type")).hasSize(1).contains("<em>abc</em>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test // DATAES-734
|
||||||
|
void shouldUseGeoSortParameter() {
|
||||||
|
GeoPoint munich = new GeoPoint(48.137154, 11.5761247);
|
||||||
|
GeoPoint berlin = new GeoPoint(52.520008, 13.404954);
|
||||||
|
GeoPoint vienna = new GeoPoint(48.20849, 16.37208);
|
||||||
|
GeoPoint oslo = new GeoPoint(59.9127, 10.7461);
|
||||||
|
|
||||||
|
List<SampleEntity> entities = new ArrayList<>();
|
||||||
|
|
||||||
|
SampleEntity entity1 = new SampleEntity();
|
||||||
|
entity1.setId("berlin");
|
||||||
|
entity1.setLocation(berlin);
|
||||||
|
entities.add(entity1);
|
||||||
|
|
||||||
|
SampleEntity entity2 = new SampleEntity();
|
||||||
|
entity2.setId("vienna");
|
||||||
|
entity2.setLocation(vienna);
|
||||||
|
entities.add(entity2);
|
||||||
|
|
||||||
|
SampleEntity entity3 = new SampleEntity();
|
||||||
|
entity3.setId("oslo");
|
||||||
|
entity3.setLocation(oslo);
|
||||||
|
entities.add(entity3);
|
||||||
|
|
||||||
|
repository.saveAll(entities);
|
||||||
|
|
||||||
|
SearchHits<SampleEntity> searchHits = repository.searchBy(Sort.by(new GeoDistanceOrder("location", munich)));
|
||||||
|
|
||||||
|
assertThat(searchHits.getTotalHits()).isEqualTo(3);
|
||||||
|
assertThat(searchHits.getSearchHit(0).getId()).isEqualTo("vienna");
|
||||||
|
assertThat(searchHits.getSearchHit(1).getId()).isEqualTo("berlin");
|
||||||
|
assertThat(searchHits.getSearchHit(2).getId()).isEqualTo("oslo");
|
||||||
|
}
|
||||||
|
|
||||||
private List<SampleEntity> createSampleEntities(String type, int numberOfEntities) {
|
private List<SampleEntity> createSampleEntities(String type, int numberOfEntities) {
|
||||||
|
|
||||||
List<SampleEntity> entities = new ArrayList<>();
|
List<SampleEntity> entities = new ArrayList<>();
|
||||||
@ -1588,6 +1623,7 @@ public abstract class CustomMethodRepositoryBaseTests {
|
|||||||
|
|
||||||
Stream<SearchHit<SampleEntity>> readByMessage(String message);
|
Stream<SearchHit<SampleEntity>> readByMessage(String message);
|
||||||
|
|
||||||
|
SearchHits<SampleEntity> searchBy(Sort sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user