Laravel-Backpack / community-forum

A workspace to discuss improvement and feature ideas, before they're actually implemented.
28 stars 0 forks source link

[Feature Request] Laravel Scout Support #166

Open kasperbjerby opened 2 years ago

kasperbjerby commented 2 years ago

Feature Request

What's the feature you think Backpack should have?

Support for Laravel Scout

Have you already implemented a prototype solution, for your own project?

I am doing it at the moment, but it's not as easy as i had hoped

Do you see this as a core feature or an add-on?

Core feature, and i really wonder why it's not just supported out of the box yet?

welcome[bot] commented 2 years ago

Hello there! Thanks for opening your first issue on this repo!

Just a heads-up: Here at Backpack we use Github Issues only for tracking bugs. Talk about new features is also acceptable. This helps a lot in keeping our focus on improving Backpack. If you issue is not a bug/feature, please help us out by closing the issue yourself and posting in the appropriate medium (see below). If you're not sure where it fits, it's ok, a community member will probably reply to help you with that.

Backpack communication channels:

Please keep in mind Backpack offers no official / paid support. Whatever help you receive here, on Gitter, Slack or Stackoverflow is thanks to our awesome awesome community members, who give up some of their time to help their peers. If you want to join our community, just start pitching in. We take pride in being a welcoming bunch.

Thank you!

-- Justin Case The Backpack Robot

kasperbjerby commented 2 years ago

So far i am just overriding the search function and replacing this:

// if a search term was present if (request()->input('search') && request()->input('search')['value']) {     // filter the results accordingly     $this->crud->applySearchTerm(request()->input('search')['value']);     // recalculate the number of filtered rows     $filteredRows = $this->crud->count(); }

With this:

// if a search term was present if (request()->input('search') && request()->input('search')['value']) {     // search using laravel scout     $builder = $this->crud->model->search($search['value'])->get();     // recalculate the number of filtered rows     $filteredRows = $builder->count();     // limit the query to the results from laravel scout     CRUD::addClause('whereIn', 'id', $builder->pluck('id')->toArray()); }

It works, but in my mind it just feels like a bad hack

pxpm commented 2 years ago

@kasperbjerby hi there 👋 I think you are on the rigth track if you want to customize the backpack search logic. Just take in consideration that Backpack also provides the ability to customize searchLogic on each individual column, and that's the function of applySearchTerm. I don't use Laravel Scout myself, from my understanding we use kind of the same as the database driver, the difference I think is that scout builds a properly indexed table and does the most optimized query against it, thing that you should be able to do yourself in backpack by customizing the query (by default backpack uses SELECT *) (PS: it will probably be changed in future versions to use optimized queries by default) and customizing the search logic in the columns and/or make some "unsearchable" so that you don't lose memory/database resources when they don't matter for search. Having a properly designed/indexed table is the base foundation to any optimized searches/queries.

Maybe a way to implement it is providing a ScoutSearchTrait that replaces the search() function in the controller you want to search using Scout. Just need to take into consideration that developer may provide a base query in setup() method and may have changed the searchLogic on the columns. After applySearchTerm you can get the query that's going to the database with $this->crud->query->toSql()

Sorry I can't help you more here, I haven't found myself in a situation where I needed it, maybe someone that already used bump into this and can share some more experience with you.

I am moving this to the ideas repo but feel free to keep the conversation if you feel I can help you with some.

Cheers

kasperbjerby commented 2 years ago

I did end up making my own trait and using that to override the search function, but like you said, it's not the best solution and again like you said, search is kinda mixed in a bunch of different places, it also just feels wrong to search one database to get a list of id's that you then fetch from another database, just to make a search

But it works for now, I just think backpack would benefit from it, one thing is optimized search, but it also allows you to easily change both the columns and the values that the search field should match against, in one easy function inside your controller, that is the main reason I wanted to use it

pxpm commented 2 years ago

Like I told you, you are on the rigth track but I am not sure how it will end.

From what I see you already have the model instances when you do $builder = $this->crud->model->search($search['value'])->get(); ? If so make sure the models have the needed relationships, (Backpack autoloads the relationships used in the ListOperation), remove the getEntries() call and return your model collection to getEntriesAsJsonForDatatables() as first parameter. Also take into account that instead of get() you should probably paginate the results.

I am not sure it will work with filters by default because you are using the model query directly and not the crud query. You do $this->model->search() and in Backpack List we use $this->crud->query that will have the setup by developer on controller, plus the filters and the search. As I said, not sure if they will play along, it seems they could, but never tested.

Cheers