Laravel Scout: only search in specific fields

8.8k views Asked by At

Laravel Scout: Is there a way that I search in only a specific field?

At the moment this line is working fine:

    $es = Element::search($q)->get();

But it searches title, shortdescription and description fields. I need it to only search in title field.

5

There are 5 answers

0
Arm092 On

If you want standard query result, but search only in a specific column (field), you can try this solution:

        Element::search($query)->rule(function($builder) {
            return [
                'must' => [
                    'match' => [
                        'some_column_name' => $builder->query
                    ]
                ]
            ];
        });

Tested on Laravel 6, but I think it will work on later versions to...

0
Kasun Sampath Weligamage On

You can do that by adding a callback function to the scout builder instance,

Person::search($searchString)->query(function($query) { 
       $query->select(['title']);  
})->get();
2
Ahmed Aboud On

for meilisearch this worked

Element::search('test',
    function ($searchEngine, string $query, array $options) use ($filter) {
        $searchEngine->resetSearchableAttributes();
        $searchEngine->updateSearchableAttributes(['field_name']);
        return $searchEngine->search($query, $options);
    }
)
0
M. Naimjon On

You can do that by adding a callback function to the scout builder instance,

Person::search($searchString)->query(function($query) { 
       $query->addSelect(['title']);  
})->get();

Worked on laravel 7

7
Renan Coelho On

You just need to change your toSearchableArray method from your model by adding the following code:

/**
 * Get the indexable data array for the model.
 *
 * @return array
 */
public function toSearchableArray()
{
    $array = $this->only('title', 'description');

    $related = $this->user->only('name', 'email');

    // Customize array...

    return array_merge($array, $related);
}

Then call php artisan scout:import "App\YourModel" to reindex the new records. 

Note:

  • $this->only('title', 'description') will search only for its title and description fields
  • $this->user->only('name', 'email') will also search for its name and email from a related Model

So you can retrieve the related data by adding ->load('user') in your search method like the following code:

public function search(Request $request)
{
    $query = $request->get('q');

    return Task::search($query)->get()->load('user');
}

UPDATE

If you're trying to retrieve the data using ->paginate() method, you must need to load the relations separately:

...
$tasks = Task::search($query)->paginate($request->get('per_page'));

$tasks->load('user');

return $tasks;

Enjoy!