由于数据未知,所以无法使用bean的方式,只能使用map来操作。
首先创建客户端
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyESConfig {
@Bean
public TransportClient client() throws UnknownHostException {
TransportAddress node=new TransportAddress(InetAddress.getByName("127.0.0.1“), 9300);
Settings setting=Settings.builder()
.put("cluster.name","my-application")
.build();
TransportClient client=new PreBuiltTransportClient(setting);
client.addTransportAddress(node);
return client;
}
}
WKT工具类
import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
import org.geotools.geometry.jts.JTSFactoryFinder;
public class WKTUtil {
private final static WKTReader wktReader = new WKTReader(JTSFactoryFinder.getGeometryFactory());
/**
* 将WKT文本字符串转换为ES中的GeoShape字符串格式
* @param wkt
* @return
* @throws ParseException
*/
public static String getESGeoTextFromWkt(String wkt) throws ParseException {
String result = null;
Geometry geom = wktReader.read(wkt);
String type = geom.getClass().getSimpleName().toLowerCase();
Point point;
MultiPoint multiPoint;
LineString lineString;
MultiLineString multiLineString;
Polygon polygon;
MultiPolygon multiPolygon;
if(type.equals("point")){
point = (Point) geom;
result = getESPointText(point);
}else if(type.equals("linestring")){
lineString = (LineString) geom;
result = getESLineStringText(lineString);
}else if(type.equals("polygon")){
polygon = (Polygon) geom;
result = getESPolygonText(polygon);
}else if(type.equals("multipoint")){
multiPoint = (MultiPoint) geom;
result = getESMultiPointText(multiPoint);
}else if(type.equals("multilinestring")){
multiLineString = (MultiLineString) geom;
result = getESMultiLineStringText(multiLineString);
}else if(type.equals("multipolygon")){
multiPolygon = (MultiPolygon) geom;
result = getESMultiPolygonText(multiPolygon);
}
return result;
}
/**
* 通过MultiPolygon对象拼接中括号表示的字符串
* @param multiPolygon
* @return
*/
private static String getESMultiPolygonText(MultiPolygon multiPolygon) throws ParseException {
Polygon polygon;
int num = multiPolygon.getNumGeometries();
StringBuffer sb = new StringBuffer("[");
for(int i = 0; i < num; i++){
polygon = (Polygon) multiPolygon.getGeometryN(i);
sb.append(getESPolygonText(polygon)+",");
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
/**
* 通过MultiLineString对象拼接中括号表示的字符串
* @param multiLineString
* @return
*/
private static String getESMultiLineStringText(MultiLineString multiLineString) {
LineString lineString;
int num = multiLineString.getNumGeometries();
StringBuffer sb = new StringBuffer("[");
for(int i = 0; i < num; i++){
lineString = (LineString) multiLineString.getGeometryN(i);
sb.append(getESLineStringText(lineString)+",");
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
/**
* 通过MultiPoint对象拼接中括号表示的字符串
* @param multiPoint
* @return
*/
private static String getESMultiPointText(MultiPoint multiPoint) {
Point point;
int num = multiPoint.getNumGeometries();
StringBuffer sb = new StringBuffer("[");
for(int i = 0; i < num; i++){
point = (Point) multiPoint.getGeometryN(i);
sb.append(getESPointText(point)+",");
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
/**
* 通过Polygon对象拼接中括号表示的字符串
* @param polygon
* @return
* @throws ParseException
*/
private static String getESPolygonText(Polygon polygon){
String result;
/**
* 内部闭合环形的数量
*/
int num = polygon.getNumInteriorRing();
if(num > 0){
StringBuffer sb = new StringBuffer("["+getESLineStringText(polygon.getExteriorRing())+",");
for(int i = 0; i < num; i++){
sb.append(getESLineStringText(polygon.getInteriorRingN(i))+",");
}
sb.setCharAt(sb.length() - 1, ']');
result = sb.toString();
}else{
result = "["+getESLineStringText(polygon.getExteriorRing())+"]";
}
return result;
}
/**
* 通过LineString对象拼接中括号表示的字符串
* @param lineString
* @return
*/
public static String getESLineStringText(LineString lineString){
Coordinate[] corrds = lineString.getCoordinates();
StringBuffer sb = new StringBuffer("[");
for(Coordinate corrd : corrds) {
sb.append(getCoordinateText(corrd)+",");
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
/**
* 通过Point对象拼接中括号表示的字符串
* @param point
* @return
*/
public static String getESPointText(Point point){
return getCoordinateText(point.getCoordinate());
}
/**
* 通过Coordinate对象拼接中括号表示的字符串
* @param coord
* @return
*/
public static String getCoordinateText(Coordinate coord) {
return "["+coord.x+","+coord.y+"]";
}
}
ES工具类
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.client.AdminClient;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
public class ESUtil {
/**
* 获取mapping
* @param map
* @param id
* @return
* @throws IOException
* @throws ParseException
*/
public static XContentBuilder getMapping(Map<String, Object> map, String id) throws IOException, ParseException {
// 字段mapping
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject();
mapping.field("id", id);
// 几何类型
if (map.get("wkt") != null) {
String polygon = map.get("wkt").toString();
mapping.field("wkt", getConversionData(polygon));
}
// 循环添加字段和值
for (String key : map.keySet()) {
// 排除要不需要的字段
if (key.equals("indexName") || key.equals("id") || key.equals("wkt")) {
continue;
}
mapping.field(key, map.get(key));
}
mapping.endObject();
return mapping;
}
/**
* 获取json数据
* @param map
* @param id
* @return
* @throws ParseException
*/
public static String getJsonData(Map<String, Object> map, String id) throws ParseException {
String json = "{";
json += "\"id\":\"" + id + "\",";
if (map.get("id") != null) {
map.remove("id");
}
if (map.get("wkt") != null) {
// wkt数据
String wkt = map.get("wkt").toString();
// wkt类型
String geometry = wkt.substring(0, wkt.indexOf("(")).trim().toLowerCase();
//ES能存储的格式
String data = "{\"coordinates\":";
data += WKTUtil.getESGeoTextFromWkt(wkt) + ",\"type\":\"" + geometry + "\"},";
json += "\"wkt\":" + data;
map.remove("wkt");
}
int i = 1;
for (String key : map.keySet()) {
json += "\"" + key + "\":\"" + map.get(key).toString() + "\"";
if (i != map.size()) {
json += ",";
}
i++;
}
json += "}";
return json;
}
/**
* 获取转换数据
* @param wkt
* @return
* @throws ParseException
*/
private static Map<String,Object> getConversionData(String wkt) throws ParseException {
//空间数据类型
String type=wkt.substring(0,wkt.indexOf("(")).trim().toLowerCase();
Map<String,Object> map = new HashMap<String,Object>();
map.put("type",type);
WKTReader wktReader = new WKTReader();
if(type.equals("point")){
Point geoPoint =(Point) wktReader.read(wkt);
Coordinate coordinates = geoPoint.getCoordinate();
double[] point=new double[2];
point[0]=coordinates.x;
point[1]=coordinates.y;
map.put("coordinates",point);
}else if(type.equals("linestring")) {
LineString geoLineString =(LineString) wktReader.read(wkt);
Coordinate[] coordinates = geoLineString.getCoordinates();
double[][] lineString = new double[coordinates.length][2];
for(int i=0;i<coordinates.length;i++) {
lineString[i][0] = coordinates[i].x;
lineString[i][1] = coordinates[i].y;
}
map.put("coordinates",lineString);
}else if(type.equals("polygon")||type.equals("multilinestring")) {
/*Geometry geometry = wktReader.read(wkt);
List<double[][]> list=new ArrayList<>();
int length = geometry.getNumGeometries();
for(int i=0;i<length;i++) {
Geometry geometryN = geometry.getGeometryN(i);
Coordinate[] coordinates = geometryN.getCoordinates();
double[][] position = new double[coordinates.length][2];
for(int j=0;j<coordinates.length;j++) {
position[j][0]=coordinates[j].x;
position[j][1]=coordinates[j].y;
}
list.add(position);
}
map.put("coordinates",list);*/
//数据
String data=wkt.trim().substring(wkt.indexOf("(")+1).trim();
data=data.substring(0,data.length()-1).trim();
String[] split = data.split("\\)");
List<double[][]> list=new ArrayList<>();
for(int i=0;i<split.length;i++) {
String trim = split[i].replace("(", "").replace(")", "").trim();
if((trim.charAt(0)+"").equals(",")) {
trim=trim.substring(trim.indexOf(",")+1);
}
String[] split2 = trim.split(",");
double[][] position = new double[split2.length][2];
for(int j=0;j<split2.length;j++) {
String ptstr = split2[j].trim();
String[] lon_lat = ptstr.split(" ");
position[j][0] = Double.parseDouble(lon_lat[0]);
position[j][1] = Double.parseDouble(lon_lat[1]);
}
list.add(position);
}
map.put("coordinates",list);
}else if(type.equals("multipolygon")){
map=null;
}else{
map=null;
}
return map;
}
/**
* 创建索引库
* @param client 客户端
* @param idnexName 索引名称
* @param type 类型
* @return
* @throws Exception
*/
public static boolean createIndex(TransportClient client,String idnexName, String type) throws Exception {
boolean sign=false;
try {
// 创建mapping
XContentBuilder mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject("properties")
.startObject("id").field("type", "text").endObject()
.startObject("wkt").field("type", "geo_shape").endObject().endObject()
.endObject();
AdminClient admin = client.admin();
IndicesAdminClient indicesAdminClient = admin.indices();
CreateIndexResponse createIndexResponse = indicesAdminClient.prepareCreate(idnexName)
.setSettings(Settings.builder()
.put("index.number_of_shards", 5) // 分片
.put("index.number_of_replicas", 1) // 副本
)
.addMapping(type, mapping) // mapping
.get();
createIndexResponse.isAcknowledged();
sign=true;
} catch (Exception e) {
e.getMessage();
}
return sign;
}
/**
* 判断索引名称是否存在
* @param client 客户端
* @param indexName 索引名称
* @return
*/
public static boolean isExistsIndex(TransportClient client,String indexName){
IndicesExistsResponse response = client.admin().indices()
.exists(new IndicesExistsRequest().indices(new String[]{indexName})).actionGet();
return response.isExists();
}
}
在需要操作的类进行注入
@Autowired
private TransportClient client;
批量插入方法,map要包含indexName和wkt数据
/**
* 添加集合索引
* @param list<map>
* @return
* @throws Exception
*/
@RequestMapping(value="/addIndexs",method=RequestMethod.POST)
@ResponseBody
public ResultBean addIndexs(@RequestBody List<Map<String,Object>> list) throws Exception {
ResultBean result =new ResultBean();
try {
//索引库名称和类型
String indexName=list.get(0).get("indexName").toString();
//判断索引是否存在,不存在就进行创建
if(!ESUtil.isExistsIndex(client,indexName)) {
ESUtil.createIndex(client,indexName,indexName);
}
//批量请求生成器
BulkRequestBuilder bulkRequest = client.prepareBulk();
for(int i=0;i<list.size();i++) {
//id
String id=UUID.randomUUID().toString().replace("-", "");
/*//字段mapping
XContentBuilder mapping=getMapping(list.get(i),id);
bulkRequest.add(client.prepareIndex(indexName, indexName,id).setSource(mapping));*/
//字段json
String json=ESUtil.getJsonData(list.get(i),id);
bulkRequest.add(client.prepareIndex(indexName, indexName,id).setSource(json,XContentType.JSON));
if(i==0) {
continue;
}
if(i==list.size()-1) {
bulkRequest.get();
break;
}
if(i%2000==0) {
bulkRequest.get();
bulkRequest=client.prepareBulk();
}
}
result.setCode(200);
result.setMsg("插入成功");
} catch (Exception e) {
result.setCode(500);
result.setMsg(e.getMessage());
}
return result;
}
wkt数据
LINESTRING(104.06076431390831 30.66749572727531,104.06728744623253 30.66776275637494)
LINESTRING(104.06133651762504 30.66513061547994,104.06744003354108 30.66520690782454)
LINESTRING(104.06133651762504 30.662803649202033,104.06736374250615 30.663337707401297)
LINESTRING(104.06232833774995 30.660285949443278,104.06763076898643 30.660781860815405)
POLYGON((104.057874680002 30.65196990964523,104.0613269802998 30.6519889830588,104.05997276335258 30.64998626644865,104.057874680002 30.65196990964523))
MULTILINESTRING ((104.043827058631 30.64563751310743,104.04817581133102 30.640754698279125),(104.04817581133102 30.640754698279125,104.08449173090048 30.641326901995853))
POINT(104.12048340775073 30.710449228936344)
POINT(103.97399900481105 30.79467767471215)