У меня 3 пользователя, профиль и местоположение. Структура этих таблиц:
таблица user
user_id | email | pass | activated | banned
таблица profile
user_id | name | birthday | picture | gender | last_active
таблица location
user_id | city | country | latitude | longitude
Теперь вот условия поиска:
Чтобы отобразить поиск, мне понадобятся имя пользователя, фотография, город и страна, возраст, пол и статус онлайн / онлайн.
У меня есть запрос на заказ по местоположению:
SELECT latitude, longitude, SQRT( POW( 69.1 * ( latitude - 52.58 ) , 2 ) + POW( 69.1 * ( - 1.12 - longitude ) * COS( latitude / 57.3 ) , 2 ) ) AS distance FROM location ORDER BY distance
Может ли кто-нибудь внести свой вклад в построение запроса codeignitor для этих условий?
вы можете попробовать построить вокруг этого запроса
select l.latitude, l.longitude, SQRT( POW( 69.1 * ( l.latitude - 52.58 ) , 2 ) + POW( 69.1 * ( - 1.12 - l.longitude ) * COS( l.latitude / 57.3 ) , 2 ) ) as distance from user as u left join profile as p on p.user_id = u.id left join location as l on l.user_id = u.id where u.activated=1 and u.banned=0 order by distance desc
Могу ли я предложить вам поиск с использованием ограничений внешнего ключа в mysql
Существует ряд других оптиций в зависимости от того, насколько вы точны и насколько быстро вам это нужно. Я не буду показывать вам, как это сделать прямо здесь, но это основной запрос CodeIgniter для того, что вы просили:
$max_distance = 20; $this->db ->select('*') // Change this to only the fields you need... ->select('SQRT( POW( 69.1 * ( latitude - 52.58 ) , 2 ) + POW( 69.1 * ( - 1.12 - longitude ) * COS( latitude / 57.3 ) , 2 ) ) AS distance') ->from('user') ->where('user.active', 1) ->where('user.banned !=', 0) ->where('distance <', $max_distance) ->join('location','location.user_id=user.user_id') ->join('profile','profile.user_id=user.user_id') ->order_by('last_active','desc') ->get();
по$max_distance = 20; $this->db ->select('*') // Change this to only the fields you need... ->select('SQRT( POW( 69.1 * ( latitude - 52.58 ) , 2 ) + POW( 69.1 * ( - 1.12 - longitude ) * COS( latitude / 57.3 ) , 2 ) ) AS distance') ->from('user') ->where('user.active', 1) ->where('user.banned !=', 0) ->where('distance <', $max_distance) ->join('location','location.user_id=user.user_id') ->join('profile','profile.user_id=user.user_id') ->order_by('last_active','desc') ->get();
Обратите внимание, что расчет расстояний становится медленным, как только у вас есть сотни тысяч записей. Наиболее очевидная optmization состоит в том, чтобы сначала ограничить запрос коробочкой, чтобы сократить, чтобы вычислить расстояние для строк, которые нигде не близки, а затем сделать радиус внутри этого.