private void Search() { IndexReader indexReader = DirectoryReader.Open(directory); IndexSearcher indexSearcher = new IndexSearcher(indexReader); Sort idSort = new Sort(new SortField("id", SortFieldType.INT32)); //--Filter by circle (<= distance from a point) { //Search with circle //note: SpatialArgs can be parsed from a string SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, ctx.MakeCircle(-80.0, 33.0, DistanceUtils.Dist2Degrees(200, DistanceUtils.EARTH_MEAN_RADIUS_KM))); Filter filter = strategy.MakeFilter(args); TopDocs docs = indexSearcher.Search(new MatchAllDocsQuery(), filter, 10, idSort); AssertDocMatchedIds(indexSearcher, docs, 2); //Now, lets get the distance for the 1st doc via computing from stored point value: // (this computation is usually not redundant) Document doc1 = indexSearcher.Doc(docs.ScoreDocs[0].Doc); String doc1Str = doc1.GetField(strategy.FieldName).GetStringValue(); //assume doc1Str is "x y" as written in newSampleDocument() int spaceIdx = doc1Str.IndexOf(' '); double x = double.Parse(doc1Str.Substring(0, spaceIdx - 0), CultureInfo.InvariantCulture); double y = double.Parse(doc1Str.Substring(spaceIdx + 1), CultureInfo.InvariantCulture); double doc1DistDEG = ctx.CalcDistance(args.Shape.Center, x, y); assertEquals(121.6d, DistanceUtils.Degrees2Dist(doc1DistDEG, DistanceUtils.EARTH_MEAN_RADIUS_KM), 0.1); //or more simply: assertEquals(121.6d, doc1DistDEG * DistanceUtils.DEG_TO_KM, 0.1); } //--Match all, order by distance ascending { IPoint pt = ctx.MakePoint(60, -50); ValueSource valueSource = strategy.MakeDistanceValueSource(pt, DistanceUtils.DEG_TO_KM); //the distance (in km) Sort distSort = new Sort(valueSource.GetSortField(false)).Rewrite(indexSearcher); //false=asc dist TopDocs docs = indexSearcher.Search(new MatchAllDocsQuery(), 10, distSort); AssertDocMatchedIds(indexSearcher, docs, 4, 20, 2); //To get the distance, we could compute from stored values like earlier. // However in this example we sorted on it, and the distance will get // computed redundantly. If the distance is only needed for the top-X // search results then that's not a big deal. Alternatively, try wrapping // the ValueSource with CachingDoubleValueSource then retrieve the value // from the ValueSource now. See LUCENE-4541 for an example. } //demo arg parsing { SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, ctx.MakeCircle(-80.0, 33.0, 1)); SpatialArgs args2 = new SpatialArgsParser().Parse("Intersects(BUFFER(POINT(-80 33),1))", ctx); assertEquals(args.toString(), args2.toString()); } indexReader.Dispose(); }
//query builders public QueryHelper <TModel> SortByDistanceFromPoint(Expression <Func <TModel, object> > exp, double longitude, double latitude, bool desc = false) { if (sort == null) { sort = new Sort(); sorts = new List <SortField>(); } string key = getName(exp.Body.ToString()); var strat = new PointVectorStrategy(ctx, key); IPoint pt = ctx.MakePoint(longitude, longitude); ValueSource valueSource = strat.MakeDistanceValueSource(pt, DistanceUtils.DEG_TO_KM); //the distance (in km) sort = new Sort(valueSource.GetSortField(desc)); //.Rewrite(indexSearcher);//false=asc dist return(this); }