初识lunece(地理空间检索)

  1 package test.test;
  2 
  3 import java.io.BufferedReader;
  4 import java.io.File;
  5 import java.io.IOException;
  6 import java.io.InputStreamReader;
  7 import java.util.Date;
  8 
  9 import org.apache.lucene.analysis.Analyzer;
 10 import org.apache.lucene.document.Document;
 11 import org.apache.lucene.document.DoubleField;
 12 import org.apache.lucene.document.Field;
 13 import org.apache.lucene.document.StringField;
 14 import org.apache.lucene.document.Field.Store;
 15 import org.apache.lucene.document.TextField;
 16 import org.apache.lucene.index.DirectoryReader;
 17 import org.apache.lucene.index.IndexReader;
 18 import org.apache.lucene.index.IndexWriter;
 19 import org.apache.lucene.index.IndexWriterConfig;
 20 import org.apache.lucene.queryparser.classic.ParseException;
 21 import org.apache.lucene.queryparser.classic.QueryParser;
 22 import org.apache.lucene.search.Filter;
 23 import org.apache.lucene.search.IndexSearcher;
 24 import org.apache.lucene.search.Query;
 25 import org.apache.lucene.search.ScoreDoc;
 26 import org.apache.lucene.search.TopDocs;
 27 import org.apache.lucene.spatial.SpatialStrategy;
 28 import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
 29 import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
 30 import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
 31 import org.apache.lucene.spatial.query.SpatialArgs;
 32 import org.apache.lucene.spatial.query.SpatialOperation;
 33 import org.apache.lucene.store.Directory;
 34 import org.apache.lucene.store.FSDirectory;
 35 import org.apache.lucene.util.Version;
 36 import org.wltea.analyzer.lucene.IKAnalyzer;
 37 
 38 import com.spatial4j.core.context.SpatialContext;
 39 import com.spatial4j.core.distance.DistanceUtils;
 40 import com.spatial4j.core.shape.Point;
 41 import com.spatial4j.core.shape.impl.PointImpl;
 42 
 43 public class Index_test {
 44 
 45     /**
 46      * If you want a typical geodetic context, just reference GEO.
 47      * */
 48     private static SpatialContext ctx = SpatialContext.GEO;
 49 
 50     
 51     
 52     
 53     private static SpatialPrefixTree spatialPrefixTree = new GeohashPrefixTree(ctx, 11);
 54 
 55     /**
 56      * 抽象类
 57      * 空间检索的主要类
 58      * spatialstrategy封装了基于形状检索的方法,以及基于形状过滤器的方法。
 59      * */
 60     private static SpatialStrategy spatialStrategy = new RecursivePrefixTreeStrategy(spatialPrefixTree, "fieldName");
 61 
 62     
 63     private static String indexPath = "/home/xy/study/index/";
 64     
 65     private static void buildIndex() throws IOException {
 66         
 67         Directory directory =  FSDirectory.open(new File(indexPath));
 68         Analyzer ikAnalyzer = new IKAnalyzer();//分析器 名称
 69         IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_46, ikAnalyzer);
 70         IndexWriter indexWriter = new IndexWriter(directory, iwConfig);
 71         
 72         
 73         BufferedReader br = null;
 74         try {
 75             // 逐行添加测试数据到索引中,测试数据文件和源文件在同一个目录下
 76             br = new BufferedReader(new InputStreamReader(
 77                     Index_test.class.getResourceAsStream("data")));
 78             
 79             
 80             int count = 0;
 81             String line = null;
 82             while ((line = br.readLine()) != null) {
 83                 String[] strarr = line.split("	");
 84                 
 85                 Document doc = new Document();
 86                 double lng = Double.parseDouble(strarr[2]);
 87                 double lat = Double.parseDouble(strarr[3]);
 88                 
 89                 
 90                 
 91                 //StringField 与 TextField区别,TextField会分词存储,StringField为不分词存储
 92                 doc.add(new StringField("myid", strarr[0], Store.YES));
 93                 doc.add(new TextField("name", strarr[1], Store.YES));
 94                 doc.add(new DoubleField("lng", lng, Store.YES));
 95                 doc.add(new DoubleField("lat", lat, Store.YES));
 96                 
 97                 //创建图形索引,如果不创建,图形过滤器将失去效果,即为图形过滤器做准备
 98                 Field[] fields = spatialStrategy.createIndexableFields(ctx.makePoint(lng, lat));
 99                 for(Field field:fields){
100                     doc.add(field);
101                 }
102                 
103                 indexWriter.addDocument(doc);
104                 count++;
105             }
106             
107             System.out.println("创建缓存:"+count);
108         } catch (Exception e) {
109             e.printStackTrace();
110         } finally {
111             if (br != null) {
112                 try {
113                     br.close();
114                     indexWriter.commit();
115                     indexWriter.close();
116                 } catch (IOException e) {
117                     e.printStackTrace();
118                 }
119             }
120         }
121     }
122 
123     
124     
125     
126     private static void search() throws IOException, ParseException {
127         String keyword = "美发";
128         double lng = 116.3838183,lat = 39.9629015 ,distance = 300.0;
129 //        
130         Directory dir = FSDirectory.open(new File(indexPath));
131         IndexReader indexReader = DirectoryReader.open(dir);
132         
133         IndexSearcher indexSearcher = new IndexSearcher(indexReader);
134         
135         
136 //        Point point = new PointImpl(lng, lat, ctx);
137         //以point为中心,半径为0.3km为半径
138         SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,ctx.makeCircle(lng,lat, DistanceUtils.dist2Degrees(
139                 distance / 1000.0, DistanceUtils.EARTH_MEAN_RADIUS_KM)));
140         
141         Analyzer ikAnalyzer = new IKAnalyzer();//分词 名称
142         QueryParser queryParser = new QueryParser(Version.LUCENE_46,"name", ikAnalyzer);
143         Query query = queryParser.parse(keyword);
144         //图形过滤器
145         Filter filter = spatialStrategy.makeFilter(args);
146         TopDocs topDocs = indexSearcher.search(query, filter, 100);
147         
148         
149         System.out.println("总找到:"+topDocs.totalHits);
150         
151         
152         ScoreDoc[] scoreDocs = topDocs.scoreDocs;
153         for(ScoreDoc scoreDoc:scoreDocs){
154             int doc = scoreDoc.doc;
155             Document document = indexReader.document(doc);
156             System.out.println(document.get("myid")+"	"+document.get("name")+"	"+document.get("lng")+"	"+document.get("lat")+"	"+scoreDoc.score);
157         }
158     }
159     
160     
161     
162     
163     
164     
165     
166     private static void search_2() throws IOException, ParseException {
167         String keyword = "30";
168         double lng = 116.3838183,lat = 39.9629015 ,distance = 3000.0;
169 //        
170         Directory dir = FSDirectory.open(new File(indexPath));
171         IndexReader indexReader = DirectoryReader.open(dir);
172         
173         IndexSearcher indexSearcher = new IndexSearcher(indexReader);
174         
175         SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,ctx.makeCircle(lng, lat, DistanceUtils.dist2Degrees(
176                 distance / 1000.0, DistanceUtils.EARTH_MEAN_RADIUS_KM)));
177 //        Filter filter = spatialStrategy.makeFilter(args);
178         
179         
180         Analyzer ikAnalyzer = new IKAnalyzer();//分词 名称
181         QueryParser queryParser = new QueryParser(Version.LUCENE_46,"myid", ikAnalyzer);
182         Query query = queryParser.parse(keyword);
183 
184         TopDocs topDocs = indexSearcher.search(query, null, 10);
185         
186         
187         System.out.println("总找到:"+topDocs.totalHits);
188         
189         
190         ScoreDoc[] scoreDocs = topDocs.scoreDocs;
191         for(ScoreDoc scoreDoc:scoreDocs){
192             int doc = scoreDoc.doc;
193             Document document = indexReader.document(doc);
194             System.out.println(document.get("myid")+"	"+document.get("name")+"	"+document.get("lng")+"	"+document.get("lat")+"	"+scoreDoc.score);
195         }
196     
197     }
198     
199     
200     
201     
202     public static void main(String[] args) {
203         try {
204             
205 //            buildIndex();
206             
207             
208 //            long l1 = new Date().getTime();
209 //            search();
210 //            long l2 = new Date().getTime();
211 //            System.out.println(l2 - l1);
212             
213             search_2();
214         } catch (Exception e) {
215             e.printStackTrace();
216         }
217         
218     }
219
测试数据
12 时尚码头美容美发热烫特价 116.3838183 39.9629015 17 审美个人美容美发套餐 116.386564 39.966102 23 海底捞吃300送300 116.38629 39.9629573 26 仅98元!享原价335元李老爹 116.3846175 39.9629125 29 都美造型烫染美发护理套餐 116.38629 39.9629573 30 仅售55元!原价80元的老舍茶馆相声下午场 116.0799914 39.9655391 33 仅售55元!原价80元的新笑声客栈早场 116.0799914 39.9655391 34 仅售39元(红色礼盒)!原价80元的平谷桃 116.0799914 39.9655391 46 仅售38元!原价180元地质礼堂白雪公主 116.0799914 39.9655391 49 仅99元!享原价342.7元自助餐 116.0799914 39.9655391 58 桑海教育暑期学生报名培训九折优惠券 116.0799914 39.9655391 59 全国发货:仅29元!贝玲妃超模粉红高光光 116.0799914 39.9655391 65 海之屿生态水族用品店抵用券 116.0799914 39.9655391 67 小区东门时尚烫染个人护理美发套餐 116.3799914 39.9655391 74 《郭德纲相声专辑》CD套装 116.0799915 39.9655391


220 }
想的都是好
原文地址:https://www.cnblogs.com/freezone/p/5124101.html