【问题标题】:Geonear is not working - mongodb?Geonear 不工作 - mongodb?
【发布时间】:2015-11-18 17:44:39
【问题描述】:

我在集合 offers 中有以下示例 mongodb 文档。

收藏:优惠

 {
   "countryCode" : "LU",
   "geoLocation" : [ 
         {
            "lat" : 49.8914114000000026,
            "lng" : 6.0950994999999999
         }
    ]
 },
 {
   "countryCode" : "DE",
   "geoLocation" : [ 
         {
            "lat" : 50.8218536999999984,
            "lng" : 9.0202151000000015
         }
    ]
 }

要求:

根据大约50公里半径的地理位置获取文档

我尝试过的:

db.getCollection('offers').aggregate([
    {
        $geoNear: {
            near: [6.0950994999999999, 49.8914114000000026],
            distanceField: "geoLocation",
            maxDistance: 50000, //50 km radius
        }
    }
]);

问题:

它正在获取所有文档而不是搜索大约 50 公里。

任何建议将不胜感激。

【问题讨论】:

    标签: mongodb geolocation geo


    【解决方案1】:

    旧版坐标对不以米为单位返回距离,而是以弧度为单位。因此,您的 maxDistance 远大于 50 公里。见Calculate Distances with Spherical Geometry

    但也要考虑这里使用的实际距离:

    db.getCollection('offers').aggregate([
        {
            $geoNear: {
                near: [6.0950994999999999, 49.8914114000000026],
                distanceField: "distance"
        }
    ]);
    

    返回:

    {
        "_id" : ObjectId("55dc0f4b6f07ad5d3ec3b6d0"),
        "countryCode" : "DE",
        "geoLocation" : [
                {
                        "lat" : 50.8218537,
                        "lng" : 9.020215100000001
                }
        ],
        "distance" : 60.588259822017925
    }
    {
        "_id" : ObjectId("55dc0f4b6f07ad5d3ec3b6cf"),
        "countryCode" : "LU",
        "geoLocation" : [
                {
                        "lat" : 49.8914114,
                        "lng" : 6.0950995
                }
        ],
        "distance" : 61.93733827090219
    }
    

    因为“distanceField”是报告与查询点的投影距离的字段。

    因此,起点是您的文档对于地理空间查询无效。像这样修复它们:

    首先删除所有索引:

    db.offers.dropIndexes();
    

    然后修复字段:

    var bulk = db.offers.initializeOrderedBulkOp(),
        count = 0;
    
    db.offers.find({}).forEach(function(doc) { 
      //printjson(doc);
    
      var tmp = {
        "type": "Point",
        "coordinates": [doc.geoLocation[0].lng,doc.geoLocation[0].lat]
      };
      doc.geoLocation = tmp;
      printjson(doc);
    
      bulk.find({ "_id": doc._id }).updateOne({
        "$set": { "geoLocation": doc.geoLocation }
      });
      count++;
    
      if ( count % 1000 == 0 ) {
        bulk.execute();
        bulk = db.offers.initializeOrderedBulkOp();
      }
    });
    

    现在数据以正确的 GeoJSON 格式表示:

    {
        "_id" : ObjectId("55dc14856f07ad5d3ec3b6d1"),
        "countryCode" : "LU",
        "geoLocation" : {
                "type" : "Point",
                "coordinates" : [
                        6.0950995,
                        49.8914114
                ]
        }
    }
    {
        "_id" : ObjectId("55dc14856f07ad5d3ec3b6d2"),
        "countryCode" : "DE",
        "geoLocation" : {
                "type" : "Point",
                "coordinates" : [
                        9.020215100000001,
                        50.8218537
                ]
        }
    }
    

    现在创建一个索引为 2dsphere:

    db.offers.createIndex({ "geoLocation": "2dsphere" })
    

    现在您可以查询了:

    db.offers.aggregate([
        { "$geoNear": {
          "near": {
            "type": "Point",
            "coordinates": [6.0950994999999999, 49.8914114000000026]
          },
          "distanceField": "distance",
          "spherical": true,
          "maxDistance": 50000
        }}
    ])
    

    返回“近”的一个文档,或者实际上是 0 距离:

    {
        "_id" : ObjectId("55dc14856f07ad5d3ec3b6d1"),
        "countryCode" : "LU",
        "geoLocation" : {
                "type" : "Point",
                "coordinates" : [
                        6.0950995,
                        49.8914114
                ]
        },
        "distance" : 0
    }
    

    【讨论】:

    • 感谢您提供信息,但上述查询未返回任何结果集
    • @karthick.k 请参阅以上信息。您还错误地使用了$geoNear
    • 谢谢,但以下查询不适用于 maxDistance,db.getCollection('offers').aggregate([ { $geoNear: { near: [6.0950994999999999, 49.8914114000000026], distanceField: "distance",最大距离:50 / 6378.1 } ]);
    • @karthick.k 这里有很多问题,而不仅仅是一个。现在的答案是解决所有问题的完整指南。
    • 仅供参考,这个答案也适用于嵌套结构。谢谢布雷克斯。
    猜你喜欢
    • 1970-01-01
    • 2017-07-18
    • 2013-04-29
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多