简体   繁体   中英

Get unique GEO data from MongoDB

I have the following GEO data in my Mongo Data base.

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

I'm trying to get the closest "name" for given radios.

When I run the following query

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

I get

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 } }

But I want to retrive the unique "name" with in the radius like shown below.

> 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 } }

How can I add constraint in it?

You can't add that sort of grouping constraint to your query (at least, with MongoDB 2.0.x) so you would have to iterate the results in your app code to pull out what you need.

Have created an example below assuming that:

  • it would be useful to keep track of the number of matches for a given name
  • you only want to include details of the nearest match for a given name
  • MongoDB geoNear() sorts by distance so the first match should be the nearest

This is using the 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
    }
}

A common approach for this sort of search result would be to display all matches found in a list and also plot them on a map. Ideally your map view would support some sort of Marker Clustering to automatically group markers based on the user's selected zoom level.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM