项目简介:
- 框架:springboot
- 数据库:mysql
- 持久层:jpa
- 搜索引擎:elasticsearch
1 地理位置保存到mysql
mysql存储point类型地理位置,如何用jpa保存地理位置到mysql,请看https://www.jianshu.com/p/0a861e931531
2 保存到es
由于我们需要用es搜索,所以也需要将数据保存到es,地理位置保存有点问题,因为上面jpa保存到mysql的实体类里的point类型不适用es,所以需要自定义转换器https://docs.spring.io/spring-data/elasticsearch/docs/4.0.3.RELEASE/reference/html/#elasticsearch.mapping.meta-model.conversions
package com.xzp.config;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import org.elasticsearch.client.RestHighLevelClient;
import org.geolatte.geom.G2D;
import org.geolatte.geom.Point;
import org.geolatte.geom.crs.CrsRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchCustomConversions;
import org.springframework.util.NumberUtils;
/**
* @author xzp
* @date 2020-08-12 13:07:06
*/
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
@Autowired
@Qualifier("elasticsearchRestHighLevelClient")
private RestHighLevelClient elasticsearchRestHighLevelClient;
@Override
public RestHighLevelClient elasticsearchClient() {
return elasticsearchRestHighLevelClient;
}
// 主要看下面的代码
@Bean
@Override
public ElasticsearchCustomConversions elasticsearchCustomConversions() {
return new ElasticsearchCustomConversions(Arrays.asList(PointToMapConverter.INSTANCE,MapToPointConverter.INSTANCE));
}
@WritingConverter
@SuppressWarnings("rawtypes")
enum PointToMapConverter implements Converter<Point, Map<String, Object>> {
INSTANCE;
@Override
public Map<String, Object> convert(Point source) {
if (source == null)
return null;
LinkedHashMap<String, Object> target = new LinkedHashMap<>();
target.put("lat", source.getPosition().getCoordinate(1));
target.put("lon", source.getPosition().getCoordinate(0));
return target;
}
}
@ReadingConverter
@SuppressWarnings({ "rawtypes", "unchecked" })
enum MapToPointConverter implements Converter<Map<String, Object>, Point> {
INSTANCE;
@Override
public Point convert(Map<String, Object> source) {
Double lat = NumberUtils.convertNumberToTargetClass((Number) source.get("lat"), Double.class);
Double lon = NumberUtils.convertNumberToTargetClass((Number) source.get("lon"), Double.class);
return new Point(new G2D(lon, lat),CrsRegistry.getCoordinateReferenceSystemForEPSG(4326, null));
}
}
// no special bean creation needed
}
参考的是elasticsearch自带的GeoConverters的写法
/*
* Copyright 2019-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.convert;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.geo.Point;
import org.springframework.util.NumberUtils;
/**
* Set of {@link Converter converters} specific to Elasticsearch Geo types.
*
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @since 3.2
*/
class GeoConverters {
static Collection<Converter<?, ?>> getConvertersToRegister() {
return Arrays.asList(PointToMapConverter.INSTANCE, MapToPointConverter.INSTANCE, GeoPointToMapConverter.INSTANCE,
MapToGeoPointConverter.INSTANCE);
}
/**
* {@link Converter} to write a {@link Point} to {@link Map} using {@code lat/long} properties.
*/
@WritingConverter
enum PointToMapConverter implements Converter<Point, Map<String, Object>> {
INSTANCE;
@Override
public Map<String, Object> convert(Point source) {
Map<String, Object> target = new LinkedHashMap<>();
target.put("lat", source.getX());
target.put("lon", source.getY());
return target;
}
}
/**
* {@link Converter} to write a {@link GeoPoint} to {@link Map} using {@code lat/long} properties.
*/
@WritingConverter
enum GeoPointToMapConverter implements Converter<GeoPoint, Map<String, Object>> {
INSTANCE;
@Override
public Map<String, Object> convert(GeoPoint source) {
Map<String, Object> target = new LinkedHashMap<>();
target.put("lat", source.getLat());
target.put("lon", source.getLon());
return target;
}
}
/**
* {@link Converter} to read a {@link Point} from {@link Map} using {@code lat/long} properties.
*/
@ReadingConverter
enum MapToPointConverter implements Converter<Map<String, Object>, Point> {
INSTANCE;
@Override
public Point convert(Map<String, Object> source) {
Double x = NumberUtils.convertNumberToTargetClass((Number) source.get("lat"), Double.class);
Double y = NumberUtils.convertNumberToTargetClass((Number) source.get("lon"), Double.class);
return new Point(x, y);
}
}
/**
* {@link Converter} to read a {@link GeoPoint} from {@link Map} using {@code lat/long} properties.
*/
@ReadingConverter
enum MapToGeoPointConverter implements Converter<Map<String, Object>, GeoPoint> {
INSTANCE;
@Override
public GeoPoint convert(Map<String, Object> source) {
Double x = NumberUtils.convertNumberToTargetClass((Number) source.get("lat"), Double.class);
Double y = NumberUtils.convertNumberToTargetClass((Number) source.get("lon"), Double.class);
return new GeoPoint(x, y);
}
}
}
网友评论