find nearest restaurant location using mongodb and php - php

I have a collection in MongoDB called restaurants
{
"_id" : ObjectId("5281f8d660ad39040c000001"),
"name" : "Bucksters Coffee",
"serves" : "Fast Food",
"location" : [
"23.755339",
"90.375408"
]
}
{
"_id" : ObjectId("5285cf0860ad39380b000000"),
"name" : "A1 Donuts",
"serves" : "Fast Food",
"location" : [
"18.5087016",
"73.8124984"
]
}
{
"_id" : ObjectId("5285cf3f60ad39380b000002"),
"name" : "B1 Donuts",
"serves" : "Fast Food",
"location" : [
"18.4893148",
"73.8213213"
]
}
{
"_id" : ObjectId("5285e7a260ad39380b000009"),
"name" : "C1 Donuts",
"serves" : "Fast Food",
"location" : [
"18.5308225",
"73.8474647"
]
}
And my location is ["18.5170345","73.83476"] and I want to find nearest restaurants from my location around 5 kms.
so I try following things,
for insert restaurants,
<?php
try {
$conn = new Mongo('localhost');
// access database
$db = $conn->demo;
// access collection
$collection = $db->restaurants;
$forlatadd="shivaji nagar, pune";
//for lat& Long
$prepAddr = str_replace(' ','+',$forlatadd);
$geocode=file_get_contents('http://maps.google.com/maps/api/geocode/json?address='.$prepAddr.'&sensor=false');
$output= json_decode($geocode);
$lat = $output->results[0]->geometry->location->lat;
$long = $output->results[0]->geometry->location->lng;
$a=array("$lat","$long");
//print_r($a);
$document = array( "name" => "C1 Donuts","serves" => "Fast Food","location" =>$a);
$collection->insert($document);
$collection->ensureIndex(array("location" => "2d"));
// disconnect from server
$conn->close();
} catch (MongoConnectionException $e) {
die('Error connecting to MongoDB server');
} catch (MongoException $e) {
die('Error: ' . $e->getMessage());
}
?>
And for searching data,
<?php
try {
$conn = new Mongo('localhost');
// access database
$db = $conn->demo;
// access collection
$collection = $db->restaurants;
$forlatadd="deccan, pune";
//for lat& Long
$prepAddr = str_replace(' ','+',$forlatadd);
$geocode=file_get_contents('http://maps.google.com/maps/api/geocode/json?address='.$prepAddr.'&sensor=false');
$output= json_decode($geocode);
$lat = $output->results[0]->geometry->location->lat;
$long = $output->results[0]->geometry->location->lng;
$a=array("$lat","$long");
//print_r($a);
$distance='5000';
$query = array('location' => array('$near' => array($lat,$long),'$maxDistance' => intval($distance)));
$cursor = $collection->find($query);
if ($cursor) {
echo json_encode(iterator_to_array($cursor));
} else {
echo "{ 'status' : 'false' }";
}
// disconnect from server
$conn->close();
} catch (MongoConnectionException $e) {
die('Error connecting to MongoDB server');
} catch (MongoException $e) {
die('Error: ' . $e->getMessage());
}
?>
But this gives following error
Error: localhost:27017: can't find any special indices: 2d (needs index), 2dsphere (needs index), for: { location: { $near: [ 18.5170345, 73.83476 ], $maxDistance: 5000 } }
But i already done
$collection->ensureIndex(array("location" => "2d"));
while inserting new restaurants in collection,
Please help me to find nearest restaurants from my locations.

It working for me,
Only change,
$a=array("$lat","$long"); //It takes lat & long as string
to
$a=array($long,$lat); //It takes lat&long as float.
And its working

In mongodb docs, they specify order in a location definition and indeed I had problems with the order in my previous dev :
Important Specify coordinates in this order: “longitude, latitude.”
http://docs.mongodb.org/manual/reference/operator/query/near/

Related

MongoDB / PHP / MapReduce / Reg Exp / Strings->Floats

I'm new with MapReduce, but I have a collection that I'd like to apply myself to as a chance to learn how mapreduce works.
Example Documents:
{ "filename" : "resume.doc",
"folder" : "work",
"completed": "0.5" },
{ "filename" : "spreadsheet.xls",
"folder" : "work",
"completed": "0.6" },
{ "filename" : "thesis.doc",
"folder" : "school",
"completed": "0.75" },
{ "filename" : "coverletter.doc",
"folder" : "work",
"completed": "0.6"}
So the whole idea is: I'd like to query:
{ "folder" : "work",
"completed": { $gt: 0.5 },
"filename" : new MongoRegex( "/\.[a-zA-Z]{2,}$/" ) }
And ultimately get the count of all documents by extension (.doc, .xls, etc.), as so:
{ ".doc" : 1,
".xls" : 1 }
I also realize i've got an issue because my %-completed are strings, not floats, so i think mongodb is going to need more instruction for comparing the strings.
I'm using (if it matters):
PHP extension: mongo/1.5.7
MongoDB: version 3.2.11
Seems I've stumbled upon my own answer.
Let me know if anybody comes up with a more concise/expert solution.
But this seems to work.
try {
$map = new MongoCode(
'function(){
var re = new RegExp(/(.+)\.([a-zA-Z]{2,})$/);
doctype = this.value.match(re);
if(parseFloat(this.completed)>0.5){
emit(doctype[2], parseFloat(this.completed));
}
}'
);
$reduce = new MongoCode(
'function(key, values){
var sum = 0, num = 0;
for(var i in values){
if(parseFloat(values[i])>0.5){
sum += values[i];
num += 1;
}
}
return { number_of_documents : num,
sum_of_document_completions : sum,
average_completion : (sum/num) };
}'
);
$query = array (
"folder" => "work"
);
$doctypes = $db->command(
array(
'mapReduce' => 'mydocuments',
"map" => $map,
"reduce" => $reduce,
"query" => $query,
"out" => array("inline"=>1)
)
);
print_r ( $doctypes);
}
catch(MongoCursorException $e) {
echo "error message: ".$e->getMessage()."\n";
echo "error code: ".$e->getCode()."\n";
}

Add data inside documents in Mongo DB using PHP

I want to insert data in Mongo database using PHP script, in year wise documents so that it may look like this (All years in one document);
cars{
2017{
car=Motorolla
color = blue
}
2016{
car=Toyota
color = green
}
2015{
car=Corolla
color = black
}
}
I wanted to add the document but it prompts
Document can't have $ prefixed field names: $years[0]
Is it possible to make such schema in Mongo using PHP?
Code
<?php
try {
$car = 'Motorolla';
$color = 'blue';
//$car = 'Toyota';
//$color = 'green';
//$car = 'Corolla';
//$color = 'black';
$years = array(2017, 2016, 2015);
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$bulkWriteManager = new MongoDB\Driver\BulkWrite;
$document = ['_id' => new MongoDB\BSON\ObjectID, '$years[0]' => $car, '$years[1]' => $color]; // Making a query type
try {
$bulkWriteManager->insert($document); // Inserting Document
echo 1;
} catch(MongoCursorException $e) {
/* handle the exception */
echo 0;
}
$manager->executeBulkWrite('dbName.carsCol', $bulkWriteManager); // Going to DB and Collection
} catch (MongoDB\Driver\Exception\Exception $e) {
$filename = basename(__FILE__);
echo "The $filename script has experienced an error.\n";
echo "It failed with the following exception:\n";
echo "Exception:", $e->getMessage(), "\n";
}
?>
I do not want to add whole car object at once. I want to add Year object every time. Any help will be appreciable.
OR
Any relative answer so that I may get the data from Mongo Database according to the year?
Edit1
For first time creation. - Credits goes to #Veeram
<?php
try {
$car = 'Malibu';
$color = 'red';
$years = array(2017);
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$bulkWriteManager = new MongoDB\Driver\BulkWrite;
//{"car":"chevy", "color":"black", year: 2017}
$insert = ['car' => $car, 'color' => $color, 'year' => $years[0]];
try {
$bulkWriteManager -> insert($insert); // Inserting Document
echo 1;
} catch (MongoCursorException $e) {
echo 0;
}
$manager->executeBulkWrite('dbName.mycol', $bulkWriteManager); // Going to DB and Collection
} catch (MongoDB\Driver\Exception\Exception $e) {
$filename = basename(__FILE__);
echo "The $filename script has experienced an error.\n";
echo "It failed with the following exception:\n";
echo "Exception:", $e->getMessage(), "\n";
echo "In file:", $e->getFile(), "\n";
echo "On line:", $e->getLine(), "\n";
}
?>
For the updation- Credits goes to #Veeram
<?php
try {
$car = 'ChangedCar';
$color = 'changedColor';
$years = array(2017);
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$bulkWriteManager = new MongoDB\Driver\BulkWrite;
$query = ['cars.year' => $years[0]];
//{ $push: { "cars.$.data": { "car":"chevy", "color":"black"} }}
$update = ['$push'=> ['cars.$.data'=>['car' => $car, 'color' => $color]]];
try {
$bulkWriteManager->update($query, $update); // Inserting Document
} catch(MongoCursorException $e) {
}
$manager->executeBulkWrite('dbName.mycol', $bulkWriteManager); // Going to DB and Collection
} catch (MongoDB\Driver\Exception\Exception $e) {
$filename = basename(__FILE__);
echo "The $filename script has experienced an error.\n";
echo "It failed with the following exception:\n";
echo "Exception:", $e->getMessage(), "\n";
}
?>
The problem in this code is that it successfully insert the data for the first time but when i update the data it does not update it.
Example:
There is a document named as cars . Insert the data with object of year in one document. Let's say the Object is 2017, it contains color and car Model. As showing below; (Multiple objects with years. Year is unique in whole document.)
cars{
2017{
car=Motorolla
color = blue
}
2016{
car=Toyota
color = green
}
2015{
car=Corolla
color = black
}
}
If I want to update just make an object of 2017 like 2017{car=Updated-Motorolla color =Updated-blue} and insert in the document. It should update only the year 2017 object in side the document.
cars{
2017{
car=Updated-Motorolla
color =Updated-blue
}
2016{
car=Toyota
color = green
}
2015{
car=Corolla
color = black
}
}
You can try something like this. Its not possible to perform all the Mongo db operations just based off key as a value.
The first solution is written to stay close to OP's design.
Assuming you can add a key to the year.
{
"cars": [{
"year": "2017",
"data": [{
"car": "Motorolla",
"color": "blue"
}]
}, {
"year": "2016",
"data": [{
"car": "Toyota",
"color": "green"
}]
}]
}
Makes it easy to reference the year by its value.
For example to add a new value into the data array for year 2017. You can try the below code.
Uses update positional $ operator.
query part to reference the array where 2017 record is stored.
update part using push to add the new car record to the existing data array for 2017 row.
<?php
try {
$car = 'Malibu';
$color = 'blue';
$years = [2017];
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$bulkWriteManager = new MongoDB\Driver\BulkWrite;
//{"cars.year":2017}
$query = ['cars.year' => $years[0]];
//{ $push: { "cars.$.data": { "car":"chevy", "color":"black"} }}
$update = ['$push'=> ['cars.$.data'=>['car' => $car, 'color' => $color]]];
try {
$bulkWriteManager->update($query, $update); // Update Document
echo 1;
} catch(MongoCursorException $e) {
/* handle the exception */
echo 0;
}
$manager->executeBulkWrite('dbName.carsCol', $bulkWriteManager); // Going to DB and Collection
} catch (MongoDB\Driver\Exception\Exception $e) {
$filename = basename(__FILE__);
echo "The $filename script has experienced an error.\n";
echo "It failed with the following exception:\n";
echo "Exception:", $e->getMessage(), "\n";
}
?>
For accessing data by year you can run below query.
Use query positional $operator to find the array index using the query part and reference that value in projection part.
db.collection.find({"cars.year":2017}, {"cars.$.data":1});
Alternative Solution :
This will take care of everything as just inserts
You are better off saving each car entry in its own document.
{ "year" : 2017, "car" : "Motorolla", "color" : "blue" }
{ "year" : 2016, "car" : "Toyota", "color" : "green" }
{ "year" : 2015, "car" : "Corolla", "color" : "black" }
For each entry you can use:
db.collection.insert({"year":2017, "car":"Motorolla", "color":"blue"});
PHP Code:
//{"car":"chevy", "color":"black", year: 2017}
$insert = ['car' => $car, 'color' => $color, 'year' => $years[0]];
try {
$bulkWriteManager - > insert($insert); // Inserting Document
echo 1;
} catch (MongoCursorException $e) {
/* handle the exception */
echo 0;
}
For access data by year you can use
db.collection.find({"year":2017});
Updated PHP code:
<?php
try {
$cars = ['Motorolla','Toyota', 'Corolla'] ;
$colors = ['blue', 'green', 'black'];
$years = [2017, 2016, 2015];
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$bulkWriteManager = new MongoDB\Driver\BulkWrite;
$query1 =["year" => $years[0]];
$query2 =["year" => $years[1]];
$query3 =["year" => $years[2]];
$update1 = ['$set' => ['car' => $cars[0], 'color' => $colors[0]]];
$update2 = ['$set' => ['car' => $cars[1], 'color' => $colors[1]]];
$update3 = ['$set' => ['car' => $cars[2], 'color' => $colors[2]]];
try {
$bulkWriteManager->update($query1, $update1, ["upsert" => true]);
$bulkWriteManager->update($query2, $update2, ["upsert" => true]);
$bulkWriteManager->update($query3, $update3, ["upsert" => true]);
echo 1;
} catch(MongoCursorException $e) {
/* handle the exception */
echo 0;
}
$manager->executeBulkWrite('dbName.carsCol', $bulkWriteManager); // Going to DB and Collection
} catch (MongoDB\Driver\Exception\Exception $e) {
$filename = basename(__FILE__);
echo "The $filename script has experienced an error.\n";
echo "It failed with the following exception:\n";
echo "Exception:", $e->getMessage(), "\n";
}
?>
You can perform complex queries using aggregation pipeline and you can add index to make your response quicker.
Observations:
First Solution : Harder to update/insert data, but keeps everything together so easier to read data.
Second Solution :
Cleaner and simpler to do CRUD operations on documents and use aggregation pipeline to preform complex queries.
Try to change
$document = ['_id' => new MongoDB\BSON\ObjectID, '$years[0]' => $car, '$years[1]' => $color];
to something like:
$document = ['_id' => new \MongoDB\BSON\ObjectID, $years[0] => ['car' => $car, 'color' => $color]];
it gives such result in mongo:
{ "_id" : ObjectId("58a936ecfc11985f525a4582"), "2017" : { "car" : "Motorolla", "color" : "blue" }
If data about all cars must be in one document, you need to combine data fitst:
$cars = [
'2017' => [
'car' => 'Motorolla',
'color' => 'blue'
],
'2016' => [
'car' => 'Toyota',
'color' => 'green'
],
'2015' => [
'car' => 'Corolla',
'color' => 'black'
]
];
and than
$document = ['_id' => new \MongoDB\BSON\ObjectID, 'cars' => $cars];
It gives mongo document like:
{ "_id" : ObjectId("58aabc0cfc11980f57611832"), "cars" : { "2017" : { "car" : "Motorolla", "color" : "blue" }, "2016" : { "car" : "Toyota", "color" : "green" }, "2015" : { "car" : "Corolla", "color" : "black" } } }

Telegram bot using PHP - echo doesn't work

I'm trying to use Google Maps API to calculate time and distance between two spots. My code is rather simple and it works (used codepad and it runs smoothly) but when I deploy the code and try to use the service the bot gives me wrong answers...
This is the code:
$details = "http://maps.googleapis.com/maps/api/distancematrix/json?origins=Miami&destinations=Miami+Beach&mode=driving&sensor=false";
$json = file_get_contents($details);
$arr = json_decode($json, TRUE);
$distance = $arr[rows][0][elements][0][distance][text];
$time = $arr[rows][0][elements][0][duration][text];
$response = "You should be there in $time. Total distance you'll cover: $distance";
$parameters = array('chat_id' => $chatId, "text" => $response);
$parameters["method"] = "sendMessage";
echo json_encode($parameters);
This is what the bot answers me:
"You should be there in {. Total distance you'll cover: {";
And this is the actual json:
{
"destination_addresses" : [ "Miami Beach, Florida, Stati Uniti" ],
"origin_addresses" : [ "Miami, Florida, Stati Uniti" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "15,7 km",
"value" : 15745
},
"duration" : {
"text" : "22 min",
"value" : 1322
},
"status" : "OK"
}
]
}
],
"status" : "OK"
}
What's going on?!
UPDATE: file_get_contents returns a string. So I decoded it into a PHP array but now the bot doesn't even answer!
$details = "http://maps.googleapis.com/maps/api/distancematrix/json?origins=Miami&destinations=Miami+Beach&mode=driving&sensor=false";
$json = file_get_contents($details);
$JsonObject = json_decode($json);
$distance = $JsonObject->rows[0]->elements[0]->distance->text;
$time = $JsonObject->rows[0]->elements[0]->duration->text;
$response = "You should be there in $time. Total distance you'll cover: $distance";
$chatId = "your telegram id here";
$botToken = "your bot token here";
file_get_contents("https://api.telegram.org/bot$botToken/sendMessage?chat_id=$chatId&text=$response");
This one works with file_get_contents.

JSON to Database with php

So I have this JSON for example
{
"top" : [
{
"info" : {
"ID" : 0,
"TID" : 1
},
"geo" : {
"poins" : [
[
[
-5.9,
57.1
],
[
-5.99,
57.0
]
]
]
}
},
{
"info" : {
"ID" : 1,
"TID" : 2
},
"geo" : {
"points" : [
[
[
-5.4,
57.0
],
[
-5.9,
57.0
]
]
]
}
}
]
}
I need to put this information in the DataBase with php
So I have a colum in the DB called points and it need the data inside to be looking like:
[-5.4, 57.0],[-5.9, 57.0]
I have a columb with ID so all I need is to put the points from the JSON for every ID
My php should be loking like:
connection to the database
$str = file_get_contents(the JSON);
$json = json_decode($str, true);
foreach ($json['top'] as $field) {
query='UPDATE poins_table
SET points='$field['geo']['points']'
WHERE ID='$field['info']['ID']' '
}
The code seems to be not working. What I am missing ...Any siggestions will be helpfull. Thank you
You could try following:
<?php
$str = file_get_contents('the JSON URL');
$json = json_decode($str, true);
try{
$db = new PDO("dbtype:host=yourhost;dbname=yourdbname;charset=utf8","username","password");
$query = $db->prepare('UPDATE poins_table SET points=? WHERE ID=?');
foreach ($json['top'] as $field) {
$query->execute(array(json_encode($field['geo']['points']), $field['info']['ID']));
}
} catch(PDOException $e) {
echo "Error: ". $e;
}
?>

mysql to json using php. Nested objects

Good Afternoon,
I am trying to get these results into arrays in PHP so that I can encode them into json objects and send them to the client. The results of the query look like this:
id name hours cat status
3bf JFK Int 24 pass open
3bf JFK Int 24 std closed
3bf JFK Int 24 exp open
5t6 Ohm CA 18 pass closed
5t6 Ohm CA 18 std closed
5t6 Ohm CA 18 std2 open
5t6 Ohm CA 18 exp open
...
I would like for the json objects to look like this:
{ "id": "3bf", "name": "JFK Int", "cats":
{ [ { "cat": "pass", "status": "open" },
{ "cat": "std", "status": "closed" },
{ "cat": "exp", "status": "open" } ] }
{ "id": "5t6", "name": "Ohm CA", "cats":
{ [ { "cat": "pass", "status": "closed" },
{ "cat": "std", "status": "closed" },
{ "cat": "std2", "status": "open" } ],
{ "cat": "exp", "status": "open" } ] }
I have succesfully connected to mysql and exported using json_encode using flat tables but this part I do not know how to do in PHP. Thanks.
This is the code that I have. This returns an array of json objects but it is flat, not nested:
$SQL = "SELECT id, name, hours, cat, status FROM bwt.vewPortCats";
$result = mysql_query($SQL);
$arr = array();
while ($row = mysql_fetch_assoc($result)) {
$arr[] = $row;}
$json = json_encode($arr);
echo $json;
The data itself is from a view that combines the tables ports and cats.
what you could do (sorry, not the best code I could write... short on time, ideas, and energy ;-) is something like this (I hope it still conveys the point):
$SQL = "SELECT id, name, hours, cat, status FROM bwt.vewPortCats";
$result = mysql_query($SQL);
$arr = array();
while ($row = mysql_fetch_assoc($result)) {
// You're going to overwrite these at each iteration, but who cares ;-)
$arr[$row['id']]['id'] = $row['id'];
$arr[$row['id']]['name'] = $row['name'];
// You add the new category
$temp = array('cat' => $row['cat'], 'status' => $row['status']);
// New cat is ADDED
$arr[$row['id']]['cats'][] = $temp;
}
$base_out = array();
// Kind of dirty, but doesn't hurt much with low number of records
foreach ($arr as $key => $record) {
// IDs were necessary before, to keep track of ports (by id),
// but they bother json now, so we do...
$base_out[] = $record;
}
$json = json_encode($base_out);
echo $json;
Haven't had the time to test or think twice about it, but again, I hope it conveys the idea...
With thanks to #maraspin, I have got my below code:
function merchantWithProducts($id)
{
if (
!empty($id)
) {
//select all query
$query = "SELECT
m.id as 'mMerchantID', m.name as 'merchantName', m.mobile, m.address, m.city, m.province,
p.id as 'ProductID', p.merchantId as 'pMerchantID', p.category, p.productName, p.description, p.price, p.image, p.ratingCount
FROM " . $this->table_name . " m
JOIN by_product p
ON m.id = p.merchantId
WHERE m.id = :id
GROUP BY m.id";
// prepare query statement
$stmt = $this->conn->prepare($query);
// sanitize
// $this->id = htmlspecialchars(strip_tags($this->id));
// bind values
$stmt->bindParam(":id", $this->id);
try {
$success = $stmt->execute();
if ($success === true) {
$results = $stmt->fetchAll();
$this->resultToEncode = array();
foreach ($results as $row) {
$objItemArray = array(
"merchantID" => $row->mMerchantID,
"merchantName" => $row->merchantName,
"mobile" => $row->mobile,
"address" => $row->address,
"city" => $row->city,
"province" => $row->province,
"product" => array(
"productID" => $row->ProductID,
"pMerchantID" => $row->pMerchantID,
"category" => $row->category,
"productName" => $row->productName,
"description" => $row->description,
"price" => $row->price,
"image" => $this->baseUrl . 'imagesProducts/' . $row->image,
"ratingCount" => $row->ratingCount
)
);
array_push($this->resultToEncode, $objItemArray);
}
http_response_code(200);
$httpStatusCode = '200 OK';
$pass = true;
// return json_encode($resultToEncode);
} else {
http_response_code(204);
$httpStatusCode = '204 No Content';
$pass = false;
$this->resultToEncode = 'No Record Found';
}
} catch (PDOException $pdoEx) {
http_response_code(500); // internal server error.
$httpStatusCode = '500 Internal Server Error';
$pass = false;
$this->resultToEncode = $pdoEx->getCode();
} catch (Exception $ex) {
// return $ex->getMessage();
http_response_code(404); // 404 Not Found.
$httpStatusCode = '404 Not Found';
$pass = false;
$this->resultToEncode = $ex->getMessage();
}
} else {
http_response_code(400);
$httpStatusCode = '400 bad request';
$pass = false;
$this->resultToEncode = 'User id not specified';
}
echo json_encode(array('passed' => $pass, 'Response' => $httpStatusCode, 'result' => $this->resultToEncode));
}

Categories