Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lucene.Net 3.0.3 Spatial search

Tags:

lucene.net

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.

like image 701
pink c Avatar asked Dec 11 '25 05:12

pink c


2 Answers

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.

like image 147
David Kirkland Avatar answered Dec 15 '25 23:12

David Kirkland


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).

like image 26
Mark Broadhurst Avatar answered Dec 15 '25 23:12

Mark Broadhurst



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!