【问题标题】:MongoDb C# GeoNear Query ConstructionMongoDb C# GeoNear 查询构造
【发布时间】:2021-09-02 20:31:57
【问题描述】:

如何使用 C# 驱动程序和GeoNear 方法在 MongoDB 中查询附近的地理点?

以下返回点的距离值不正确:

var results = myCollection.GeoNear(
    Query.GT("ExpiresOn", now), // only recent values
    latitude,
    longitude,
    20
);

我怀疑我应该告诉 Mongo 查询 double[] Location 字段,但我不知道查询语法。

【问题讨论】:

    标签: c# mongodb syntax geospatial


    【解决方案1】:

    通过thisthis找到答案:

    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
    );
    

    【讨论】:

    • 你使用了什么库。它不适合我。 EnsureIndex 没有定义
    • @Habo 很抱歉很久以前 - 不记得了。
    【解决方案2】:

    这是驱动程序 v2.10+ 的工作示例。它使用正确的geospatial point 字段类型并运行$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&lt;GeoJson2DGeographicCoordinates&gt;

    附言。您还可以为您的字段创建索引以便更快地搜索,如下所示:

    collection.Indexes.CreateManyAsync(
        new []
        {
            new CreateIndexModel<TDocument>(Builders<TDocument>.IndexKeys.Geo2DSphere(it => it.YourLocationField))
        }
    );
    

    【讨论】:

      【解决方案3】:

      在 2.x 驱动程序中,IMongoCollection 上不再有 GeoNear 方法。 这是使用MongoDB.Entities 便利库进行$geoNear 查询的一种强类型且简单的方法。

      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")
              }
          }
      ])
      

      【讨论】:

        猜你喜欢
        • 2012-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多