Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDb C# GeoNear Query Construction

How do I query MongoDB for nearby geographic points using the C# driver and the GeoNear method?

The following returns points with an incorrect Distance value:

var results = myCollection.GeoNear(
    Query.GT("ExpiresOn", now), // only recent values
    latitude,
    longitude,
    20
);

I suspect I should be telling Mongo to query on the double[] Location field, but I don't know the query syntax.

like image 539
Petrus Theron Avatar asked Nov 03 '11 12:11

Petrus Theron


2 Answers

Found the answer via this and this:

var earthRadius = 6378.0; // km
var rangeInKm = 3000.0; // km

myCollection.EnsureIndex(IndexKeys.GeoSpatial("Location"));

var near =
    Query.GT("ExpiresOn", now);

var options = GeoNearOptions
    .SetMaxDistance(rangeInKm / earthRadius /* to radians */)
    .SetSpherical(true);

var results = myCollection.GeoNear(
    near,
    request.Longitude, // note the order
    request.Latitude,  // [lng, lat]
    200,
    options
);
like image 86
Petrus Theron Avatar answered Oct 24 '22 19:10

Petrus Theron


Here is a working example for driver v2.10+. It uses a correct geospatial point field type and runs $nearSphere query.

var longitude = 30d; //x
var latitude= 50d; //y
var point = new GeoJsonPoint<GeoJson2DGeographicCoordinates>(new GeoJson2DGeographicCoordinates(longitude, latitude));
var filter = Builders<TDocument>.Filter.NearSphere(doc => doc.YourLocationField, point, maxGeoDistanceInKm * 1000);
var result = await collection.Find(filter).ToListAsync();

Type of YourLocationField should be GeoJsonPoint<GeoJson2DGeographicCoordinates>.

PS. Also you can create an index of your field for faster searching like this:

collection.Indexes.CreateManyAsync(
    new []
    {
        new CreateIndexModel<TDocument>(Builders<TDocument>.IndexKeys.Geo2DSphere(it => it.YourLocationField))
    }
);
like image 23
Rodion Mostovoy Avatar answered Oct 24 '22 21:10

Rodion Mostovoy