2
votes

I'm trying to search results that are within specific radius, and get the results sorted based the distance from a point (near first, far last). However, The results returned comes in the opposite sorting (far first, near last).

Here is my code:

string name = "__Location";
var strategy = new PointVectorStrategy(ctx, name);

var indexSearcher = new IndexSearcher(_dir, true);

double radious = Double.Parse(rad);

double lat = 33.8886290;
double lng = 35.4954790;

var distance = DistanceUtils.Dist2Degrees(radious, DistanceUtils.EARTH_MEAN_RADIUS_MI);

var spatialArgs = new SpatialArgs(SpatialOperation.Intersects, ctx.MakeCircle(lng, lat, distance));
var spatialQuery = strategy.MakeQuery(spatialArgs);
Point pt = ctx.MakePoint(lng, lat);
ValueSource valueSource = strategy.MakeDistanceValueSource(pt);


ValueSourceFilter vsf = new ValueSourceFilter(new QueryWrapperFilter(spatialQuery ), valueSource, 0, distance);
var filteredSpatial = new FilteredQuery(new MatchAllDocsQuery(), vsf);
var spatialRankingQuery = new FunctionQuery(valueSource);
BooleanQuery bq = new BooleanQuery();
bq.Add(filteredSpatial,Occur.MUST);
bq.Add(spatialRankingQuery,Occur.MUST);

TopDocs hits = indexSearcher.Search(bq, 10);

How can i sort the results on distance from nearest to the far?

I'm using:

  • Lucene.Net 3.0.3

  • Lucene.Net.Contrib.Spatial 3.0.3

  • Spatial4n.Core 0.3

Thanks

1

1 Answers

1
votes

This seems to be a bug in Lucene.Net.Contrib.Spatial in MakeDistanceValueSource method, so i wrote a a new DistanceValueSource class that can fix the problem, called DistanceReverseValueSource , you can find the source for class in:

https://gist.github.com/aokour/088cd6484bce5e95ba83

Here is my updated code snippet now:

string name = "__Location";
var strategy = new PointVectorStrategy(ctx, name);

var indexSearcher = new IndexSearcher(_dir, true);

double radious = Double.Parse(rad);

double lat = 33.8886290;
double lng = 35.4954790;

var distance = DistanceUtils.Dist2Degrees(radious, DistanceUtils.EARTH_MEAN_RADIUS_MI);

var spatialArgs = new SpatialArgs(SpatialOperation.Intersects, ctx.MakeCircle(lng, lat, distance));
var spatialQuery = strategy.MakeQuery(spatialArgs);
Point pt = ctx.MakePoint(lng, lat);
DistanceReverseValueSource valueSource = new DistanceReverseValueSource(strategy, pt, distance);


ValueSourceFilter vsf = new ValueSourceFilter(new QueryWrapperFilter(spatialQuery ), valueSource, 0, distance);
var filteredSpatial = new FilteredQuery(new MatchAllDocsQuery(), vsf);
var spatialRankingQuery = new FunctionQuery(valueSource);
BooleanQuery bq = new BooleanQuery();
bq.Add(filteredSpatial,Occur.MUST);
bq.Add(spatialRankingQuery,Occur.MUST);

TopDocs hits = indexSearcher.Search(bq, 10);

Now results are sorted from closest to farest!