简体   繁体   中英

C# & MongoDb 2.0 - NearSphere issue

I am currently working on MongoDB with C# and I was wondering how was working near/geoNear in .NET. I could make it work in go but I am struggling with C#

In go I have the following:

var addresses []*models.Address
bson.M{
    "location": bson.M{
        "$near": bson.M{
            "$geometry": bson.M{
                "type":        "Point",
                "coordinates": []float64{ in.Area.Longitude, in.Area.Latitude },
            },
            "$maxDistance": in.Area.Scope,
        },
    },
}, &addresses)

Now in C# , I have the following:

var options = new FindOptions<SchoolDataModel> { Limit = 10 }; // Just because I wanna limit to 10 results
var filter = NewFilterBuilder().NearSphere(s => s.Location, in.Area.Longitude, in.Area.Latitude);
return await (await GetCollection<AddressDataModel>().FindAsync(filter, options)).ToListAsync();

I am then getting the following:

"ExceptionMessage": "Command find failed: error processing query: ns=eyesapp.SchoolDataModel limit=9Tree: GEONEAR field=Location maxdist=1.79769e+308 isNearSphere=1\\nSort: {}\\nProj: {}\\n planner returned error: unable to find index for $geoNear query."

I know in go I had to create an Index so I tried the same in C# :

await GetMongoDatabase()
    .GetCollection<AddressDataModel>(typeof(AddressDataModel).Name)
    .Indexes.CreateOneAsync(new CreateIndexModel<AddressDataModel>(Builders<AddressDataModel>.IndexKeys.Geo2DSphere(x => x.Location)));

However I get the following exception when starting my ASP.NET app, when trying to create my index:

{"Command createIndexes failed: Can't extract geo keys: { _id: ObjectId.... }."}


By the end what I want to achieve is that, like in Go , be able to find addresses near the given location, with a maximal distance, but also with a predefined limit, such as 10, 20 or 50.

Thanks for any help

It turns out that everything was good but the storage of the Location itself. In my data model I had the following:

public class Location
{
    public double Latitude { get; set; }

    public double Longitude { get; set; }
}

But I was wrong, the class below is the right way to store the location

public class Location
{
    [BsonElement("type")]
    public string Type { get; } = "Point";

    [BsonElement("coordinates")]
    public double[] Coordinates { get; set; } = new double[2] { 0.0, 0.0 };

    public double Latitude
    {
        get => Coordinates[1];
        set => Coordinates[1] = value;
    }

    public double Longitude
    {
        get => Coordinates[0];
        set => Coordinates[0] = value;
    }
}

Hope it can help :)

Max

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM