如何在C#Mongodb强类型驱动程序中存储和查询坐标数组
我使用官方的C#MongoDb强类型驱动程序版本2.5.0与MongoDb交互 我有一个经纬度坐标数组,我想将它们存储在MongoDB中 用于存储坐标数组的类的名称是什么?所以我最近可以做下面的查询,检查给定的坐标是否在坐标数组中的任何点附近,如何实现这一点 下面是一个简单的代码来演示这个问题如何在C#Mongodb强类型驱动程序中存储和查询坐标数组,c#,.net,mongodb,mongodb-query,mongodb-.net-driver,C#,.net,Mongodb,Mongodb Query,Mongodb .net Driver,我使用官方的C#MongoDb强类型驱动程序版本2.5.0与MongoDb交互 我有一个经纬度坐标数组,我想将它们存储在MongoDB中 用于存储坐标数组的类的名称是什么?所以我最近可以做下面的查询,检查给定的坐标是否在坐标数组中的任何点附近,如何实现这一点 下面是一个简单的代码来演示这个问题 var coordinates = new List<(double latitude, double longitude)>(); //Store coor
var coordinates = new List<(double latitude, double longitude)>();
//Store coordinates array in the database
(double latitude, double longitude) point = (-33.847927, 150.6517805);
int maxDistance = 300;//Max Distance in meters
//Check if any point in the coordinates array is 300 m near the given point
var坐标=新列表();
//在数据库中存储坐标数组
(双纬度,双经度)点=(-33.847927,150.6517805);
int最大距离=300//最大距离(米)
//检查坐标数组中的任何点是否靠近给定点300 m
编辑:-
根据@CodeFuller评论中提到的这个问题:-
MangGDB不支持数组上的地理空间索引,因此考虑以下类:
class SomeDocument {
public ObjectId Id { get; set; }
public string Title { get; set; }
public List<MyClass> Locations {get; set;} = new List<MyClass>();
}
class MyClass {
public ObjectId Id { get; set; }
public GeoJsonPoint<GeoJson2DGeographicCoordinates> Location { get; set;
}
class文件{
公共对象Id{get;set;}
公共字符串标题{get;set;}
公共列表位置{get;set;}=new List();
}
类MyClass{
公共对象Id{get;set;}
公共GeoJsonPoint位置{get;set;
}
如何获取在给定点附近至少有一个点的某个文档的所有实例?并按最近的一个对它们进行排序?MongoDB.NET驱动程序为二维地理坐标提供了
MongoDB.Driver.GeoJsonObjectModel.geojson2dgeographicalcoordinates
类
以下是基本用法:
GeoJsonPoint
类型定义属性:
public class SomeDocument
{
public ObjectId Id { get; set; }
public string Title { get; set; }
public GeoJsonPoint<GeoJson2DGeographicCoordinates> Location { get; set; }
}
collection.InsertOne(new SomeDocument
{
Title = "Place #1",
Location = GeoJson.Point(new GeoJson2DGeographicCoordinates(145.89, -35.83)),
});
collection.InsertOne(new SomeDocument
{
Title = "Place #2",
Location = GeoJson.Point(new GeoJson2DGeographicCoordinates(154.98, -53.38)),
});
请注意,在MongoDB中,您可以var point = GeoJson.Point(new GeoJson2DGeographicCoordinates(145.889, -35.831));
int maxDistance = 300;
IAsyncCursor<SomeDocument> cursor = collection.FindSync(new FilterDefinitionBuilder<SomeDocument>().Near(x => x.Location, point, maxDistance: maxDistance));
// Check whether at least one is near the point
var hasNeighbors = cursor.Any();
var point=GeoJson.point(新的geojson2dgeographicalcoordinates(145.889,-35.831));
int最大距离=300;
IAsyncursor cursor=collection.FindSync(新的FilterDefinitionBuilder().Near(x=>x.Location,point,maxDistance:maxDistance));
//检查是否至少有一个靠近该点
var hasnights=cursor.Any();
MongoDB.NET驱动程序为二维地理坐标提供了
MongoDB.Driver.geoJSONObject Model.GeoJson2DGeographicCoordinates
类
以下是基本用法:
GeoJsonPoint
类型定义属性:
public class SomeDocument
{
public ObjectId Id { get; set; }
public string Title { get; set; }
public GeoJsonPoint<GeoJson2DGeographicCoordinates> Location { get; set; }
}
collection.InsertOne(new SomeDocument
{
Title = "Place #1",
Location = GeoJson.Point(new GeoJson2DGeographicCoordinates(145.89, -35.83)),
});
collection.InsertOne(new SomeDocument
{
Title = "Place #2",
Location = GeoJson.Point(new GeoJson2DGeographicCoordinates(154.98, -53.38)),
});
请注意,在MongoDB中,您可以var point = GeoJson.Point(new GeoJson2DGeographicCoordinates(145.889, -35.831));
int maxDistance = 300;
IAsyncCursor<SomeDocument> cursor = collection.FindSync(new FilterDefinitionBuilder<SomeDocument>().Near(x => x.Location, point, maxDistance: maxDistance));
// Check whether at least one is near the point
var hasNeighbors = cursor.Any();
var point=GeoJson.point(新的geojson2dgeographicalcoordinates(145.889,-35.831));
int最大距离=300;
IAsyncursor cursor=collection.FindSync(新的FilterDefinitionBuilder().Near(x=>x.Location,point,maxDistance:maxDistance));
//检查是否至少有一个靠近该点
var hasnights=cursor.Any();
更新@CodeFuller的答案 第2点
CreateOne(新的IndexKeyDefinitionBuilder..)
已折旧。请改用CreateOne(新的CreateIndexModel()…
)
以下是方法:
collection.Indexes.CreateOne(
new CreateIndexModel<TDocument>(
new IndexKeysDefinitionBuilder<TDocument>().Geo2DSphere(x => x.Location)));
collection.index.CreateOne(
新CreateIndexModel(
新的IndexKeysDefinitionBuilder().Geo2DSphere(x=>x.Location));
后来,我创建了一个通用函数,用于在启动时创建索引,如下所示:
public CreateIndexes CreateGeoSpatialIndex<TDocument>(Expression<Func<TDocument, object>> field, string collectionName)
{
var collection = _database.GetCollection<TDocument>(collectionName);
try
{
collection.Indexes.CreateOne(
new CreateIndexModel<TDocument>(
new IndexKeysDefinitionBuilder<TDocument>().Geo2DSphere(field)));
}
catch (Exception ex) when (ex.Message.Contains("already exists"))
{
// Log info
}
return this;
}
public CreateIndexes CreateGeoSpatialIndex(表达式字段,字符串集合名称)
{
var collection=\u database.GetCollection(collectionName);
尝试
{
collection.index.CreateOne(
新CreateIndexModel(
新的IndexKeysDefinitionBuilder().Geo2DSphere(字段));
}
当(例如Message.Contains(“已存在”)时捕获(异常)
{
//日志信息
}
归还这个;
}
第4点
此外,Near()对我不起作用,而是在查询时必须使用NearSphere()
var filterDefinition = new FilterDefinitionBuilder<T>().NearSphere(x => x.Location, lng, lat, maxdistance)
var filterDefinition=new FilterDefinitionBuilder().NearSphere(x=>x.位置、液化天然气、纬度、最大距离)
更新@CodeFuller的答案
第2点
CreateOne(新的IndexKeyDefinitionBuilder..)
已折旧。请改用CreateOne(新的CreateIndexModel()…
)
以下是方法:
collection.Indexes.CreateOne(
new CreateIndexModel<TDocument>(
new IndexKeysDefinitionBuilder<TDocument>().Geo2DSphere(x => x.Location)));
collection.index.CreateOne(
新CreateIndexModel(
新的IndexKeysDefinitionBuilder().Geo2DSphere(x=>x.Location));
后来,我创建了一个通用函数,用于在启动时创建索引,如下所示:
public CreateIndexes CreateGeoSpatialIndex<TDocument>(Expression<Func<TDocument, object>> field, string collectionName)
{
var collection = _database.GetCollection<TDocument>(collectionName);
try
{
collection.Indexes.CreateOne(
new CreateIndexModel<TDocument>(
new IndexKeysDefinitionBuilder<TDocument>().Geo2DSphere(field)));
}
catch (Exception ex) when (ex.Message.Contains("already exists"))
{
// Log info
}
return this;
}
public CreateIndexes CreateGeoSpatialIndex(表达式字段,字符串集合名称)
{
var collection=\u database.GetCollection(collectionName);
尝试
{
collection.index.CreateOne(
新CreateIndexModel(
新的IndexKeysDefinitionBuilder().Geo2DSphere(字段));
}
当(例如Message.Contains(“已存在”)时捕获(异常)
{
//日志信息
}
归还这个;
}
第4点
此外,Near()对我不起作用,而是在查询时必须使用NearSphere()
var filterDefinition = new FilterDefinitionBuilder<T>().NearSphere(x => x.Location, lng, lat, maxdistance)
var filterDefinition=new FilterDefinitionBuilder().NearSphere(x=>x.位置、液化天然气、纬度、最大距离)
感谢您的回答,问题在于位置字段是一个位置数组,或者换言之是一条路线或一条线。如何使用该字段实现近距离查询?MongoDB不支持数组上的地理空间索引。可以为基本上为一个点的属性创建索引。请查看详细信息。如果要使用MongoDB for查找邻近点,此时您唯一的选择是为每个路由点创建单独的MongoDB文档,并使用上面的回答中的$near
操作符。感谢回复。如果位置是嵌套文档数组的属性,我可以实现邻近查询吗?请参阅我的编辑以获得进一步解释感谢answer、 问题是