Sort issue- Orderby non db column - php

I have a database with zipcodes, latitude and longitude. The other database I have has cars with zipcodes of their location. I have a function return the distance between the user location (pulled from ip address) and and the cars location (based on zipcode, latitude and longitude). I want to order the cars by the closest to the user. I am not sure the best method.
I would imagine a orderby(distance ASC), but distance isn't in the db and its obtained on a per user basis.
Language: PHP, MYSQL Framework: YII2

If this function is in MySQL (e.g. stored function) then you can order by this function fine using say, ORDER BY USER_DISTANCE(user, distance) or similar.
If the function is within PHP code (not-MySQL) then you would need to sort the results after you got the query back. PHP has various functions that would help you with this:
You likely want one of the user-defined sort functions found here:
http://php.net/manual/en/array.sorting.php

Related

Retrieving records from the database and comparing those records with the current values

I've an Android App where I take the GPS position, and I have a back-end REST service written in Laravel, and in my DB I have a table named 'GPS' which saves the GPS coordinates when I click on a 'Save' button.
When I click on the 'Save' button on My app, it must check whether the current position is within a radius of X meters when compared to one of the saved GPS on my DB.
I have no idea on doing it, is it possible?
Table GPS field are:
id, gps
Depends on how your GPS column looks like but you can easily calculate the distance from two gps (lat, lng) points with the haversine formula.
See this nice explanation in Javascript: http://www.movable-type.co.uk/scripts/latlong.html
Basically, you calculate the distance between your two points and then check if the result is within your radius.
For PHP, just search stackoverflow. For calculation with MySQL, take a look at this answer.
I have a plan for it:
1. create new route
2. create controller or use exist
3. create action
4. create function for search these points in your DB
5. provide it in JSON or XML format
Just use it from point to point.

Custom MySQL Order By depending on a PHP function value

I have a database like this
http://i.stack.imgur.com/MHEwr.jpg
I have a PHP function which will compute distance { get_distance ($person_location) } of that address from the user (web user).
I need to have a query which will use that function and return the data from the database order by distance from the user [Using { get_distance ($person_location) } function of PHP].
Can anyone help me please?
You can't sort your SQL results on the serverside by the result of a PHP function.*
There are two approaches to your general problem:
1. Move calculation to SQL
Your distance computation probably relies on geo-coordinates (latitude and longitude). Save this data for every address in the database and then do the distance computation in SQL as well.
Find more on how to do this in MySQL here: Fastest Way to Find Distance Between Two Lat/Long Points
Your todo list for this. Do the following things ONCE:
Get all your addresses from the DB
Calculate the geo coordinates for each address with your PHP API
Update your database and put those geo coordinates in extra columns
Do the following things from now on:
Every time you add a row to your table, calculate the geo coordinates beforehand with your API and add them as well
Every time you change an address in the database, calculate the new geo coordinates with your PHP API and update them as well
Every time you need to calculate the distance for the current user to all other addresses, do a SELECT query which computes the distance and does the sorting
2. Do everything in PHP
Query your database for all addresses, put them into a PHP array, compute the distance to the current user with your function and then sort your array.
I strongly suggest not to do that, however, and implement everything on the server-side (Approach 1).
* well in theory you could, by calulcating the distance for every address offline, updating a temporary table with the result, and then querying your table again using this temporary table to sort your results. However, this is even worse than doing everything in PHP, you shouldn't even consider this!
imho it is not possible to use PHP functions in your query, only thing like aggregate functions served by MySQL.
I guess you need to process through the data by PHP.

Include distance in search form

I would like to implement a search by distance on a website.
There must be a user in a living city can find all users living within 100 or 200 km for example.
I have a table in my database that stores all the cities and their coordinates.
I thought to create another table that would store the distance between all cities but my data base contains 36,000 cities and it may make a lot of records ...
How could I make this search more simply knowing that my project will be developed with Symfony and Doctrine?
Thank you beforehand
You can use the correct answer here to determine the distance between co-ordinates.
Measuring the distance between two coordinates in PHP
For performance reasons you need to use geospatial index to efficiently query such a database. For example MongoDB has a feature for this.
If performance is not an issue you can simply store locations in relational database table and calculate distances in SQL. See this question for some information about this solution: Geo-Search (Distance) in PHP/MySQL (Performance)

Levenshtein search

I work on a site which sells let's say stuff and offers a "vendors search". On this search you enter your city, or postal code, or region and a distance (in km or miles) then the site gives you a list of vendors.
To do that, I have a database with the vendors. In the form to save these vendors, you enter their full address and when you click on the save button, a request to google maps is made in order to get their latitude and longitude.
When someone does a search, I look on a table where I store all the search terms and their lat/lng.
This table looks like
+--------+-------+------+
| term | lat | lng |
+--------+-------+------+
So the first query is something very simple
select lat, lng from my_search_table where term = "the term"
If I find a result, I then search with a nice method for all the vendors in the range the visitor wants and print the result on a map.
If I don't find a result, I search with a levenshtein function because people writing bruxelle or bruxeles instead of bruxelles is something really common and I don't want to make a request to google maps all the time (I also have a "how many time searched" column in my table to get some stats)
So I request my_search_time with no where clause and loop through all results to get the smallest levensthein distance. If the smallest result is greater than 2, I request coordinates from google maps.
Here is my problem. For some countries (we have several sites all around the world), my_search_table has 15-20k+ entries... and php doesn't (really) like looping on such data (which I perfectly understand) and my request falls under the php timeout. I could increase this timeout but the problem will be the same in a few months.
So I tried a levensthein MySQL function (found on stackoverflow btw) but it's also very slow.
So my question is "is there any way to make this search fast even on very large datasets ?"
My suggestion is based on three things:
First, your data set is big. That means - it's: big enough to reject the idea of "select all" + "run levenshtein() in PHP application"
Second, you have control over your database. So you can adjust some architecture-related things
Finally, performance of SELECT queries is the most important thing, while performance for adding new data doesn't matter.
The thing is you can not perform fast levenshtein search because levenshtein itself is very slow. I mean, calculating levenshtein distance is a slow thing. Thus, you'll not be able to resolve the issue with only "smart search". You'll have to prepare some data.
Possible solution will be: create some group index and assign it during adding/updating data. That means - you'll store additional column which will store some hash (numeric, for example). When adding new data, you'll:
Perform search with levenshtein distance (for that you may either use your application or that function which you've (already mentioned) over all records in your table against inserted data
Set group index for new row to value of index which found rows in previous step have.
If nothing found, set some new group index value (it' the first row and there are no similar rows yet) - which will be different from any group index values that already present in table
To search desired rows, you'll need just select rows with same group index value. That means: your select queries will be very fast. But - yes, this will cause extremely huge overhead when adding/changing your data. Thus, it isn't applicable for case, when performance of updating/inserting matters.
You could try MySQL function SOUNDS LIKE
SELECT lat, lng FROM my_search_table WHERE term SOUNDS LIKE "the term"
You can use a kd-tree or a ternary tree to speed up the search. The idea is to use a binary search.

Matching long & lat within radius

I'm thinking of using my map coordinates to allow for location based searching and I don't know where to start.
I have a database of coordidinates - When I enter a suburb, I want to display all matches within a given radius. (i.e. search database of long/lat coords and return all coords that are in an x radius of long/lat of suburb searched)
I'm not sure how to achieve this or where to start?
Well it really depends on what database you are using.
the general technique is to use a scaler value function that uses a formula such as:
distance = ACOS(SIN(lat1)*SIN(lat2)+COS(lat1)*COS(lat2)*COS(lon2-lon1))*6371
then you can write a query like:
select *
from locations
where mydistancefunction(lat1,lng1,locations.lat,locations.lng) < #radius
Are you aware of mysql spatial extensions?Try to create a spatial column in your table i.e. Point and then use the functions that spatial extensions offer so you don't reinvent the wheel

Categories