teamtnt / laravel-scout-tntsearch-driver

Driver for Laravel Scout search package based on https://github.com/teamtnt/tntsearch
MIT License
1.1k stars 144 forks source link

Where is the Eloquent model accessed or re-hydrated? #107

Closed CJLees01 closed 7 years ago

CJLees01 commented 7 years ago

First of all, thanks so much for this awesome package (both this and the main tntsearch) -- it's really amazing!

My Eloquent models use eager-loading quite extensively, and I'm able to short-hand this by populating the $with array on the Model to auto-load these relationships every time I request the model. It's great, but it can be a performance hit if we are finding a lot.

I've got tntsearch working and returning my model (with all eager-loaded relations):

// Returns matching model with eager-loaded relations 
MyModel::search('foo')->get();                         

Because I'm just using this for search, however, I don't need any of the eager-loaded relations to display the results -- I'm paying the eager-loading penalty when I don't need them.

If I was doing "plain" Eloquent, I can easily disable fetching the relations like this:

// Returns all models without relations
MyModel::without['relation']->get();                 

But I don't seem to be able to use this in combination with search(). Both of these return an error:

// Returns BadMethodCallException with message
'Call to undefined method Illuminate\Database\Query\Builder::search()'
MyModel::without['relation']->search('foo')->get(); 

//  Returns BadMethodCallException with message
'Method without does not exist.' 
MyModel::search('foo')->without['relation']->get();   

Can anyone think of a good way of disabling relations?

CJLees01 commented 7 years ago

OK, I think I've figured out my problem here...

MyModel::search('foo') returns a Laravel\Scout\Builder object as opposed to an Illuminate\Database\Eloquent\Builder object that we normally work with.

The Laravel\Scout\Builder is limited to the following methods such as take,orderBy,raw,first, keys and of course get. For my particular purpose it doesn't accept without, which is why I hit the error.

In case it helps others, my simple solution is to simply use keys()->all() to return an array of primary keys from tntsearch and then I can use them as needed in a plain Eloquent statement.

$ids = MyModel::search('foo')->keys()->all();
MyModel::without(['relation']->findMany($ids);