mysql 空间函数 vs ES GEO hash
mysql 空间函数 vs ES GEO hash
很多时候我们都可以看到 根据自己点位 查看门店到和自己最近的距离,这个时候 geo hash ,距离排序 就排上用处了。数据量小简单一点就 mysql ,数据量大推荐 就用 es.
mysql
SELECT st_distance_sphere(POINT(121.590347, 31.388094),POINT(longitude,latitude))/1000 AS distant,s.* FROM table_name s ORDER BY distant ;
es
Pageable pageable = PageRequest.of(0, 10);
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("filmId", 1L);
TermQueryBuilder termQuery = QueryBuilders.termQuery("date", "2023-03-24");
// 以某点为中心,搜索指定范围
Double latitude = new BigDecimal(30.58203).doubleValue();
Double longitude = new BigDecimal(114.02919).doubleValue();
GeoDistanceQueryBuilder distanceQueryBuilder = new GeoDistanceQueryBuilder("location");
distanceQueryBuilder.point(latitude, longitude);
boolQueryBuilder.must(termQueryBuilder);
boolQueryBuilder.must(termQuery);
String distance = "500000";
// 定义查询单位:公里
distanceQueryBuilder.distance(distance, DistanceUnit.KILOMETERS);
boolQueryBuilder.filter(distanceQueryBuilder);
// 按距离升序
GeoDistanceSortBuilder distanceSortBuilder =
new GeoDistanceSortBuilder("location", latitude, longitude);
distanceSortBuilder.unit(DistanceUnit.KILOMETERS);
distanceSortBuilder.order(SortOrder.ASC);
NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
.withQuery(boolQueryBuilder)
.withPageable(pageable)
.withSorts(distanceSortBuilder)
.build();
SearchHits<Class> page = elasticsearchRestTemplate.search(nativeSearchQuery, Class.class, IndexCoordinates.of("cinema"));
page.forEach(emp -> {
double dist = GeoDistance.ARC.calculate(latitude, longitude, emp.getContent().getLocation().getLat(),emp.getContent().getLocation().getLon(), DistanceUnit.KILOMETERS);
log.info(emp+"; 距离我 : "+dist+"公里");
});
总结:
用合适的技术 解决合适的问题,学会取舍 ,没有完美 只有适合。
elk