1.maven用依赖如下

    <properties>        <lib.lucene.version>6.1.0</lib.lucene.version>    </properties>        <dependency>            <groupId>com.fasterxml.jackson.core</groupId>            <artifactId>jackson-databind</artifactId>            <version>2.8.1</version>        </dependency>        <dependency>            <groupId>org.apache.lucene</groupId>            <artifactId>lucene-core</artifactId>            <version>${lib.lucene.version}</version>        </dependency>        <dependency>            <groupId>org.apache.lucene</groupId>            <artifactId>lucene-analyzers-common</artifactId>            <version>${lib.lucene.version}</version>        </dependency>        <dependency>            <groupId>org.apache.lucene</groupId>            <artifactId>lucene-spatial</artifactId>            <version>${lib.lucene.version}</version>        </dependency>        <dependency>            <groupId>org.apache.lucene</groupId>            <artifactId>lucene-spatial-extras</artifactId>            <version>${lib.lucene.version}</version>        </dependency>        <dependency>            <groupId>org.apache.lucene</groupId>            <artifactId>lucene-analyzers-smartcn</artifactId>            <version>${lib.lucene.version}</version>        </dependency>

2.直接上代码

package org.xpen.hello.search.lucene;

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;

import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.document.Field.Store;import org.apache.lucene.document.NumericDocValuesField;import org.apache.lucene.document.StoredField;import org.apache.lucene.document.TextField;import org.apache.lucene.index.DirectoryReader;import org.apache.lucene.index.IndexReader;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.IndexWriterConfig;import org.apache.lucene.index.Term;import org.apache.lucene.queries.function.ValueSource;import org.apache.lucene.search.BooleanClause;import org.apache.lucene.search.BooleanQuery;import org.apache.lucene.search.IndexSearcher;import org.apache.lucene.search.Query;import org.apache.lucene.search.Sort;import org.apache.lucene.search.TermQuery;import org.apache.lucene.search.TopDocs;import org.apache.lucene.spatial.SpatialStrategy;import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;import org.apache.lucene.spatial.query.SpatialArgs;import org.apache.lucene.spatial.query.SpatialOperation;import org.apache.lucene.store.Directory;import org.apache.lucene.store.RAMDirectory;import org.junit.Test;import org.locationtech.spatial4j.context.SpatialContext;import org.locationtech.spatial4j.distance.DistanceUtils;import org.locationtech.spatial4j.shape.Point;import org.locationtech.spatial4j.shape.Shape;

import com.fasterxml.jackson.core.JsonFactory;import com.fasterxml.jackson.core.JsonParser;import com.fasterxml.jackson.databind.ObjectMapper;

/** * Lucene spatial演示 * 出处:官方junit代码 */public class SpatialExample {

    @Test    public void test() throws Exception {        init();        indexPoints();        search();    }

    /** Spatial4j上下文 */    private SpatialContext ctx;// "ctx" is the conventional variable name

    /** 提供索引和查询模型的策略接口 */    private SpatialStrategy strategy;

    /** 索引目录 */    private Directory directory;

    protected void init() {        // SpatialContext也可以通过SpatialContextFactory工厂类来构建        this.ctx = SpatialContext.GEO;

        //网格最大11层, geohash的精度        int maxLevels = 11;

        //Spatial Tiers        SpatialPrefixTree grid = new GeohashPrefixTree(ctx, maxLevels);

        this.strategy = new RecursivePrefixTreeStrategy(grid, "myGeoField");

        this.directory = new RAMDirectory();    }

    private void indexPoints() throws Exception {        IndexWriterConfig iwConfig = new IndexWriterConfig(new SmartChineseAnalyzer());        IndexWriter indexWriter = new IndexWriter(directory, iwConfig);

        JsonFactory jsonFactory = new JsonFactory();        jsonFactory.enable(JsonParser.Feature.ALLOW_COMMENTS);        ObjectMapper mapper = new ObjectMapper(jsonFactory);

        BufferedReader br = new BufferedReader(new InputStreamReader(                SpatialExample.class.getClassLoader().getResourceAsStream("search/lucene/shop.json")));

        String line = null;          while ((line = br.readLine()) != null) {            ShopBean shopBean = mapper.readValue(line, ShopBean.class);            //这里的x,y即经纬度,x为Longitude(经度),y为Latitude(纬度)              Document document = newSampleDocument(shopBean.getId(), shopBean.getName(), ctx.makePoint(shopBean.getLongitude(), shopBean.getLatitude()));            indexWriter.addDocument(document);        }  

        indexWriter.close();    }

    private Document newSampleDocument(int id, String title, Shape... shapes) {        Document doc = new Document();        doc.add(new StoredField("id", id));        doc.add(new NumericDocValuesField("id", id));        doc.add(new TextField("name", title, Store.YES));

        // Potentially more than one shape in this field is supported by some        // strategies; see the javadocs of the SpatialStrategy impl to see.        for (Shape shape : shapes) {            for (Field f : strategy.createIndexableFields(shape)) {                doc.add(f);            }            // store it too; the format is up to you            // (assume point in this example)            Point pt = (Point) shape;            doc.add(new StoredField(strategy.getFieldName(), pt.getX() + " " + pt.getY()));        }

        return doc;    }

    private void search() throws Exception {        searchInner("密室");        System.out.println("----------------");        searchInner("咖啡");    }

    private void searchInner(String keyword) throws Exception {        IndexReader indexReader = DirectoryReader.open(directory);        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        // --Filter by circle (<= distance from a point)        // Search with circle        // note: SpatialArgs can be parsed from a string        Point pt = ctx.makePoint(121.41791, 31.21867);        // the distance in km        ValueSource valueSource = strategy.makeDistanceValueSource(pt, DistanceUtils.DEG_TO_KM);        //按距离由近及远排序        Sort distSort = new Sort(valueSource.getSortField(false)).rewrite(indexSearcher); // false=asc                                                                                         dist

        SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,                ctx.makeCircle(pt, DistanceUtils.dist2Degrees(3.0, DistanceUtils.EARTH_MEAN_RADIUS_KM)));        Query query = strategy.makeQuery(args);

        BooleanQuery.Builder bqb = new BooleanQuery.Builder();        bqb.add(query, BooleanClause.Occur.MUST);        bqb.add(new TermQuery(new Term("name", keyword)), BooleanClause.Occur.MUST);

        TopDocs docs = indexSearcher.search(bqb.build(), 20, distSort);        printDocs(indexSearcher, docs, args);

        indexReader.close();    }

    private void printDocs(IndexSearcher indexSearcher, TopDocs docs, SpatialArgs args) throws IOException {        for (int i = 0; i < docs.totalHits; i++) {            Document doc = indexSearcher.doc(docs.scoreDocs[i].doc);            System.out.print(doc.getField("id").numericValue().intValue());            System.out.print(":" + doc.getField("name").stringValue());

            //计算距离            String docStr = doc.getField(strategy.getFieldName()).stringValue();            // assume docStr is "x y" as written in newSampleDocument()            int spaceIdx = docStr.indexOf(' ');            double x = Double.parseDouble(docStr.substring(0, spaceIdx));            double y = Double.parseDouble(docStr.substring(spaceIdx + 1));            double docDistDEG = ctx.calcDistance(args.getShape().getCenter(), x, y);

            System.out.print("(" + DistanceUtils.degrees2Dist(docDistDEG, DistanceUtils.EARTH_MEAN_RADIUS_KM) + "km)");

            System.out.println();        }    }

}

3.测试数据
shop.json

{"id":22130905,"name":"nook诺克密室&DIY多肉(人民广场店)","address":"浙江南路78号东新大厦216室","longitude":121.48206,"latitude":31.2288}{"id":2871847,"name":"星巴克(江苏店)","address":"江苏路458号1层116","longitude":121.43091,"latitude":31.218975}{"id":18179096,"name":"极道真人密室逃脱(人民广场大世界总店)","address":"金陵东路569号汇通大厦804室","longitude":121.48103,"latitude":31.226982}{"id":22676436,"name":"I high club","address":"上大路99号","longitude":121.39542,"latitude":31.312284}{"id":16820366,"name":"小仙屋剧情密室逃脱","address":"胶州路941号长久商务中心2203室","longitude":121.436646,"latitude":31.237585}{"id":8852374,"name":"魔方剧情真人密室逃脱(静安店)","address":"西康路618号华通大厦13楼D座","longitude":121.446335,"latitude":31.23506}{"id":24065790,"name":"A9真人密室逃脱(黄浦店)","address":"福州路465号上海书城6楼贝亦迪科技体验馆","longitude":121.48146,"latitude":31.23335}{"id":66552930,"name":"Charles' VR 虚拟现实体验馆","address":"五角场大学路161号701室","longitude":121.509865,"latitude":31.304022}{"id":8843152,"name":"iDream真人密室逃脱(百米香榭店)","address":"浙江路229号百米香榭街354店铺","longitude":121.479,"latitude":31.233591}{"id":11579304,"name":"1617Cafe(中山公园龙之梦服务区)","address":"长宁路890号玫瑰坊1楼88B","longitude":121.41786,"latitude":31.219374}{"id":19649586,"name":"MC精品真人密室逃脱(八佰伴店)","address":"浦东南路1088号4F-05","longitude":121.515366,"latitude":31.228285}{"id":66350697,"name":"初鱼vr咖-虚拟现实体验馆","address":"大学路103号802室","longitude":121.51079,"latitude":31.304335}{"id":3564328,"name":"Boom Cafe","address":"宣化路313号","longitude":121.42288,"latitude":31.216875}{"id":6850935,"name":"nook诺克密室逃脱(长宁店)","address":"中山公园附近","longitude":121.4217,"latitude":31.215496}{"id":23306435,"name":"暗黑魔盒集中营(鬼屋密室)","address":"翔殷路1099号4楼","longitude":121.51839,"latitude":31.30048}{"id":6438722,"name":"Min魔魔岛密室逃脱(中山公园店)","address":"长宁路988号花园大厦6楼606室","longitude":121.417885,"latitude":31.21871}{"id":5411446,"name":"COSTA COFFEE(上海长宁新世界)","address":"长宁路823号1楼","longitude":121.42047,"latitude":31.21866}{"id":7658577,"name":"因奥密室","address":"锦秋路699弄二区一排121号","longitude":121.38976,"latitude":31.32106}{"id":17163949,"name":"aMaze真人密室逃脱","address":"长宁路988号花园大厦903","longitude":121.41791,"latitude":31.21867}{"id":21930982,"name":"MANGOSIX(长宁龙之梦店)","address":"长宁路1018号龙之梦购物中心1楼1075号铺","longitude":121.41745,"latitude":31.21966}{"id":13915001,"name":"ZOOCOFFEE(定西路店)","address":"定西路1100号辽油大厦101室","longitude":121.42346,"latitude":31.2117}{"id":8019669,"name":"贝克街5号密室逃脱","address":"长寿路181弄日月星辰2号楼1007室","longitude":121.4421,"latitude":31.241724}{"id":67979580,"name":"Zero VR零维虚拟现实体验馆","address":"定西路1310弄18号303","longitude":121.42359,"latitude":31.215818}{"id":21374196,"name":"Dobe密室逃脱(杨浦大学路店)","address":"大学路33号701室loft37运动酒吧楼上","longitude":121.5117,"latitude":31.3047}{"id":17999648,"name":"DTR梦空间密室逃脱(八佰伴店)","address":"张杨路628弄东明广场2号楼2203室","longitude":121.52058,"latitude":31.228123}{"id":22636011,"name":"猫小姐的店","address":"长宁路890号玫瑰坊1楼","longitude":121.41781,"latitude":31.219257}{"id":23516373,"name":"Forest Rose Afternoon Tea","address":"长宁路890号玫瑰坊1F-72","longitude":121.418724,"latitude":31.21922}{"id":23550163,"name":"白兔子密室逃脱","address":"长宁路405弄1号地下1层","longitude":121.427055,"latitude":31.22307}{"id":32392280,"name":"海盗奇兵密室逃脱(五角场店)","address":"大学路33号601室loft37运动酒吧楼上","longitude":121.511765,"latitude":31.304789}{"id":56588006,"name":"第五空间咖啡馆","address":"长宁路1018号龙之梦购物中心4楼4202","longitude":121.41633,"latitude":31.218613}{"id":32508745,"name":"Vital Tea(长宁龙之梦店)","address":"长宁路1018号龙之梦购物中心1F-1055","longitude":121.41703,"latitude":31.21874}{"id":58805309,"name":"探险者世界(VR体验馆)","address":"人民广场迪美购物中心B1层","longitude":121.47345,"latitude":31.228691}{"id":57380950,"name":"阿拉丁真人密室逃脱(八佰伴店)","address":"张杨路628弄东明广场3号2C","longitude":121.52024,"latitude":31.22793}{"id":17950766,"name":"JOJO真人密室逃脱","address":"长寿路457号2楼C室","longitude":121.43657,"latitude":31.23879}{"id":57832242,"name":"Daisy花&咖啡","address":"江苏路54弄18号后门","longitude":121.42814,"latitude":31.223377}{"id":28615799,"name":"Let it go台球密室逃脱","address":"国济路20号七楼","longitude":121.51599,"latitude":31.30196}{"id":38092929,"name":"趣密室 & DIY手工坊","address":"石门二路333弄3号振安广场恒安大厦22楼E座","longitude":121.4598,"latitude":31.235432}{"id":57546152,"name":"好久不读 long time no read","address":"愚园路1208号","longitude":121.42646,"latitude":31.219221}{"id":66865461,"name":"VR family-虚拟现实体验馆","address":"大学路锦创路20号1101室创智66商务楼内(一兆韦德健身馆旁)","longitude":121.50922,"latitude":31.304209}{"id":9335488,"name":"77密室逃脱+真人CS(五角场店)","address":"四平路2500号东方商厦楼上金岛大厦1305室","longitude":121.515465,"latitude":31.298822}{"id":23062800,"name":"毛利侦探事务所密室逃脱","address":"大学路302号702室","longitude":121.50763,"latitude":31.30317}{"id":50431953,"name":"颠九宫真人游戏体验馆(杨浦店)","address":"国权路与邯郸路交叉口","longitude":121.50096,"latitude":31.297478}{"id":14155399,"name":"慢时光MYTIMECAFE","address":"武夷路339号","longitude":121.42406,"latitude":31.21347}{"id":59180246,"name":"月球剧情密室逃脱(淮海中路店)","address":"普安路189号曙光大厦18D","longitude":121.47889,"latitude":31.22244}{"id":27174604,"name":"MC精品真人密室逃脱(五角场店)","address":"翔殷路1128号8楼B4、B5","longitude":121.51691,"latitude":31.30103}{"id":32640417,"name":"西塞密室(长宁店)","address":"愚园路1391号3楼","longitude":121.42288,"latitude":31.218843}{"id":23403568,"name":"暗黑迷宫第三季","address":"南京西路1788号1788广场F201","longitude":121.44376,"latitude":31.22278}{"id":7045554,"name":"巴黎春天新世界酒店浓咖啡","address":"定西路1555号酒店2楼","longitude":121.4211,"latitude":31.218554}{"id":24899623,"name":"GIVE ME FIVE剧情密室逃脱(大学路店)","address":"大学路锦创路26号1102室创智66商务楼内","longitude":121.50918,"latitude":31.30425}{"id":67335522,"name":"nook诺克剧情密室 & VR虚拟现实体验馆(五角场店)","address":"大学路锦创路26号1602室创智66商务楼内","longitude":121.509315,"latitude":31.304174}{"id":4275877,"name":"Home Garden","address":"安化路492号德必易园多媒体创意园区106室","longitude":121.4202,"latitude":31.215342}{"id":18593150,"name":"TIK  TOK","address":"江苏路458号112室舜元企业发展大厦","longitude":121.43106,"latitude":31.218548}{"id":22447664,"name":"Running基地","address":"军工路100号","longitude":121.558266,"latitude":31.281694}{"id":24678174,"name":"太平洋咖啡(兆丰广场店)","address":"长宁路999号兆丰广场","longitude":121.41788,"latitude":31.21765}{"id":57439748,"name":"essence casa","address":"愚园路1329号","longitude":121.42449,"latitude":31.21873}{"id":65835399,"name":"大华虎城第三空间","address":"白丽路61号","longitude":121.35216,"latitude":31.27899}{"id":19671618,"name":"FullHouse桌游棋牌密室(南京西路店)","address":"大田路129号嘉发大厦A座25楼G","longitude":121.46391,"latitude":31.23294}{"id":23740568,"name":"aMaze真人密室逃脱(人民广场大世界店)","address":"云南南路180号淮云大厦8楼","longitude":121.48128,"latitude":31.2265}{"id":22132387,"name":"智源咖啡(中山公园店)","address":"安化路492号易园","longitude":121.42034,"latitude":31.21529}{"id":56890263,"name":"跑男开始了 runningman(公司活动,年会撕名牌)","address":"淮海中路","longitude":121.49525,"latitude":31.22792}{"id":18636516,"name":"ASA亚撒真人密室逃脱","address":"武夷路418弄(近定西路)1号武定大厦203室","longitude":121.421974,"latitude":31.212627}{"id":5857955,"name":"Crazycube颠九宫密室逃脱(大学路店)","address":"创智坊大学路302号701室","longitude":121.50754,"latitude":31.303108}{"id":2036581,"name":"星巴克(龙之梦2店)","address":"长宁路1018号龙之梦购物中心1楼1073号铺","longitude":121.416916,"latitude":31.218727}{"id":13913129,"name":"Captain.C真人密室逃脱","address":"延平路69号延平大厦701室","longitude":121.44161,"latitude":31.227833}{"id":57682702,"name":"aMaze真人密室逃脱(五角场店)","address":"大学路292号602室","longitude":121.50777,"latitude":31.30327}

4.测试结果
以下为分别搜索周围3公里内的密室和咖啡店的结果。

17163949:aMaze真人密室逃脱(0.0km)6438722:Min魔魔岛密室逃脱(中山公园店)(0.005043281377521635km)32640417:西塞密室(长宁店)(0.47300570633073574km)6850935:nook诺克密室逃脱(长宁店)(0.5044378650402169km)18636516:ASA亚撒真人密室逃脱(0.7751646578452988km)23550163:白兔子密室逃脱(0.9977952318745087km)13913129:Captain.C真人密室逃脱(2.473229285495286km)16820366:小仙屋剧情密室逃脱(2.7563385153155853km)17950766:JOJO真人密室逃脱(2.855389720759213km)----------------24678174:太平洋咖啡(兆丰广场店)(0.11345485407738468km)7045554:巴黎春天新世界酒店浓咖啡(0.30362262844238574km)22132387:智源咖啡(中山公园店)(0.44119592062398144km)57832242:Daisy花&咖啡(1.1046485391701188km)

5.参考资料
[url=http://baobeituping.iteye.com/blog/2214857]使用Lucene-Spatial实现集成地理位置的全文检索[/url]
[url=http://iamyida.iteye.com/blog/2204455]Lucene5学习之Spatial地理位置搜索[/url]

lucene spatial 6.1搜索附近的饭店相关推荐

  1. lucene Lucene Spatial

    lucene sf2gis@163.com 2015年6月26日 1  目标:查询目标词汇所在的相关文档. 参考:http://www.cnblogs.com/forfuture1978/catego ...

  2. Lucene5.5.4入门以及基于Lucene实现博客搜索功能

    前言 一直以来个人博客的搜索功能很蹩脚,只是自己简单用数据库的like %keyword%来实现的,所以导致经常搜不到想要找的内容,而且高亮显示.摘要截取等也不好实现,所以决定采用Lucene改写博客 ...

  3. Lucene.net站内搜索—5、搜索引擎第一版实现

    目录 Lucene.net站内搜索-1.SEO优化 Lucene.net站内搜索-2.Lucene.Net简介和分词 Lucene.net站内搜索-3.最简单搜索引擎代码 Lucene.net站内搜索 ...

  4. Katta:基于Lucene可伸缩分布式实时搜索方案

    http://www.ij2ee.com/2011/11/29/katta%EF%BC%9A%E5%9F%BA%E4%BA%8Elucene%E5%8F%AF%E4%BC%B8%E7%BC%A9%E5 ...

  5. 基于Lucene实现博客搜索功能

    前言: 最近毕设开会无意间听到小陈同学使用lucene整一个全文索引,出于好奇了解了一下发现其是结合相关分词器可以对一大段文字建立索引,然后可以实现搜索功能,本来博客一直差着一个搜索博客功能(不想通过 ...

  6. ajax+lucene pdf,基于Ajax/Lucene的站内搜索技术研究

    摘要: 站内搜索引擎是找出网站重要信息的必要工具,高效的站内搜索将有助于提升网站的价值,发挥网站应有的作用.虽然现在一些网络巨头已开始研究并应用这类工具,但整个互联网行业中,受制于技术的门槛,真正的站 ...

  7. Lucene.Net如何实现搜索结果分类统计功能

    最近我们搜易站内搜索系统的一个客户需要一个无限级分类和分类统计功能,要实现的效果如下: 但由于搜易站内搜索系统是基于Lucene.net 2.0开发的,并没有内置的分类统计搜索功能,于是乎只能自己实现 ...

  8. lucene分词器与搜索

    一.分词器 lucene针对不同的语言和虚伪提供了许多分词器,我们可以针对应用的不同的需求使用不同的分词器进行分词.我们需要注意的是在创建索引时使用的分词器与搜索时使用的分词器要保持一致.否则搜索的结 ...

  9. Lucene整理--索引的搜索

    看lucene主页(http://lucene.apache.org/)上目前lucene已经到4.9.0版本了, 参考学习的书是按照2.1版本讲解的,写的代码例子是用的3.0.2版本的,版本 的不同 ...

最新文章

  1. 【JavaSE】day03_Date、SimpleDateFormat、Calendar、Collection
  2. .net core 2.1 发布到IIS遇到的问题
  3. oracle 增长型分区,oracle 11g 分区表创建(自动按年分区)
  4. how to verify that Listener is entry point of application
  5. 单链表操作实现getelem_c语言实现--带头结点单链表操作
  6. sap的ides和ecc分别是什么意思
  7. php如何查询本周的数据,php、mysql查询当天,查询本周,查询本月的数据实例
  8. 机器学习项目实战----信用卡欺诈检测(一)
  9. 计算机中函数的括号怎么输,Excel函数中括号的使用
  10. RL(Chapter 6): Windy Gridworld
  11. 雷达威力计算 matlab,威力雷达指标
  12. JEESZ 模块开发文档
  13. shell wait 等待命令
  14. Linux压缩命令gzip、tar、zip的区别和用法
  15. “富强“, “民主“, “文明“, “和谐“, “自由“, “平等“, “公正“, “法治“, “爱国“, “敬业“, “诚信“, “友善“
  16. 点评Hack易支付 - 免签约支付平台 -彩虹易支付,1分钟快速接入支付功能
  17. equals和hashcode方法
  18. C++基础入门(超详细)
  19. 总投资2185.38亿元,澜沧江水电站传来好消息
  20. 如何做一个网页送给女朋友做生日礼物

热门文章

  1. Jetson 基本笔录
  2. 动易数据库conn.asp的问题
  3. 单声道数据转双声道_单声道转双声道方法
  4. collections.abc与abc模块是同一个东西吗?
  5. EcShop开发手册
  6. 串口调试助手版本合集
  7. python在煤矿的用途-矿用非金属制品检测前处理方法研究
  8. HDU 2542 树上战争
  9. 格式工厂 – 万能视频/音频/图片多媒体格式转换软件 (完全免费)
  10. 这是新技术时代来临,却始终都无法打开局面的“紧箍咒”