-
Type: Improvement
-
Resolution: Done
-
Priority: Minor - P4
-
Affects Version/s: 2.7.0
-
Component/s: Documentation
-
Not Needed
-
I had an issue recently figuring out how to perform a $nearSphere query with the strongly-typed methods available in the driver. I could get it to work by creating a filter with a string containing the JSON query syntax, but then the compiler would be unable to help me. I ended up creating a StackOverflow question for it, until I eventually solved it myself by tinkering: https://stackoverflow.com/questions/51987894/why-do-i-get-a-valid-but-inaccurate-nearsphere-query-when-using-the-typed-metho
I'm going to copy and paste parts of my StackOverflow question here to describe the issue:
{{var query = _col.Find($"{{ location: {{ $nearSphere: {{ $geometry: {{ type: \"Point\", coordinates: [
, {lat} ] }}, $maxDistance: {rad} }} }} }}");}}
This worked fine. My query was accurate. But wherever possible, I'd like to use the typed methods instead so the compiler can help me in the future, so I looked online to figure out how to code it, and I came up with this after reading a previous StackOverflow answer:
var filter = Builders<Node>.Filter.NearSphere(n => n.Location, lon, lat, rad);var query2 = _col.Find<Node>(filter);
The problem is that these generate different queries under the hood, and the query generated by the latter is inaccurate. It catches many more points.
{{}}
By calling .ToString() on the queries generated, I see that the first one turns into...
{{{find({ "location" : { "$nearSphere" : { "$geometry" :
, "$maxDistance" : 3 } } })}}}
...which produces an accurate result).
And the second one turns into...
{{{find({ "location" :
})}}}
..which has a different form and does not produce an accurate result.
[and then when I found the solution...]
The code for performing this type of query with version 2.7 of the C# driver is:
var filterPoint = GeoJson.Point(new GeoJson2DCoordinates(lon, lat));var filter = new FilterDefinitionBuilder<Node>().NearSphere(n => n.Location, filterPoint, rad);var query = _col.Find<Node>(filter);
{{}}
I also had to make sure I was using the MongoDB GeoJSON point data type in my model (the class I use to perform the queries):
{{}}
{{public class Node{[BsonElement("_id")]public long Id
[BsonElement("tags")]public BsonDocument Tags { get; set; }}}}{{}}
{{}}
}}{{