I have a case where I need to search nearby merchants of the logged in Users's location.
The user's current city's lat long to be used for comparison with the Merchant data stored in our database which is like this -
{ "merchant_id" : "W234FDHDF##234", "location" : { "loc" : {"lat" : -58.4,"lng" : 30.8},"city" : "Cupertino" , "display_address" : [ "20956 W Homestead Rd" , "Cupertino, CA 95015"] , "postal_code" : "95015" , "country_code" : "US" , "address" : [ "20956 W Homestead Rd"] , "state_code" : "CA"} }
I am new to MongoDB and do not have much idea about it. I am using mongodb API for our Java application.
Can someone provide a guidance how to implement this in Java ?
MongoDB does not care about the field names in loc. It always first uses longitude, and then latitude. You have it the wrong way around. Instead you want this:
db.col.ensureIndex( { location.loc: "2dsphere" } );
db.col.insert( {
"merchant_id" : "W234FDHDF##234",
"location" : {
"loc" : { type: "Point", coordinates: [ 30.8, -58.4 ] },
"city" : "Cupertino",
}
} );
And then you can use a $geoNear query:
// location object
BasicDBObject myLoc = new BasicDBObject();
myLoc.append("type", "Point");
double[] loc = {-121.97679901123047,37.557369232177734};
// place comma in myLoc.append("coordinates", location);
myLoc.append("coordinates" , loc );
// command object
BasicDBObject myCmd = new BasicDBObject();
myCmd.append("geoNear", "col");
myCmd.append("near", myLoc);
myCmd.append("spherical", true);
myCmd.append("maxDistance", 50000); // in meters
System.out.println(myCmd);
CommandResult myResults = db.command(myCmd);
Related
I've a BigChainDB docker container running in my machine and I'm trying to store and retrieve geospatial data.
I've created through the MongoDB interface a 2dsphere index "location" in the "metadata" collection.
I've checked with the command:
db.people.getIndexes()
And I think that everything it's ok, in fact the result is this:
{
"v" : 2,
"key" : {
"loc" : "2dsphere"
},
"name" : "loc_2dsphere",
"ns" : "bigchain.metadata",
"2dsphereIndexVersion" : 3
}
The document that I've inserted to try some spatial queries is (this is the result of a db.metadata.findOne() query):
{
"_id" : ObjectId("5ccab10a2ce1b70022823a0f"),
"id" : "752ee9abccf83c7fd25d86c9a7d12229ae292fa27544f6881f1dbf97ccd8b413",
"metadata" : {
"location" : {
"type" : "Point",
"coordinates" : [
22.170872,
113.578749
]
}
}
}
But when I use this spatial query nothing is retrieved:
db.metadata.find(
{
"metadata": {
"location": {
$near: {
$geometry: {
type: "Point" ,
coordinates: [ 22 , 113 ]
},
}
}
}
})
I'm doing anything wrong, or is there the possibility that the index doesn't work?
There are a couple of issues here.
The first is that the index is on the field loc whereas your query is querying metadata.location.
If you try creating a 2dsphere index on metadata.location you will see the 2nd error:
"errmsg" : "invalid point in geo near query $geometry argument: { type: \"Point\", coordinates: [ 22.0, 113.0 ] } longitude/latitude is out of bounds, lng: 22 lat: 113",
This error shows that the GEOJSON point defined in your document is invalid, as the latitude value of 113 is outside the acceptable range of [-90, 90].
You would need to correct the data to be valid GEOJSON before indexing.
How Could i get longitude and lattitude using mongodb query from mongo collection
based on disatnce and certain coordinates.
{
"_id" : ObjectId("5a559b13ae201d0c05cb6f6a"),
"id" : "99623",
"city" : "Wasilla",
"cnty" : "Matanuska Susitna",
"cntyFips" : null,
"st" : "AK",
"stName" : "Alaska",
"areaCode" : "907",
"lat" : 61.5816,
"long" : -149.4393,
"rgn" : "West",
"__v" : 0
}
in this document "lat" is for latitude and "long" is for longitude.
so basically i have to get all ids based on present id lat and long which comes in a particular miles distance range.
Mongo supports GeoJSON which should allow you to perform basic queries easily on these kind of data. Examples include $geoWithin for your particular use-case.
We need a little more information on the structure of the documents that you are querying, but here is a simple example of the query available in the Mongo documentation here.
It's worth noting that you require a 2dsphere index for location data defined as GeoJSON points in order for this to be effective.
{
$nearSphere: {
$geometry: {
type : "Point",
coordinates : [ <longitude>, <latitude> ]
},
$minDistance: <distance in meters>,
$maxDistance: <distance in meters>
}
}
the mongodb document 'contents' is
{
"_id" : ObjectId("57bd1ff410ea3c38386b9194"),
"name" : "4Fingers",
"locations" : [
{
"id" : "locations1",
"address" : "68 Orchard Rd, #B1-07 Plaza Singapura, Plaza Singapura, Singapura 238839",
"phone" : "+65 6338 0631",
"openhours" : "Sunday-Thursday: 11am - 10pm \nFriday/Saturday/Eve of PH*: 11am - 11pm",
"loc" : [
"1.300626",
"103.845061"
]
}
],
"comments" : [ ],
"modified" : 1472271793525,
"created" : 1472012276724,
"createdby" : "Admin",
"modifiedby" : "Admin",
"createdipaddress" : "localhost",
"modifiedipaddress" : null,
"types" : "Restaurant",
"category" : "FoodAndBeverages",
"logo" : "logo4Fingers.png",
"tags" : "western, chicken, restaurant, food, beverages"
}
I want to find the nearest place to my location that i get from HTML5 navigation. How do i query it? Data should be sorted in near to far order.
Thank you.
To query mongodb geospatial data first you need a geo spatial index on your location field.
Your location field is a string, it needs to be a numeric type, you need to update your data accordingly.
Create your index on numerical location data:
db.collection.createIndex( { "locations.loc" : "2d" });
Query:
var projection = {"locations.loc":1};
var query = {"locations.loc": {"$near":[1.300626, 103.845061], "$maxDistance": 0.5}};
db.collection.find(query, projection).pretty();
//result:
{
"_id" : ObjectId("57bd1ff410ea3c38386b9194"),
"locations" : [
{
"loc" : [
1.300626,
103.845061
]
}
]
}
var query2 = {"locations.loc": {"$near":[2.300626, 103.845061], "$maxDistance": 0.5}};
db.collection.find(query2, projection).pretty();
//result:
{}
The query result will be sorted always, with nearest as first document.
Thanks Sergiu Zaharie.
It's working.
Then how can i returned all the field instead of returning this field only.
{
"_id" : ObjectId("57bd1ff410ea3c38386b9194"),
"locations" : [
{
"loc" : [
103.845061,
1.300626
]
}
]
}
//edit
Solved.
i just clear the projection then it work like charm.
Thank you.
I have a Mongodb collection parking_info and this is one document in the collection:
{
"_id" : ObjectId("559c152fa439a961c357f931"),
"POST_ID" : "354-20160",
"MS_ID" : "-",
"MS_SPACEID" : 0,
"CAP_COLOR" : "Grey",
"METER_TYPE" : "SS",
"SMART_METE" : "Y",
"ACTIVESENS" : "N",
"JURISDICTI" : "SFMTA",
"ON_OFF_STR" : "ON",
"OSP_ID" : 0,
"STREET_NUM" : 2016,
"STREETNAME" : "CHESTNUT ST",
"STREET_SEG" : 3.977e+006,
"RATEAREA" : "Area 5",
"SFPARKAREA" : "Marina",
"LOCATION" : "(37.8007983983, -122.4368696024)"
}
I need to convert the last field "LOCATION" : "(37.8007983983, -122.4368696024)"
here the order is latitude , then longitude.
to
"LOCATION" : { type: "Point", coordinates: [ -122.4368696024, 37.8007983983]},
The coordinate order is longitude, then latitude.
How can I apply that to all documents in the collection?
You can use the cursor method forEach() returned from the find() method to iterate the cursor, access the documents, and with each document modify the LOCATION field by using native JavaScript methods as in the following example:
db.parking_info.find({"LOCATION": {"$type": 2}}).forEach(function(doc){
var obj = {},
loc = [],
temp = doc.LOCATION.replace("(", "").replace(")", "");
loc = temp.split(",").map(function(point){
return parseFloat(point);
});
obj["type"] = "Point";
obj["coordinates"] = loc;
doc.LOCATION = obj;
db.parking_info.save(doc);
});
I have a mongodb collection with thousands of "records" with latitute and longitude, for instance:
{ "_id" : ObjectId("50ad4f686579e337e1ec2294"), "place" : "Portugal", "lat" : 41.8343, "lon" : -8.3342 }
How to update all collection "records" to be put the lat and lon inside a new field called location like this:
{ "_id" : ObjectId("50ad4f686579e337e1ec2294"), "place" : "Portugal", "location": {"lat" : 41.8343, "lon" : -8.3342 } }
Regards
fak
Basically you can not do this just using update.
You have to iterate through all the documents and update in place:
db.coll.find().forEach(
function (doc) {
doc.location = { lat: doc.lat, lon: doc.lon };
delete doc.lat;
delete doc.lon;
db.coll.save(doc);
}
)
Another option can be to do this programmatically. Going through each document. Copy it using programming language of your choice and update each of the documents the way you want
P.S when you ask someone to help - make sure that you do not have errors in your starting code. It took me quite a while to spot missing "