Use load() after you get the object back.
https://laravel.com/docs/5.3/eloquent-relationships#eager-loading
Look at lazy eager loading.
I'm using Laravel Scout to search my records with Algoria. As a result, Laravel creates a database query like this:
SELECT * FROM table WHERE id IN (3, 7, 13)
Is there any way to alter this query? I want to use with() to get some related data too. Or should I extend some class to do it?
Use load() after you get the object back.
https://laravel.com/docs/5.3/eloquent-relationships#eager-loading
Look at lazy eager loading.
Is this the only way? For better flexibility, I'd rather prefer to have a normal Builder out of this Scout operation. Scout's Builder is more limited.
Ultimately it really the same thing. Either way same queries will be run.
@jekinney I know load() is the same, because it's Collection's method, not Builder's. I mean that I would like to get a Builder instance after I take Scout's results, because I have several other ways of getting records in this code piece. I have a Service Provider that does affect the Builder instance some way after this. But it doesn't work on Scout's Builder, because this one is very limited. It might be impossible to take a classic Builder out of it though, because Scout's results are ordered by relevance.
@RoboRobok Did you find a solution. I would also like to eager load when I receive a result from algolia.
@lars6 Yes, like @jekinney said, you can do it via load() method. The only difference is that load() works on Collection instance and with() works on Builder instance. So, to use load() you get results first and then load relations. For now, I don't think there is any easy way to load relations first.
Did you try https://laravel.com/docs/5.3/scout#configuring-searchable-data
/**
* Get the indexable data array for the model.
*
* @return array
*/
public function toSearchableArray()
{
$array = $this->with('relations')->toArray();
return $array;
}
@RoboRobok you're back.
@jlrdw Did you miss me? :)
@jekinney that's nice. But it does not work for me -_-
public function toSearchableArray()
{
$array = $this->with('forum')->toArray();
return $array;
}
The forum relation is correct I use it in other places in my application and that works fine. Any idea?
@lars6 The point of toSearchableArray() is to define what is being sent to search provider (like Algolia). I don't think that's what you are looking for.
@RoboRobok aah oke I missed that one haha :) thanks!
I think we need to stick to load() until Builder returned by search() is more alike normal Builder. I am personally okay with load().
@RoboRobok Hmm how could I do that?
I've this:
return Message::search($search)->paginate(4);
And I tried this:
return Message::search($search)->load('forum')->paginate(4);
Or do you mean this:
public function toSearchableArray()
{
$array = $this->load('forum')->toArray();
return $array;
}
But that does not work /:
return Message::search($search)->paginate(4)->load('forum');
Try this :)
return Message::search($search)->paginate(4)->load('forum');
After search() you are with Scout's Builder. load() method is part of regular Collection class, which you have after you either get() or paginate().
@jekinney @RoboRobok thanks guys appreciate it!
@mevlutozdemir That's exactly the same solution :D
@RoboRobok Not exactly. In your solution it returns an Collection. In my solution it returns a LengthAwarePaginator :D
So what shall I do If I want to search the matched text among all models? Currently I'm running the search method on all the models. @mevlutozdemir @lars6
In my case it does not return paginater I just simply gets the amount of elements I specify in paginate method parameters.
@jekinney Your code is almost close the answer. The code should be
/**
* Get the indexable data array for the model.
*
* @return array
*/
public function toSearchableArray()
{
$array = $this->with("brand")->with("category")->with("productSkus")->where("id", $this->id)->first()->toArray();
return $array;
}
Laravel : php artisan scout:import "" will index models one by one.
Please or to participate in this conversation.