搜索地理位置呢,es字段 也就是经度纬度都必须是它需要的指定的类型,要不然查询不了,在kibana中新增加个geo_point数据类型的字段用来做位置字段
#添加geo_point类型的字段
PUT demo_data/_mapping/demotable
{
"properties": {
"location1":{
"type":"geo_point"
}
}
}
然后添加位置信息
PUT demo_data/demotable/1
{
"location1" : {
"lat" : 40.1130101944,
"lon" : 116.0940402747
}
}
我已经添加很多条不同的位置信息了,可以添加不同的信息测试
我在某一个位置上,然后搜索我附近7km的位置有哪些玩的地方,这种方式是在你的点上画一个7km的圆,7km内有值的话就能查询出来
GET demo_data/demotable/_search
{
"query":{
"bool":{
"must":[
{
"match_all":{}
}
],
"filter":{
"geo_distance": {
"distance": "7km",
"location1": {
"lat": 40.0484217966,
"lon": 116.2531422502
}
}
}
}
}
}
查看我7km有哪些景点返回的数据
{
"took": 11,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 1,
"hits": [
{
"_index": "demo_data",
"_type": "demotable",
"_id": "9",
"_score": 1,
"_source": {
"doc": {
"location": "40.0021050751,116.4877734631"
},
"location": "40.0351136791,116.2614275195",
"name": "李四",
"address": "北京百望山森林公园",
"location1": {
"lon": 116.2614275195,
"lat": 40.035113679
}
}
},
{
"_index": "demo_data",
"_type": "demotable",
"_id": "8",
"_score": 1,
"_source": {
"doc": {
"location": "39.9294974651,116.3135646417"
},
"location": "39.9975825792,116.2778147503",
"name": "三三",
"address": "北京颐和园",
"location1": {
"lon": 116.2778147503,
"lat": 39.9975825792
}
}
},
{
"_index": "demo_data",
"_type": "demotable",
"_id": "5",
"_score": 1,
"_source": {
"doc": {
"location": "40.0351136791,116.2610841967"
},
"location": "40.0128168042,116.3099281033",
"name": "df",
"address": "北京圆明园",
"location1": {
"lon": 116.3099281033,
"lat": 40.0128168042
}
}
}
]
}
}
这回用Java程序搜索范围
@Autowired
private TransportClientUitl clientUitl;/**
* location 经纬度 格式是:40.0037160625,116.2891179180
* range 范围 搜索多少米或多少千米
* unit 单位 m是米 km是千米ss
* */
@Override
public List getRange(String location,Float range,String unit) throws Exception {
List arrayList=new ArrayList();
//分割 经纬度
String[] slocation=location.split(",");
Double lat= Double.parseDouble(slocation[0]);
Double lon= Double.parseDouble(slocation[1]);
SearchRequestBuilder srb=clientUitl.getClient().prepareSearch("demo_data")
.setTypes("demotable");
srb.setFrom(0).setSize(1000);//查询多少条
GeoDistanceQueryBuilder location1=null;
//按哪种长度单位去查找 km还是m
if(unit.equals("km")){
location1=QueryBuilders.geoDistanceQuery("location1").point(lat,lon)
.distance(range, DistanceUnit.KILOMETERS);
}else if(unit.equals("m")){
location1=QueryBuilders.geoDistanceQuery("location1").point(lat,lon)
.distance(range, DistanceUnit.METERS);
}
srb.setPostFilter(location1);
//获取距离多少公里 这个才是获取点与点之间距离的
GeoDistanceSortBuilder sort= SortBuilders.geoDistanceSort("location1",lat,lon);
//sort.unit(DistanceUnit.METERS);
//排序
sort.order(SortOrder.ASC);
sort.point(lat,lon);
srb.addSort(sort);
SearchResponse searchResponse=srb.execute().actionGet();
SearchHits hits=searchResponse.getHits();
SearchHit[] searchHit=hits.getHits();
//搜索耗时
float userTime=searchResponse.getTookInMillis()/1000f;
System.out.println("搜索附近的地址("+hits.getTotalHits()+"个),耗时("+userTime+"秒);");
//获取搜索完后的信息
for (SearchHit hit:searchHit){
Map map=new HashMap();
map.put("address",(String)hit.getSource().get("address"));
//获取距离值,并保留两位小数点
BigDecimal geoDis = new BigDecimal((Double) hit.getSortValues()[0]);
Object location2=hit.getSource().get("location1");
Map hitMap=hit.getSource();
//计算距离
hitMap.put("geoDistance",geoDis.setScale(0,BigDecimal.ROUND_HALF_DOWN));
map.put("range",hit.getSource().get("geoDistance"));
arrayList.add(map);
System.out.println((String)hit.getSource().get("address")+"的坐标:"+
location2 + "与我的距离" +
hit.getSource().get("geoDistance") +
DistanceUnit.METERS.toString());
}
return arrayList;
}
打印控制台输出
访问网址得到的接口信息
简单的按条件搜索成功了