Closed GaspariLab closed 7 years ago
Currently it's not possible, guess we should add it to the config file
searchBoolean would be very useful for me and I think for many other developers
This is necessary indeed. Currently searches like "Bugs Bunny" will return all entries with "Bugs" and all items with "Bunny" in it.
Since this is currently not available in the package you can use a workaround and call the searchBoolean
method directly, something like:
$tnt = new TNTSearch;
$driver = config('database.default');
$config = config('scout.tntsearch') + config("database.connections.$driver");
$tnt->loadConfig($config);
$tnt->setDatabaseHandle(app('db')->connection()->getPdo());
$tnt->selectIndex("users.index");
$res = $tnt->searchBoolean("Bugs Bunny", 12);
$keys = collect($res['ids'])->values()->all();
$users = User::whereIn('id', $keys)->get();
If you pack this into a method it's simple to reuse it when you need it.
Works, thank you!
I would like the same functionality. Could you add add option the the search method to indicate you want a boolean search? I tweaked the performSearch method and changed the return to searchBoolean and this worked as I wanted but now I loose the other search option. This works for this application because I only need all word matches (boolean).
protected function performSearch(Builder $builder, array $options = [])
{
$index = $builder->index ?: $builder->model->searchableAs();
$limit = $builder->limit ?: 10000;
$this->tnt->selectIndex("{$index}.index");
$this->builder = $builder;
$this->tnt->asYouType = $builder->model->asYouType ?: false;
if ($builder->callback) {
return call_user_func(
$builder->callback,
$this->tnt,
$builder->query,
$options
);
}
return $this->tnt->searchBoolean($builder->query, $limit);
}
I tried to add an additional parameter to the Scout search method but it will only accept one parameter. I think we might need to request that the Scout package add the ability to pass additional parameters.
$orders = App\Order::search('Star Trek', true)->get();
Mark
Looks like you can already. Just need pass an array instead of a search string.
Here would be the updated performSearch method in TNTSearchEngine.php
$query = [
'query' => 'Star Trek',
'exact' => true,
];
$orders = App\Order::search($query)->get();
protected function performSearch(Builder $builder, array $options = [])
{
// if an array then expects two keys - query [string], exact [boolean]
if (is_array($builder->query)) {
$builder->exact = $builder->query['exact'];
$builder->query = $builder->query['query'];
} else {
$builder->exact = false;
}
$index = $builder->index ?: $builder->model->searchableAs();
$limit = $builder->limit ?: 10000;
$this->tnt->selectIndex("{$index}.index");
$this->builder = $builder;
$this->tnt->asYouType = $builder->model->asYouType ?: false;
if ($builder->callback) {
return call_user_func(
$builder->callback,
$this->tnt,
$builder->query,
$options
);
}
return $builder->exact ? $this->tnt->searchBoolean($builder->query, $limit) : $this->tnt->search($builder->query, $limit);
}
OK - was working this some more to see if I could also get the geoSearch working. You will need to implement the geoIndexing outside of the searchable trait. Follow the instructions at https://github.com/teamtnt/tntsearch
protected function performSearch(Builder $builder, array $options = [])
{
// tests $builder->query is an array
$queryType = is_array($builder->query) ? $builder->query['type'] : false;
$index = $builder->index ?: $builder->model->searchableAs();
$limit = $builder->limit ?: 10000;
$this->tnt->selectIndex("{$index}.index");
$config = $this->tnt->config;
$this->builder = $builder;
$this->tnt->asYouType = $builder->model->asYouType ?: false;
if ($builder->callback) {
return call_user_func(
$builder->callback,
$this->tnt,
$builder->query,
$options
);
}
switch ($queryType) {
case 'geo':
// $builder->query should be passed as an array
// $params = [
// 'locaton' => [
// 'longitude' => $lng [float]
// 'latitude' => $lat [float]
// ],
// 'distance' => $distance [float]
// 'limit' => $limit [integer] [optional]
// ];
$location = $builder->query['location'];
$distance = $builder->query['distance'];
$limit = array_key_exists('limit', $builder->query) ? $builder->query['limit'] : 10;
$this->tnt = new TNTGeoSearch();
$this->tnt->loadConfig($config);
$this->tnt->selectIndex("{$index}.index");
return $this->tnt->findNearest($location, $distance, $limit);
break;
case 'boolean':
// $builder->query should be passed as an array
// $params = [
// 'query' => $query [string]
// 'limit' => $limit [integer] [optional]
// ];
$query = $builder->query['query'];
$limit = array_key_exists('limit', $builder->query) ? $builder->query['limit'] : $limit;
return $this->tnt->searchBoolean($query, $limit);
break;
default:
return $this->tnt->search($builder->query, $limit);
break;
}
}
@nticaric would you mind tagging a release with the latest commit?
Best regards,
@dominiquedutra sure, no problem
Hi!
Is there a way to use the searchBoolean method using the Scout driver?