Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smarter search for gridfield Proof-of-Concept #9836

Conversation

maxime-rainville
Copy link
Contributor

@maxime-rainville maxime-rainville commented Jan 28, 2021

Issue: #9356

This is a proof-of-concept to improve the default search set up for GridField.

NOT READY FOR PEER REVIEW.

The current Gridfield primary search has the default shortcomings:

  • It only search against the first search field ... usually Name or Title.
  • It requires the search term to appear as-is in the field. e.g. "Royal Shell Dutch" will not match "Royal Dutch Shell"
  • The primary search is an alias for the matching advanced search filter field ... if you enter a search term and then open the "advanced filter" menu, you see your search term there, which is super confusing from a UX's perspective.
  • It doesn't provide an obvious way to customise the primary search field.

This Proof-of-Concept improves on this by

  • By splitting up the search expression into individual words and searching for each word across all searchable summary fields.
  • By not mapping to a visible field in the "advanced filter" menu.

This works mostly out of the box and could reasonably be shipped in 4.8 without requiring DEV to change anything.

This video illustrates the problem and then switch to this PR to illustrate how it works: https://www.youtube.com/watch?v=Z6SuDeMCrdI

@maxime-rainville
Copy link
Contributor Author

Some of the follow up points worth looking into:

  • Make sure it works with Relation (Category.Title)
  • Make sure it works with fields across different tables
  • Make sure it doesn't fall over when the summary fields include a none-searchable column
  • Provide and document a nice clean API people can use to customise the search
  • Provide a way to tweak the name of the Global search field. Right now it defaults to q
  • The search filter is kind of hackish. It adds a where statement for each term and each column combination. If your search term has 10 words and your gridifeld has 10 summary columns, you'll end up with a 100 where statements
  • Maybe add a way for this to work with fulltext search, solr and/or elastic search.
  • Maybe default to searchable_fields instead of summary_fields

@lekoala
Copy link
Contributor

lekoala commented May 11, 2021

This is a must have ! Currently, the search experience is just really bad as customers expect that typing something in a large search bar would, at least, search in all visible columns. I don't know if it's really necessary to search for all possibles combinations (leading to potentially slow queries or too many matches).. or maybe make that a configurable option rather than a fixed default.
I think it's probably safer to rely on searchable_fields and their associated filters to avoid edge cases (in many case, summary fields are not searchable because they may include computed or non db values). Basically, a global search filter that would do a $list->filterAny($params) with params being all the searchable_fields with their filter would be perfect as a first start.

@emteknetnz
Copy link
Member

emteknetnz commented Aug 13, 2021

This combination of hidden field + new filter does provide a nice experience. It does plug in well with the existing php classes + frontend

The raw SQL it generates when searching for "lorem ipsum" will look like this

 FROM "Member"
 WHERE ((Surname LIKE "%lorem%") OR (Email LIKE "%lorem%"))
 AND ((Surname LIKE "%ipsum%") OR (Email LIKE "%ipsum%"))

Which is quite different to passing in an array of values to the existing SearchContext, which does not produce a nice set of results

 FROM "Member"
 WHERE ((("Member"."FirstName" LIKE "%lorem%") OR ("Member"."FirstName" LIKE "%ipsum%))
 AND (("Member"."Surname" LIKE "%lorem%") OR ("Member"."Surname" LIKE "%ipsum%"))
 AND (("Member"."Email" LIKE "%lorem%") OR ("Member"."Email" LIKE "%ipsum%")))

My main feedback here is that the the use of a SearchFilter on where you define multiple fields via $fieldList is pretty odd and breaks from all the other SearchFilters that work on a single field

I'm just wondering if there's a way to write this SQL without the use of a SearchFilter that queries multiple columns? Maybe the logic can be moved somewhere else?

@jasonloeve
Copy link

What ever happened to this feature ? is there currently a work around ?

@lekoala
Copy link
Contributor

lekoala commented Apr 22, 2022

What ever happened to this feature ? is there currently a work around ?

you can use mine of you want

the class is here
https://github.com/lekoala/silverstripe-base/blob/master/src/ORM/Search/WildcardSearchContext.php

the idea is to override the default search context in the GridFieldFilterHeader

it's not so easy to do, because there is no way to set the searchContext, so I had to use reflection to do so. then, the idea is simply if there is only one search argument to do a filterAny for all availables filters. as an added bonus, i deal with multiple words as multiple AND/OR groups.

sample usage in model admin

    $filter =  $config->getComponentByType(GridFieldFilterHeader::class);
    $wildCardHeader = WildcardSearchContext::fromContext($filter->getSearchContext($gridfield));
    $wildCardHeader->setWildcardFilters(['FirstName', 'Surname','Email']);
    $wildCardHeader->replaceInFilterHeader($filter);

@GuySartorelli
Copy link
Member

Closed in favor of #10382

@GuySartorelli GuySartorelli deleted the pulls/4/smarter-gridfield-search branch July 1, 2022 02:53
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.

6 participants