使用一个或多个搜索词构建自动完成服务

时间:2019-07-08 12:00:23

标签: php laravel autocomplete

我正在为我的移动应用构建自动完成功能。结果需要来自我基于Laravel 5.8构建的Web服务。

api.php:

Route::get('locations/autocomplete', 'LocationsController@autocomplete');

LocationsController:

public function autocomplete(Request $request)
{
    $locations = Location::query();
    foreach($request->words as $word) {
        $locations->whereRaw('country_name LIKE ? OR state_name LIKE ? OR city_name LIKE ? ', ['%'.$word.'%','%'.$word.'%','%'.$word.'%']);
    } 
    $locations = $locations->distinct()->paginate(10);

    return AutoCompleteLocationResource::collection($locations);
}

当我对localhost:8000/api/locations/autocomplete?words[]=united&words[]=atlanta进行GET请求时,它给我的结果就像我使用$locations->orWhereRaw编写的那样:

select * from locations where 
country_name LIKE %united% OR state_name LIKE %united% OR city_name LIKE %united% 
AND 
country_name LIKE %atlanta% OR state_name LIKE %atlanta% OR city_name LIKE %atlanta%

我想要的是用AND逻辑上分隔两个块,如下所示:

select * from locations where 
(country_name LIKE %united% OR state_name LIKE %united% OR city_name LIKE %united%)
AND 
(country_name LIKE %atlanta% OR state_name LIKE %atlanta% OR city_name LIKE %atlanta%)

2 个答案:

答案 0 :(得分:1)

尝试一下:

$query = Location::query();

foreach($request->words as $word) {
   $query->where(function($qry) use ($word)  {
       $qry->where('country_name', 'like', '%'.$word.'%');
       $qry->orWhere('state_name', 'like', '%'.$word.'%');
       $qry->orWhere('city_name', 'like', '%'.$word.'%');
   });
}

$locations = $query->distinct()->paginate(10);

答案 1 :(得分:0)

显然,对whereRaw的多次调用并没有在逻辑上分隔每个查询。您必须手动执行。

这就是解决问题的方法。

$locations->whereRaw('(country_name LIKE ? OR state_name LIKE ? OR city_name LIKE ? )', ['%'.$word.'%','%'.$word.'%','%'.$word.'%']);

请注意whereRaw的第一个参数的开头和结尾处的多余'('和')'字符。