【问题标题】:Get unique GEO data from MongoDB从 MongoDB 获取唯一的 GEO 数据
【发布时间】:2012-08-02 03:35:06
【问题描述】:

我的 Mongo 数据库中有以下 GEO 数据。

db.car.ensureIndex({"loc":"2d" , "name" :1})

db.car.save({ "name":"Toyota car", "affiliation":"Toyota", "loc":{"lon":55.93939251390387,"lat":-113.999}})
    db.car.save({"name":"Honda car", "affiliation":"Honda", "loc":{"lon":58.93939251390387,"lat":-113.999}})
    db.car.save({"name":"Skoda", "affiliation":"Skoda", "loc":{"lon":52.93939251390387,"lat":-113.999}})
    db.car.save({"name":"Ford", "affiliation":"Ford", "loc":{"lon":45.93939251390387,"lat":-113.999}})
    db.car.save({"name":"Audi SUV", "affiliation":"Audi", "loc":{"lon":35.93939251390387,"lat":-113.999}})
    db.car.save({"name":"Benz", "affiliation":"Benz", "loc":{"lon":75.93939251390387,"lat":-113.999}})
    db.car.save({"name":"Skoda", "affiliation":"Skoda", "loc":{"lon":50.93939251390387,"lat":-113.999}})
    db.car.save({"name":"Benz", "affiliation":"Skoda", "loc":{"lon":51.93939251390387,"lat":-113.999}})
    db.car.save({"name":"Skoda SUV", "affiliation":"Skoda", "loc":{"lon":50.93939251390387,"lat":-113.999}})
    db.car.save({"name":"Honda", "affiliation":"Skoda", "loc":{"lon":55.93939251390387,"lat":-113.999}})

我正在尝试为给定的收音机获取最接近的“名称”。

当我运行以下查询时

db.car.find({"loc" : {"$within" : {"$center" : [[50.93939251390,-114],5]}}})

我明白了

enter code here

> db.car.find({"loc" : {"$within" : {"$center" : [[50.93939251390,-114],5]}}})
{ "_id" : ObjectId("501cc07eebb626e104d5a23b"), "name" : "Skoda", "affiliation" : "Skoda", "loc" : { "lon" : 50.93939251390387, "lat" : -113.999 } }
{ "_id" : ObjectId("501cc07eebb626e104d5a237"), "name" : "Skoda", "affiliation" : "Skoda", "loc" : { "lon" : 52.93939251390387, "lat" : -113.999 } }
{ "_id" : ObjectId("501cc07eebb626e104d5a23c"), "name" : "Benz", "affiliation" : "Skoda", "loc" : { "lon" : 51.93939251390387, "lat" : -113.999 } }
{ "_id" : ObjectId("501cc07febb626e104d5a23d"), "name" : "Skoda SUV", "affiliation" : "Skoda", "loc" : { "lon" : 50.93939251390387, "lat" : -113.999 } }

但我想检索半径中的唯一“名称”,如下所示。

> db.car.find({"loc" : {"$within" : {"$center" : [[50.93939251390,-114],5]}}})
{ "_id" : ObjectId("501cc07eebb626e104d5a23b"), "name" : "Skoda", "affiliation" : "Skoda", "loc" : { "lon" : 50.93939251390387, "lat" : -113.999 } }
{ "_id" : ObjectId("501cc07eebb626e104d5a23c"), "name" : "Benz", "affiliation" : "Skoda", "loc" : { "lon" : 51.93939251390387, "lat" : -113.999 } }
{ "_id" : ObjectId("501cc07febb626e104d5a23d"), "name" : "Skoda SUV", "affiliation" : "Skoda", "loc" : { "lon" : 50.93939251390387, "lat" : -113.999 } }

如何在其中添加约束?

【问题讨论】:

    标签: mongodb geo


    【解决方案1】:

    您无法将这种分组约束添加到您的查询中(至少对于 MongoDB 2.0.x),因此您必须在应用代码中迭代结果以提取您需要的内容。

    假设以下创建了一个示例:

    • 跟踪给定名称的匹配数会很有用
    • 您只想包含给定名称的最接近匹配项的详细信息
    • MongoDB geoNear() 按距离排序,因此第一个匹配项应该是最近的

    这是使用 JS shell:

    // Hash to save results
    > var cars = {}
    
    // Find closest cars to given geo point using geoNear
    >   db.runCommand(
            { geoNear: 'car', near : [50.93939251390,-114], num:5}
        ).results.forEach(
            function(doc) {
                if (cars[doc.obj.name]) {
                    // Increment number of matches for this name
                    cars[doc.obj.name]['matches'] = cars[doc.obj.name]['matches'] + 1;
                } else {
                    // Closest match found
                    doc.obj['matches'] = 1;
                    doc.obj['distance'] = doc.dis;
                    cars[doc.obj.name] = doc.obj;
                }
            }
        )
    
    // Check the results
    > cars
    {
        "Skoda" : {
            "_id" : ObjectId("501d108c9d2b5b2b5443712d"),
            "name" : "Skoda",
            "affiliation" : "Skoda",
            "loc" : {
                "lon" : 50.93939251390387,
                "lat" : -113.999
            },
            "matches" : 2,
            "distance" : 0.0010000000000047748
        },
        "Skoda SUV" : {
            "_id" : ObjectId("501d108c9d2b5b2b5443712f"),
            "name" : "Skoda SUV",
            "affiliation" : "Skoda",
            "loc" : {
                "lon" : 50.93939251390387,
                "lat" : -113.999
            },
            "matches" : 1,
            "distance" : 0.0010000000000047748
        },
        "Benz" : {
            "_id" : ObjectId("501d108c9d2b5b2b5443712e"),
            "name" : "Benz",
            "affiliation" : "Skoda",
            "loc" : {
                "lon" : 51.93939251390387,
                "lat" : -113.999
            },
            "matches" : 1,
            "distance" : 1.0000005000037404
        },
        "Ford" : {
            "_id" : ObjectId("501d108c9d2b5b2b5443712a"),
            "name" : "Ford",
            "affiliation" : "Ford",
            "loc" : {
                "lon" : 45.93939251390387,
                "lat" : -113.999
            },
            "matches" : 1,
            "distance" : 5.000000099996134
        }
    }
    

    此类搜索结果的一种常见方法是显示在列表中找到的所有匹配项,并将它们绘制在地图上。 理想情况下,您的地图视图将支持某种Marker Clustering,以根据用户选择的缩放级别自动对标记进行分组。

    【讨论】:

    • 太棒了!非常感谢。它有效......所以我想首先显示最近的位置,因此我在循环中进行了元素洗牌。那是对的吗 ?或任何其他可用的直接机制。
    • @Siva:正如我的假设中提到的,如果您有一个查询返回按距离排序的结果,那么给定名称的第一个结果也应该是最接近的。我更新了示例以使用geoNear 而不是$within,因此可以显式检查/包含距离。
    • 谢谢斯坦尼!!但是在 geoNear 中我们不能使用 Radius 对吗?我想用半径列出给定 Geo 中最接近的数据。请指教。
    • @Siva:我认为 geoNear 提供了使用 maxDistance 和球形查询的等效选项;您的原始搜索以某个点为中心,但没有返回距离。会阅读地理空间索引文档,尤其是The Earth is Round but Maps are Flat
    • 谢谢!!会穿过它然后回来。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-09
    • 1970-01-01
    • 1970-01-01
    • 2013-03-26
    相关资源
    最近更新 更多