Reputation: 31
I am a newcomer to Lucene.Net. I started trying to use spatial searches with Lucene.Net 3.0.3 release.
Could someone have a simple demo project that can help me to understand how it works? Thank you, that would be very appreciated.
Upvotes: 3
Views: 1652
Reputation: 2461
Just got spatial search working today. Below is the core SearchByLocation
method:
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);
var 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;
}
The basic example works with Lucene.NET 3.0.3
and consists of 3 classes plus a test (example use) class. I don't think it makes sense to post the whole solution here.
The key part which drives the spatial search is this:
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);
var bq = new BooleanQuery();
bq.Add(filteredSpatial,Occur.MUST);
bq.Add(spatialRankingQuery,Occur.MUST);
You can get the entire solution (VS2015) on GitHub.
Let me know if you have any questions and I'll try to help or improve the answer.
Upvotes: 3
Reputation: 2695
I've posted a Gist up this morning. https://gist.github.com/Mark-Broadhurst/8931898
It should get you going. Please note that it does not sort by distance yet (still working on that).
Upvotes: 2