Я выполняю геопространственный поиск с использованием Spring Data Elasticsearch - в основном, нахожу все объекты в пределах заданного радиуса на основе координат широты / долготы, хранящихся в ES (@GeoPointField). Ранее мы использовали транспортный клиент, и все работало нормально. Недавно мы перешли на использование последней версии Spring Data Reactive Elasticsearch (Spring Boot Data ElasticSearch Starter 2.2.0) и заметили, что наша сортировка больше не применяется. Т.е. ближайшие места по расстоянию больше не находятся в начале списка результатов. Логика с QueryBuilder и SearchQuery не изменилась, вместо этого мы сейчас просто используем ReactiveElasticsearchTemplate и возвращаем Flux .
Наша логика получения ответа теперь выглядит примерно так:
//TODO this does not sort the results properly based on distance as it previously did using transport client
public Mono<LocationResultDTO> findLocationsNearby(Location fromLocation, Integer distance, BusinessUnit businessUnit) {
if (distance == null || distance == 0) {
distance = defaultDistance;
}
GeoPoint point = new GeoPoint(fromLocation.getLatitude(), fromLocation.getLongitude());
// this is the actual query to find everything from a certain point
QueryBuilder query = geoDistanceQuery("geoLocationAsString")
.point(point)
.distance(distance, DistanceUnit.KILOMETERS);
// 1) do not include the input store
// 2) only use selling locations! - MFD-4765
// 3) only find stores in the same business unit
QueryBuilder filter = boolQuery()
.mustNot(QueryBuilders.matchQuery("storeNumber", fromLocation.getStoreNumber()))
.must(QueryBuilders.matchQuery("sellingLocation", "Y"))
.must(QueryBuilders.matchQuery("businessUnit", businessUnit));
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(query)
.withFilter(filter)
.withSort(SortBuilders.geoDistanceSort("geoLocationAsString", point) // this sorts by distance
.order(SortOrder.ASC)).build();
// get the Flux from repository
Flux<Location> locationFlux = reactiveElasticsearchTemplate.find(searchQuery, Location.class);
// map to a Mono List - should this preserve order of the stream?
Mono<List<Location>> locationList = locationFlux.flatMapSequential(location -> Mono.just(location)).collectList();
// map to our DTO
return locationList.flatMap(locations -> Mono.just(LocationResultDTO.builder().result(locations).build()));
Мы довольно плохо знакомы с использованием реактивных идиом и задаемся вопросом, правильно ли мы отображаем результирующий поток из реактивного шаблона? Должен ли результирующий поток из реактивного шаблона поддерживать порядок сортировки?