how to change mongodb string to geoJSON point throughout the collection - mongodb

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

Related

MongoDB delete specific nested element in object array

I want to remove this
"lightControl" : 75
from this
{
"_id" : "dfdfwef-fdfd-fd94284o-aafg",
"name" : "Testing",
"serialNumber" : "fhidfhd8ghfd",
"description" : "",
"point" : {
"type" : "Point",
"coordinates" : [
10.875447277532754,
20.940549069378634
]
},
"ancestors" : [ ],
"metadata" : {
"measurement" : {
"high" : "40000.0",
"medium" : "25000.0"
},
"digitalTwin" : {
},
"emails" : [
""
],
"lastMeasurementDate" : "2010-03-04T11:32:06.691Z",
"lightControl" : 75
},
"tags" : [ ],
"createdAt" : ISODate("2019-12-07T15:22:10.988Z"),
"updatedAt" : ISODate("2020-03-08T15:38:21.736Z"),
"_class" : "com.test.demo.api.model.Device"
}
All I want is for this specific id, to completely delete the lightControl element from metadata. I have tried $pull, but I am probably missing something. Any ideas? Thank you in advance!
Your lightControl is not in array, for nested property, use the dot wrapped in doublequotes:
MongoDB shell:
db.getCollection('yourCollectionName').update({},{$unset:{
"metadata.lightControl":""
}})
In case you have a list of objects with _id(s) instead of updating directly, assume Node.js client for MongoDB is used:
// import mongodb from "mongodb"; // ES6
const mongodb = require("mongodb");
var client = MongoClient(...);
var coll = client["yourDbName"]["yourCollectionName"];
var objs = []; // <-- The array with _id(s)
for (let i=0; i<objs.length; i++){
let id = mongodb.ObjectID(objs[i]["_id"]);
coll.update({ _id:id },{$unset:{ "metadata.lightControl":"" }});
}

MONGODB-QUERY WITH DIFFERENT DOCUMENTS

IMAGE OF MY DOCUMENT
This is one of my document with trip detailS.The return ride taking passenger will have his drop latlong of one document equal to pickup lat long of another document.But I am not able to query with taking one field and query with all other documents matching the condition.
{
"_id" : ObjectId("5a1058cd2514972098b5b4e6"),
"trip_id" : 895728,
"pass_id" : 1,
"driver_id" : 5119,
"pick_lat" : 16.863973,
"pick_lon" : 96.11646259999999,
"drop_lat" : 16.806106699999997,
"drop_lon" : 96.15429830000001,
"pickup_date" : ISODate("2017-10-27T13:00:58.000+05:30"),
"drop_date" : ISODate("2017-10-27T14:10:21.000+05:30"),
"distance" : 11.13,
"coordinates" : [
96.11646259999999,
16.863973
],
"type" : "Point",
"
loglat" : {
"type" : "Point",
"coordinates" : [
96.11646259999999,
16.863973
]
}
},

How to search nearest place in array object in mongodb

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.

MongoDB lat long search with 2D sphere indexing in Java application

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

Geo spatial queries with Doctrine MongoDB ODM

I have a 2d index on a coordinates property of my document. Using the mongo shell, I can query the collection like this;
db.adverts.find({coordinates:{$near:[20,40]}})
And that returns the following results, as expected;
{ "_id" : ObjectId("4fddac51352de93903000000"), "title" : "dummy #3", "coordinates" : { "longitude" : 22, "latitude" : 31 } }
{ "_id" : ObjectId("4fddac48352de95105000000"), "title" : "dummy #3", "coordinates" : { "longitude" : 20, "latitude" : 30 } }
{ "_id" : ObjectId("4fddaca4352de93703000000"), "title" : "dummy #3", "coordinates" : { "longitude" : 31, "latitude" : 22 } }
{ "_id" : ObjectId("4fdda6a2352de90a03000000"), "title" : "dummy title", "created" : ISODate("2012-06-17T09:42:58Z"), "coordinates" : { "longitude" : 54.1234, "latitude" : -1.234 } }
{ "_id" : ObjectId("4fdda6d8352de9c004000000"), "title" : "dummy title #2", "created" : ISODate("2012-06-17T09:43:52Z"), "coordinates" : { "longitude" : 54.34, "latitude" : -1.124 } }
However, using Doctrine as per the documentation to query the exact same collection, I get no results e.g.
$adverts = $dm->createQueryBuilder('Advert')
->field('coordinates')->near(20, 40)
->getQuery()
->execute();
$adverts->count(); // => 0
My advert yaml looks like this;
Advert:
type: document
collection: adverts
fields:
id:
id: true
title:
type: string
content:
type: string
created:
type: date
updated:
type: date
status:
type: int
distance:
type: int
indexes:
coordinates:
keys:
coordinates: 2d
referenceOne:
owner:
targetDocument: User
embedOne:
coordinates:
targetDocument: Coordinates
And the Coordinates document is like this;
Coordinates:
type: embeddedDocument
fields:
longitude:
type: float
latitude:
type: float
Any ideas why using Doctrine's ODM would return zero results on the same query?
UPDATE #1
It looks that there is a problem with Doctrine\MongoDB\Query\Builder::near() L363. The method parameter ignores the second value ($y). So only the first value is being passed to be executed.
There appears to be an implementation issue with the near() method (see https://github.com/doctrine/mongodb/pull/53). To fix my original query, I would need to do the following;
$adverts = $dm->createQueryBuilder('Advert')
->field('coordinates.latitude')->near(20)
->field('coordinates.longitude')->near(40);
$adverts->getQuery()->count(); // => 5
This contradicts the current documentation that implies both x, y coordinates can be passed to Doctrine\MongoDB\Query\Builder::near().
EDIT
To make life easier, I've created a custom repository class to provide a more intuitive solution for this inconsistency;
public function near($longitude, $latitude)
{
$query = $this->createQueryBuilder()
->field('coordinates.longitude')->near((float) $longitude)
->field('coordinates.latitude')->near((float) $latitude)
->getQuery();
return $query;
}