#c# #mongodb #syntax #geospatial
#c# #mongodb #синтаксис #геопространственный
Вопрос:
Как мне запросить MongoDB для близлежащих географических точек, используя драйвер C # и GeoNear
метод?
Следующее возвращает точки с неправильным значением расстояния:
var results = myCollection.GeoNear(
Query.GT("ExpiresOn", now), // only recent values
latitude,
longitude,
20
);
Я подозреваю, что я должен сказать Mongo запросить поле double[] Location
, но я не знаю синтаксиса запроса.
Ответ №1:
Нашел ответ через this и 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
);
Комментарии:
1. Какую библиотеку вы использовали. У меня это не работает. Нет определения ensureIndex
2. @Habo извините слишком давно — не могу вспомнить.
Ответ №2:
Вот рабочий пример для драйвера версии v2.10 . Он использует правильный тип поля геопространственной точки и выполняет запрос $nearSphere.
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();
Тип YourLocationField
должен быть GeoJsonPoint<GeoJson2DGeographicCoordinates>
.
PS. Также вы можете создать индекс своего поля для более быстрого поиска следующим образом:
collection.Indexes.CreateManyAsync(
new []
{
new CreateIndexModel<TDocument>(Builders<TDocument>.IndexKeys.Geo2DSphere(it => it.YourLocationField))
}
);
Ответ №3:
в GeoNear
IMongoCollection
драйвере 2.x больше нет метода on. вот строго типизированный и простой способ выполнения запросов $ geoNear с использованием библиотеки MongoDB.Entities convenience.
using MongoDB.Driver;
using MongoDB.Entities;
namespace StackOverflow
{
public class Program
{
public class Cafe : Entity
{
public string Name { get; set; }
public Coordinates2D Location { get; set; }
public double DistanceMeters { get; set; }
}
private static void Main(string[] args)
{
new DB("test");
DB.Index<Cafe>()
.Key(c => c.Location, KeyType.Geo2DSphere)
.Create();
(new Cafe
{
Name = "Coffee Bean",
Location = new Coordinates2D(48.8539241, 2.2913515),
}).Save();
var searchPoint = new Coordinates2D(48.796964, 2.137456);
var cafes = DB.GeoNear<Cafe>(
NearCoordinates: searchPoint,
DistanceField: c => c.DistanceMeters,
MaxDistance: 20000)
.ToList();
}
}
}
приведенный выше код отправляет следующий запрос на сервер mongodb:
db.Cafe.aggregate([
{
"$geoNear": {
"near": {
"type": "Point",
"coordinates": [
48.796964,
2.137456
]
},
"distanceField": "DistanceMeters",
"spherical": true,
"maxDistance": NumberInt("20000")
}
}
])