如何在2.1 MongoDB C#驱动程序中使用地理空间查询?

Jos*_*ill 13 c# spatial geospatial mongodb

几天来,我一直在敲打这个.我有一个非常简单的查询,我试图在C#中运行,它在shell中看起来像这样.

db.runCommand({geoNear: "items", near: {type: "Point", coordinates : [-111.283344899999, 47.4941836]}, spherical : true, distanceMultiplier: 3963.2, maxDistance : 25});
Run Code Online (Sandbox Code Playgroud)

我的收藏看起来像这样

{    
  "_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"    
}
Run Code Online (Sandbox Code Playgroud)

根据MongoDB C#API文档中的文档,MongoDB.Driver.Builders.Query对象现在已成为遗产.所以,当我做这样的事情

 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);
Run Code Online (Sandbox Code Playgroud)

编译器抱怨它无法从IMongoQuery转换为FilterDefinition.这告诉我新的2.1库不支持旧的Query <>构建器.但是对于我的生活,我在api文档中找不到任何引用替换的文档?

有没有人能指出我在2.1 C#驱动程序中执行这个简单的地理空间查询的正确方向?我很难过.

此外,我确实在集合上创建了一个2dsphere索引,如果我没有shell命令不起作用.这是索引输出.

{
            "v" : 1,
            "key" : {
                    "Location.Coordinates" : "2dsphere"
            },
            "name" : "Location.Coordinates_2dsphere",
            "ns" : "ppn.items",
            "2dsphereIndexVersion" : 2
    }
Run Code Online (Sandbox Code Playgroud)

编辑

在深入了解TON文档后,我想我找到了它.所有示例仍然显示遗留的Query <>方法,但似乎新方法是Builders <>.Filter命名空间的一部分.所以这个代码块似乎对我有用,

 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;
Run Code Online (Sandbox Code Playgroud)

这个代码块非常混乱,它是try和fail一遍又一遍的结果.我相信我会想办法清理它.我必须从GeoJson2DGeographicCoordinates创建一个GeoJsonPoint,这似乎有点冗长,但我确信这是有充分理由的.如果有人知道,请随时发表评论.任何关于改进这个答案的建议都是非常受欢迎的,这对于文档来说是一个令人沮丧的挖掘,所以希望这有助于指出其他人正确的方向.

小智 2

这就是我的做法:

    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();
    }
Run Code Online (Sandbox Code Playgroud)