I've been banging my head on this one for days. I have a very simple query I'm trying to run in C#, it looks like this in the shell.
db.runCommand({geoNear: "items", near: {type: "Point", coordinates : [-111.283344899999, 47.4941836]}, spherical : true, distanceMultiplier: 3963.2, maxDistance : 25});
My collection looks like this
{
"_id" : ObjectId(),
"Title" : "arst",
"Description" : "<p>arst</p>",
"Date" : new Date("11/29/2015 09:28:15"),
"Location" : {
"type" : "Point",
"Coordinates" : [-111.28334489999998, 47.4941836]
},
"Zip" : "59405"
}
According to the docs here MongoDB C# API Docs the MongoDB.Driver.Builders.Query object is now legacy. So when I do something like this
var point = new GeoJson2DGeographicCoordinates(double.Parse(longitude), double.Parse(latitude)) ;
var query = Query<Item>.Near(x => x.Location, new GeoJsonPoint<GeoJson2DGeographicCoordinates>(point), distance, true);
var result = collection.Find(query);
The compiler complains that it can't convert from IMongoQuery to FilterDefinition. This tells me that the legacy Query<> builder isn't supported by the new 2.1 library. But for the life of me I can't find anywhere in the api docs that reference a replacement?
Can anyone point me in the right direction on executing this simple geo-spatial query in the 2.1 C# Driver? I'm stumped.
Also, I do have a 2dsphere index created on the collection, if I didn't the shell command wouldn't work. Here's the index output.
{
"v" : 1,
"key" : {
"Location.Coordinates" : "2dsphere"
},
"name" : "Location.Coordinates_2dsphere",
"ns" : "ppn.items",
"2dsphereIndexVersion" : 2
}
EDIT
After digging through a TON of documentation I think I found it. All the examples still show the legacy Query<> method, but it seems that the new method is part of the Builders<>.Filter namespace. So this code block seems to be working for me,
double lng = double.Parse(longitude);
double lat = double.Parse(latitude);
point = new GeoJson2DGeographicCoordinates(lng, lat);
pnt = new GeoJsonPoint<GeoJson2DGeographicCoordinates>(point);
dis = distance * 1609.34;
fil = Builders<Item>.Filter.NearSphere(p => p.Location.Coordinates, pnt, dis);
filter = filter & fil;
var sort = Builders<Item>.Sort.Descending("Date");
// This is the actual query execution
List<Item> items = collection.Find(filter).Sort(sort).ToListAsync().Result;
This code block is very messy, it's the result of try and fail over and over. I'm sure I'll figure out ways to clean it up. It seems a little verbose to me that you have to create a GeoJsonPoint from a GeoJson2DGeographicCoordinates, but I'm sure there's a good reason for it. If anyone knows, please feel free to comment. Any suggestions on improving this answer are very welcome, this has been a frustrating dig through documentation, so hopefully this helps point someone else in the right direction.
MongoDB supports query operations on geospatial data.
Geospatial queries are specialized types of SQL queries supported in Athena. They differ from non-spatial SQL queries in the following ways: Using the following specialized geometry data types: point , line , multiline , polygon , and multipolygon .
MongoDB, which is a NoSQL Database, allows storing of Geospatial Data in the form of multiple GeoJSON types. Geospatial Feature of MongoDB makes it easy to store Geographical data into a database. So, basically, you can store the geospatial type data in the MongoDB in the form of GeoJSON objects.
MongoDB provides the functionality to store locations under the object type geoJSON and their coordinates against the coordinate field in [longitude, latitude] form where longitude must lie between [-180, 180] and latitude must lie between [-90,90], both inclusive.
this is how I do it on my end:
public IQueryable<TEntity> FindNear<TEntity>(string collectionName, Expression<Func<TEntity, object>> field, double longitude, double latitude, double maxDistanceInKm) where TEntity : IEntity
{
var collection = database.GetCollection<TEntity>(collectionName);
var point = GeoJson.Point(GeoJson.Geographic(longitude, latitude));
var filter = Builders<TEntity>.Filter.Near(field, point, maxDistanceInKm * 1000);
return collection.Find(filter).ToList().AsQueryable();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With