1. 程式人生 > >elasticsearch 全文檢索,geo地理位置附近的人查詢

elasticsearch 全文檢索,geo地理位置附近的人查詢

            elasticsearch 5.0.1  單機 cpu 8g記憶體

    100萬資料量,搜尋耗時30ms 左右

       

**
 * 實現附近的人功能,最大限額1000人,1米到100米範圍內的人
 */
public class ES4 {

    // 建立索引
    public static void createIndex(String indexName, String indexType) throws IOException {
        Client esClient = new PreBuiltTransportClient(Settings.EMPTY).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 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) throws UnknownHostException {
        Client client = new PreBuiltTransportClient(Settings.EMPTY).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
        List<String> cityList = new ArrayList<String>();

        double lat = 39.929986;
        double lon = 116.395645;
        for (int i = 100000; i < 1000000; 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.getLon()).value(user.getLat()).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);
        GeoDistanceQueryBuilder location1 = QueryBuilders.geoDistanceQuery("location").point(lat,lon).distance(100,DistanceUnit.METERS);
        srb.setPostFilter(location1);
        // 獲取距離多少公里 這個才是獲取點與點之間的距離的
        GeoDistanceSortBuilder sort = SortBuilders.geoDistanceSort("location",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[] 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 PreBuiltTransportClient(Settings.EMPTY).addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 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用完不用關閉
    }
}

相關推薦

elasticsearch 全文檢索,geo地理位置附近查詢

            elasticsearch 5.0.1  單機 cpu 8g記憶體     100萬資料量,搜尋耗時30ms 左右         ** * 實現附近的人功能,最大限額1000人,1米到100米範圍內的人 */ public class ES

redis GEO地理位置命令介紹

each limits 排序。 ima 字符 lex member pat uniq GEOADD keylongitude latitude member [longitude latitude member ...] Available since 3.2.0. T

Elasticsearch全文檢索,高亮關鍵字

code spa nsh pes lds exp response sets highlight 問題 用如下這樣的term方式,可以高亮 .setQuery(QueryBuilders.termQuery("PARAM_NAME", "a")) { "query":

Elasticsearch全文檢索工具入門

使用步驟 artifact rop 創建 是否 方式 cluster 包名 Lucene 1 Elasticsearch全文檢索工具入門: 2 1.下載對應系統版本的文件 3 elasticsearch-2.4.0.zip 4

ElasticSearch 全文檢索ElasticSearch 核心概念

行處理 nod 分詞 關註 使用 stack 分布 creat 一是 ElasticSearch核心概念-Cluster   1)代表一個集群,集群中有多個節點,其中有一個為主節點,這個主節點是可以通過選舉產生的,主從節點是對於集群內部來說的。es的一個概念就是去中心化,

TB級Elasticsearch全文檢索優化研究

TB級Elasticsearch全文檢索優化研究 背景 今年工作的一個重點是“新技術新模式”的匯入和研究。Elasticsearch技術比較火,各專案和產品用的都也比較多。其中某團隊遇到一個問題:“在TB級的資料量下進行全文檢索時,ES叢集檢索響應速度比較慢”。雖然由於各種原因沒有接觸到系統,沒有看到程式

Elasticsearch全文檢索之copy_to

全文檢索場景在實際專案中,無界搜尋具體查詢某一個欄位對於客戶來說是不確定的,但是實際資料中需要檢索的欄位非常多。 在使用elasticsearch時遇見了這樣的需求:es聚合指定欄位時聚合的結果裡面只顯

springboot整合elasticsearch全文檢索入門

只是簡單的整合介紹 # 安裝 # 依賴 springBootVersion = '2.0.5.RELEASE' compile group: 'org.springframework.boot', name: 'spring-boot-starter-da

Elasticsearch全文檢索系統實現深入詳解

題記 學習ES的童鞋,都有一個開發一個類似百度的搜尋引擎的想法。當然功能不一定是百度、360、谷歌傳統的搜尋引擎那麼強大。 但是,能實現基本的全文檢索、指定型別的檢索、評分高低優先順序排序等等。 那麼問題來了,該如何實現?需要什麼技術呢? 1、Ela

redis3.2新功能--GEO地理位置命令介紹

概述 redis3.2釋出rc版本已經有一段時間了,估計RedisConf 2016左右,3.2版本就能release了。3.2版本中增加的最大功能就是對GEO(地理位置)的支援。說起redis的GEO特性,最大的貢獻還是咱們中國人。redis作者在對3.2引進新特性的部落格中介紹了為什麼支援GEO。G

Elasticsearch全文檢索

簡介   Elasticsearch是一個實時分散式搜尋和分析引擎,用於全文搜尋、結構化搜尋、分析以及將這三者混合使用。Elasticsearch實現全文索引,需要使用分詞器,預設使用的standard分詞器。由於本文介紹的是中文的全文檢索,因此我們需要使用第

Elasticsearch全文檢索實戰小結——覆盤我帶的第二個專案

一、專案概述 這是一個被我稱之為“沒有槍、沒有炮,硬著頭皮自己造”的專案。專案是和其它公司合作的三個核心模組開發。 使用ES的目的是: 1)、採集資料、網站資料清洗後存入ES; 2)、對外提供精確檢索、萬用字元檢索、模糊檢索、分詞檢索、全文檢索介面等二次

Elasticsearch全文檢索企業開發記錄總結(二):ES客戶端搭建

專案依賴 <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport<

redis geo 地理位置系應用戰案例

兩個 usb des long tor ember pos tar 最大 專有名詞geographic 地理radius 半徑範圍; 半徑(距離); 用半徑度量的圓形面積 redis GEO實現 redis GEO實現主要包含了以下兩項技術: 1、使用geoha

Elasticsearch全文檢索學習

ElasticSearch官方網址:https://www.elastic.co ElasticSearch官方網址(中文):https://www.elastic.co/cn/ Elasticsearch 權威指南(中文版文件,線上觀看):https://es.xiaoleilu.com/ 1、

使用Lucene-Spatial實現整合地理位置全文檢索

        Lucene通過Spatial包提供了對基於地理位置的全文檢索的支援,最典型的應用場景就是:“搜尋中關村附近1公里內的火鍋店,並按遠近排序”。使用Lucene-Spatial新增對地理位置的支援,和之前普通文字搜尋主要有兩點區別:        1. 將座標資

全文檢索學習歷程目錄結構Lucene、ElasticSearch

wql elong f2c xiang bench ros dml bst nsh Linux%20Shell%E7%B3%BB%E5%88%97%E6%95%99%E7%A8%8B%E4%B9%8B%E4%BA%8C%E7%AC%AC%E4%B8%80%E4%B8%AAS

14套java精品高級架構課,緩存架構,深入Jvm虛擬機,全文檢索Elasticsearch視頻教程

http soft 精品 target mysql rocket body 精通 ava 14套java精品高級架構課,緩存架構,深入Jvm虛擬機,全文檢索Elasticsearch,Dubbo分布式Restful服務,並發原理編程,SpringBoot,SpringClo

全文檢索ElasticSearch框架學習

性能 tar 監控 流行 ron ref 目的 快速 服務 1. 全文檢索的通用步驟: 1、建庫步驟:   a 分詞   b 倒排索引 : 關鍵詞和記錄Id的對應關系,1對多。 2、查詢步驟:   a 分詞   b 查索引   c 取交集

地理位置geo處理之mysql函式

目前越來越多的業務都會基於LBS,附近的人,外賣位置,附近商家等等,現就討論離我最近這一業務場景的解決方案。 原文:https://www.jianshu.com/p/455d0468f6d4 目前已知解決方案有: mysql 自定義函式計算