elasticsearch 1.5.2 를 사용 하여 근처에 있 는 사람 찾기

pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.heli</groupId>
	<artifactId>ElasticSearch</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>ElasticSearch</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<es.version>1.5.2</es.version>
		<lucene.maven.version>4.10.4</lucene.maven.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.elasticsearch</groupId>
			<artifactId>elasticsearch</artifactId>
			<version>${es.version}</version>
		</dependency>
		
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.8.2</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

사용자 실체:
package com.heli.es;

public class User {

	private long id;// id
	private String name;//   
	private double lat;//   
	private double lon;//   
	private double[] location;// hashcode
	
	public User(long id, String name, double lat, double lon) {
		super();
		this.id = id;
		this.name = name;
		this.lat = lat;
		this.lon = lon;
	}
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getLat() {
		return lat;
	}
	public void setLat(double lat) {
		this.lat = lat;
	}
	public double getLon() {
		return lon;
	}
	public void setLon(double lon) {
		this.lon = lon;
	}
	public double[] getLocation() {
		return location;
	}
	public void setLocation(double[] location) {
		this.location = location;
	}
}

테스트 클래스:
package com.heli.es;

import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.FilterBuilders.geoDistanceRangeFilter;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.FilterBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
/**
 *         ,    1000 ,1  100      
 */
public class ES4 {

	//     
	public static void createIndex(String indexName, String indexType) throws IOException {
		Client esClient = new TransportClient().addTransportAddress(new InetSocketTransportAddress("127.0.0.1", 9300));
		//   Mapping
		XContentBuilder mapping = createMapping(indexType);
		System.out.println("mapping:" + mapping.string());
		//        
		esClient.admin().indices().prepareCreate(indexName).execute().actionGet();
		PutMappingRequest putMapping = Requests.putMappingRequest(indexName).type(indexType).source(mapping);
		PutMappingResponse response = esClient.admin().indices().putMapping(putMapping).actionGet();
		if (!response.isAcknowledged()) {
			System.out.println("Could not define mapping for type [" + indexName + "]/[" + indexType + "].");
		} else {
			System.out.println("Mapping definition for [" + indexName + "]/[" + indexType + "] succesfully created.");
		}
	}

	//   mapping
	public static XContentBuilder createMapping(String indexType) {
		XContentBuilder mapping = null;
		try {
			mapping = jsonBuilder().startObject()
					//     (        )
					.startObject(indexType).startObject("properties")
					// ID
					.startObject("id").field("type", "long").endObject()
					//   
					.startObject("name").field("type", "string").endObject()
					//   
					.startObject("location").field("type", "geo_point").endObject()
			.endObject().endObject().endObject();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return mapping;
	}

	//     
	public static Integer addIndexData100000(String indexName, String indexType) {
		Client client = new TransportClient().addTransportAddress(new InetSocketTransportAddress("127.0.0.1", 9300));
		List<String> cityList = new ArrayList<String>();

		double lat = 39.929986;
		double lon = 116.395645;
		for (int i = 0; i < 100000; i++) {
			double max = 0.00001;
			double min = 0.000001;
			Random random = new Random();
			double s = random.nextDouble() % (max - min + 1) + max;
			DecimalFormat df = new DecimalFormat("######0.000000");
			// System.out.println(s);
			String lons = df.format(s + lon);
			String lats = df.format(s + lat);
			Double dlon = Double.valueOf(lons);
			Double dlat = Double.valueOf(lats);

			User city1 = new User(i, "   "+i, dlat, dlon);
			cityList.add(obj2JsonUserData(city1));
		}
		//      
		List<IndexRequest> requests = new ArrayList<IndexRequest>();
		for (int i = 0; i < cityList.size(); i++) {
			IndexRequest request = client.prepareIndex(indexName, indexType).setSource(cityList.get(i)).request();
			requests.add(request);
		}

		//       
		BulkRequestBuilder bulkRequest = client.prepareBulk();
		for (IndexRequest request : requests) {
			bulkRequest.add(request);
		}

		BulkResponse bulkResponse = bulkRequest.execute().actionGet();
		if (bulkResponse.hasFailures()) {
			System.out.println("        !");
		}
		return bulkRequest.numberOfActions();
	}


	public static String obj2JsonUserData(User user) {
		String jsonData = null;
		try {
			//   XContentBuilder  json  
			XContentBuilder jsonBuild = XContentFactory.jsonBuilder();
			jsonBuild.startObject().field("id", user.getId()).field("name", user.getName()).startArray("location").value(user.getLat()).value(user.getLon()).endArray()
					.endObject();
			jsonData = jsonBuild.string();
			System.out.println(jsonData);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return jsonData;
	}

	//       
	public static void testGetNearbyPeople(Client client, String index, String type, double lat, double lon) {
		SearchRequestBuilder srb = client.prepareSearch(index).setTypes(type);
		srb.setFrom(0).setSize(1000);//1000 
		// lon, lat      ,      1  1000 
		FilterBuilder builder = geoDistanceRangeFilter("location").point(lon, lat).from("1m").to("100m").optimizeBbox("memory").geoDistance(GeoDistance.PLANE);
		srb.setPostFilter(builder);
		//                         
		GeoDistanceSortBuilder sort = SortBuilders.geoDistanceSort("location");
		sort.unit(DistanceUnit.METERS);
		sort.order(SortOrder.ASC);
		sort.point(lon, lat);
		srb.addSort(sort);

		SearchResponse searchResponse = srb.execute().actionGet();

		SearchHits hits = searchResponse.getHits();
		SearchHit[] searchHists = hits.getHits();
		 //     
        Float usetime = searchResponse.getTookInMillis() / 1000f;
		System.out.println("      (" + hits.getTotalHits() + " ),  ("+usetime+" ):");
		for (SearchHit hit : searchHists) {
			String name = (String) hit.getSource().get("name");
			List<Double> location = (List<Double>)hit.getSource().get("location");
			//      ,        
			BigDecimal geoDis = new BigDecimal((Double) hit.getSortValues()[0]);
			Map<String, Object> hitMap = hit.getSource();
			//    MAPPING   ,       geoDistance。
			hitMap.put("geoDistance", geoDis.setScale(0, BigDecimal.ROUND_HALF_DOWN));
			System.out.println(name+"   :"+location + "     " + hit.getSource().get("geoDistance") + DistanceUnit.METERS.toString());
		}

	}
	public static void main(String[] args) throws IOException {
		Client client = new TransportClient().addTransportAddress(new InetSocketTransportAddress("127.0.0.1", 9300));
		String index = "es";
		String type = "people";
		//createIndex(index, type);
		//addIndexData100000(index, type);

		double lat = 39.929986;
		double lon = 116.395645;
		long start = System.currentTimeMillis();
		//query(" ", index, type);
		testGetNearbyPeople(client, index, type, lat, lon);
		long end = System.currentTimeMillis();
		System.out.println((end - start) + "  ");
		//client.close();// 1.5.2      
	}
}

검색 결과:
      (69 ),  (0.016 ):
   17413   :[39.929999, 116.395658]     2m
   79407   :[39.930006, 116.395665]     2m
   26009   :[39.93003, 116.395689]     5m
   90577   :[39.930041, 116.3957]     7m
   4479   :[39.930049, 116.395708]     8m
   59538   :[39.930068, 116.395727]     10m
   56225   :[39.930072, 116.395731]     10m
   78623   :[39.930075, 116.395734]     11m
   21402   :[39.930092, 116.395751]     13m
   98117   :[39.930098, 116.395757]     14m
   92957   :[39.9301, 116.395759]     14m
   75291   :[39.930101, 116.39576]     14m
   84154   :[39.930121, 116.39578]     16m
   73369   :[39.93016, 116.395819]     21m
   38979   :[39.930174, 116.395833]     23m
   78569   :[39.930193, 116.395852]     25m
   15100   :[39.930207, 116.395866]     27m
   3864   :[39.930218, 116.395877]     28m
   66276   :[39.930237, 116.395896]     30m
   90141   :[39.930243, 116.395902]     31m
   29377   :[39.930249, 116.395908]     32m
   54727   :[39.930253, 116.395912]     32m
   10456   :[39.930292, 116.395951]     37m
   48968   :[39.930298, 116.395957]     38m
   20625   :[39.930305, 116.395964]     39m
   58066   :[39.930307, 116.395966]     39m
   76596   :[39.930308, 116.395967]     39m
   73185   :[39.930323, 116.395982]     41m
   26093   :[39.930331, 116.39599]     42m
   76719   :[39.930331, 116.39599]     42m
   27200   :[39.930337, 116.395996]     43m
   48983   :[39.930337, 116.395996]     43m
   21808   :[39.930356, 116.396015]     45m
   70386   :[39.930356, 116.396015]     45m
   56140   :[39.93036, 116.396019]     45m
   19567   :[39.930365, 116.396024]     46m
   9499   :[39.930366, 116.396025]     46m
   11682   :[39.930381, 116.39604]     48m
   19372   :[39.930382, 116.396041]     48m
   12508   :[39.930383, 116.396042]     48m
   56554   :[39.930385, 116.396044]     48m
   79324   :[39.930389, 116.396048]     49m
   30910   :[39.930394, 116.396053]     50m
   45095   :[39.930412, 116.396071]     52m
   73533   :[39.930422, 116.396081]     53m
   46509   :[39.930422, 116.396081]     53m
   81262   :[39.93044, 116.396099]     55m
   30077   :[39.930448, 116.396107]     56m
   61049   :[39.930456, 116.396115]     57m
   16607   :[39.930458, 116.396117]     57m
   50464   :[39.930467, 116.396126]     58m
   7272   :[39.930468, 116.396127]     59m
   82133   :[39.93047, 116.396129]     59m
   46350   :[39.930472, 116.396131]     59m
   40185   :[39.930502, 116.396161]     63m
   28020   :[39.930515, 116.396174]     64m
   75873   :[39.93052, 116.396179]     65m
   83959   :[39.930527, 116.396186]     66m
   5175   :[39.930529, 116.396188]     66m
   15511   :[39.930531, 116.39619]     66m
   61721   :[39.930535, 116.396194]     67m
   54860   :[39.930549, 116.396208]     68m
   38391   :[39.93055, 116.396209]     69m
   5603   :[39.930555, 116.396214]     69m
   70588   :[39.930579, 116.396238]     72m
   12256   :[39.930583, 116.396242]     73m
   93219   :[39.930598, 116.396257]     74m
   80353   :[39.930607, 116.396266]     75m
   19737   :[39.930617, 116.396276]     77m
82  

주:server 와 client 버 전 은 1.5.2 를 사 용 했 습 니 다.server 버 전 은 elasticsearch-rtf-master 를 사용 하면 sort 는 항상 보고 합 니 다.
Exception in thread "main" org.elasticsearch.action.search.SearchPhaseExecutionException: Failed to execute phase [query], all shards failed; shardFailures {[alee59cPQNuzRP4go6-5vw][testes][4]: SearchParseException[[testes][4]: from[-1],size[-1]: Parse Failure [Failed to parse source [{"post_filter":{"geo_distance_range":{"location":"wx4g0th9p0gk","from":"1km","to":"2000km","include_lower":true,"include_upper":true,"distance_type":"arc","optimize_bbox":"memory"}},"sort":[{"_geo_distance":{"location":[{"lat":39.929986,"lon":116.395645}],"unit":"km","distance_type":"arc"}}]}]]]; nested: ElasticsearchParseException[Numeric value expected]; }{[alee59cPQNuzRP4go6-5vw][testes][0]: SearchParseException[[testes][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{"post_filter":{"geo_distance_range":{"location":"wx4g0th9p0gk","from":"1km","to":"2000km","include_lower":true,"include_upper":true,"distance_type":"arc","optimize_bbox":"memory"}},"sort":[{"_geo_distance":{"location":[{"lat":39.929986,"lon":116.395645}],"unit":"km","distance_type":"arc"}}]}]]]; nested: ElasticsearchParseException[Numeric value expected]; }{[alee59cPQNuzRP4go6-5vw][testes][1]: SearchParseException[[testes][1]: from[-1],size[-1]: Parse Failure [Failed to parse source [{"post_filter":{"geo_distance_range":{"location":"wx4g0th9p0gk","from":"1km","to":"2000km","include_lower":true,"include_upper":true,"distance_type":"arc","optimize_bbox":"memory"}},"sort":[{"_geo_distance":{"location":[{"lat":39.929986,"lon":116.395645}],"unit":"km","distance_type":"arc"}}]}]]]; nested: ElasticsearchParseException[Numeric value expected]; }{[alee59cPQNuzRP4go6-5vw][testes][2]: SearchParseException[[testes][2]: from[-1],size[-1]: Parse Failure [Failed to parse source [{"post_filter":{"geo_distance_range":{"location":"wx4g0th9p0gk","from":"1km","to":"2000km","include_lower":true,"include_upper":true,"distance_type":"arc","optimize_bbox":"memory"}},"sort":[{"_geo_distance":{"location":[{"lat":39.929986,"lon":116.395645}],"unit":"km","distance_type":"arc"}}]}]]]; nested: ElasticsearchParseException[Numeric value expected]; }{[alee59cPQNuzRP4go6-5vw][testes][3]: SearchParseException[[testes][3]: from[-1],size[-1]: Parse Failure [Failed to parse source [{"post_filter":{"geo_distance_range":{"location":"wx4g0th9p0gk","from":"1km","to":"2000km","include_lower":true,"include_upper":true,"distance_type":"arc","optimize_bbox":"memory"}},"sort":[{"_geo_distance":{"location":[{"lat":39.929986,"lon":116.395645}],"unit":"km","distance_type":"arc"}}]}]]]; nested: ElasticsearchParseException[Numeric value expected]; }

 1.5.2 결과 로 바 꿨 으 면 좋 겠 어 요.그리고...
.point(lon, lat)

  반드시 경도 가 앞 에 있 고 위도 가 뒤에 있어 야 합 니 다.그렇지 않 으 면 조회 가 비어 있 습 니 다.한 친구 와 이 야 기 를 나 누 어 이것 은 bug 일 수 있 습 니 다.
  또한 조회 속도 가 너무 느 려 서 어느 곳 에 설정 해 야 하 는 지 시험 을 통 해 클 라 이언 트 를 만 드 는 데 1 초 정도 걸 렸 고 10 만 개의 기수 조회 82 밀리초 가 매우 빨 랐 습 니 다.

좋은 웹페이지 즐겨찾기