public IList <SearchItem> SearchByLocation(string queryString, double longitude, double latitude, double searchRadiusKm, int maxHits = 10) { IList <SearchItem> results; using (var searcher = new IndexSearcher(Directory, true)) using (var analyser = new StandardAnalyzer(LuceneVersion)) { var distance = DistanceUtils.Dist2Degrees(searchRadiusKm, DistanceUtils.EARTH_MEAN_RADIUS_KM); var searchArea = _spatialContext.MakeCircle(longitude, latitude, distance); var fields = new[] { Name }; var parser = new MultiFieldQueryParser(LuceneVersion, fields, analyser); parser.DefaultOperator = QueryParser.Operator.OR; // Allow multiple terms. var query = ParseQuery(queryString, parser); var spatialArgs = new SpatialArgs(SpatialOperation.Intersects, searchArea); var spatialQuery = _strategy.MakeQuery(spatialArgs); var valueSource = _strategy.MakeRecipDistanceValueSource(searchArea); var valueSourceFilter = new ValueSourceFilter(new QueryWrapperFilter(spatialQuery), valueSource, 0, 1); var filteredSpatial = new FilteredQuery(query, valueSourceFilter); var spatialRankingQuery = new FunctionQuery(valueSource); BooleanQuery bq = new BooleanQuery(); bq.Add(filteredSpatial, Occur.MUST); bq.Add(spatialRankingQuery, Occur.MUST); var hits = searcher.Search(bq, maxHits).ScoreDocs; results = MapResultsToSearchItems(hits, searcher); } return(results); }
public Query MakeQuery(Query existingQuery, SpatialStrategy spatialStrategy, string shapeWKT, SpatialRelation relation, double distanceErrorPct = 0.025, SpatialUnits?unitOverride = null) { SpatialOperation spatialOperation; var shape = ReadShape(shapeWKT, unitOverride); switch (relation) { case SpatialRelation.Within: spatialOperation = SpatialOperation.IsWithin; break; case SpatialRelation.Contains: spatialOperation = SpatialOperation.Contains; break; case SpatialRelation.Disjoint: spatialOperation = SpatialOperation.IsDisjointTo; break; case SpatialRelation.Intersects: spatialOperation = SpatialOperation.Intersects; break; case SpatialRelation.Nearby: // only sort by this, do not filter return(new FunctionQuery(spatialStrategy.MakeDistanceValueSource(shape.GetCenter()))); default: throw new ArgumentOutOfRangeException("relation"); } var args = new SpatialArgs(spatialOperation, shape) { DistErrPct = distanceErrorPct }; if (existingQuery is MatchAllDocsQuery) { return(new CustomScoreQuery(spatialStrategy.MakeQuery(args), new ValueSourceQuery(spatialStrategy.MakeRecipDistanceValueSource(shape)))); } return(spatialStrategy.MakeQuery(args)); }