Skip to content

Add a method to convert a search result into an Eloquent query builder#610

Closed
Synchro wants to merge 2 commits into
laravel:9.xfrom
Synchro:to-eloquent
Closed

Add a method to convert a search result into an Eloquent query builder#610
Synchro wants to merge 2 commits into
laravel:9.xfrom
Synchro:to-eloquent

Conversation

@Synchro

@Synchro Synchro commented Apr 1, 2022

Copy link
Copy Markdown

I'm using Scout with Algolia, and I want to add post-search filters. Scout only has very rudimentary abilities for that, but Eloquent has lots. Once Scout has done its thing and given you a response, it would be useful to be able to convert that into an Eloquent builder and carry on adding filtering operations from there.

This PR adds a simple method to convert a Scout search result into an eloquent builder. It works by extracting the keys from the scout result and using them in a whereIn method. It uses the keys method to get the model IDs directly from the search result and doesn't look them up again unnecessarily. It's obviously somewhat inefficient because you're doing two searches, but it does make it very easy to work with.

Example:

$result = SearchableUserModel::search('Laravel')
    ->toEloquent()
    ->where('created_at', '>', Carbon::yesterday());

The test I initially wrote failed, but I discovered that this was not my doing, so I've included a failing test for that (with no other code changes) as a separate commit. It seems that calling search()->keys() triggers an error in Meilisearch that I don't understand. My method calls the same function, and so suffers the same failure – if you fix it, both will work!

@taylorotwell

Copy link
Copy Markdown
Member

Personally I just suggest filtering the collection outside of the DB after you retrieve it. This is going to break pagination counts, etc.

@Synchro

Synchro commented Apr 1, 2022

Copy link
Copy Markdown
Author

I'm aware of that, but after the conversion I can use Eloquent's own pagination instead. It also means I can use Scout with things that are not otherwise compatible with it, for example it makes it much easier to use Filament's filter UI components (which only work with Eloquent) with Scout. Operating on a collection is also massively inefficient if you have a large search result.

@JerryBels

Copy link
Copy Markdown
Contributor

I find this idea very interesting. Scout is awesome, but Eloquent capabilities in sorting, filtering etc... are on an entirely other level. It would be very useful.

@websitevirtuoso

websitevirtuoso commented Feb 13, 2023

Copy link
Copy Markdown

Sad that this request failed. Idea great. Hope to get it to work with another implementation at least. I will copy this code as good idea of using scout and Eloquent together

@johncarter-

Copy link
Copy Markdown

The other problem with this is that the order of the search results (i.e. relevancy) becomes jumbled when using a whereIn as far as I have tested. I'm still trying to find a solution to this 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants