-
Notifications
You must be signed in to change notification settings - Fork 11.1k
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
[8.x] Implement Full-Text Search for MySQL & PostgreSQL #40129
Conversation
749d88b
to
26672a8
Compare
26672a8
to
4e5ee00
Compare
Might also be related for SQL Server: https://docs.microsoft.com/en-us/sql/relational-databases/search/full-text-search |
I worked on 3 database migrations (EC2 to RDS, RDS to Aurora and Aurora 5.6 to 5.7) on databases ranging from 100GB to 350GB and all 3 migrations were a nightmare because of Mysql full text indexes. When using services like AWS DMS to copy data over without downtime, large table with fulltext indexes easily crash. MySQL 5.7 is very buggy with fulltext indexes and can lead to a lot of deadlocks and semaphore waits crashing after 600 seconds. Even a table with only 2 columns (id and comment) where the comment column is fulltext indexed lead to database crashes (Aurora MySQL 5.7 compatible). I don't know how 8.0 is now but I would avoid MySQL fulltext indexes like the plague. |
@driesvints @deleugpn |
RDS Aurora supports adding indexes only to read-replicas. You should not experience locking, going that route. :P |
As promised on Twitter, I would take a look at the implementation for porting it to PostgreSQL. The implementation looks solid but is very MySQL-specific (as expected). For introducing PostgreSQL support, I would have to add entirely new functions, as the current ones are exactly designed to work with MySQL. I had already been working on a common implementation, but that's not simple. PostgreSQL's fulltext engine is wholly different from the MySQL one:
These are the most impactful differences. But still is not tackling the options PostgreSQL will provide. The article Fine Tuning Full Text Search with PostgreSQL 12 easily explains how many options you have to really fine-tune the fulltext search behavior of PostgreSQL in contrast to MySQL. My advice would be to make the following changes to be able to add a very basic PostgreSQL implementation i could work on:
I am aware that supporting all PostgreSQL options for fulltext search are beyond the scope of Laravel. With my adviced changes i could add them one by one to tpetry/laravel-postgresql-enhanced. |
Another question I have is the default mode for MySQL fulltext search by Laravel? Which mode will be used? It would be best aligning the default behavior for MySQL and PostgreSQL so they kind of behave similar. The results will not be exactly similar (search term combining differences in I am not very experienced in MySQL's fulltext search and the documentation does not exactly describe how the default mode works. Is the default mode comparable to one of the PostgreSQL string functions i described? I guess making the default search behaviour the typical google one |
Placing this in draft while I talk to @tpetry on how to improve this PR. |
We simplified the API to |
Merged @tpetry's PostgreSQL PR into this one. |
Hi @driesvints, Redis also supports Fulltext search. I'd like to work on that, too. Checkout https://redis.com/redis-best-practices/indexing-patterns/full-text-search/ Could we discuss adding it to this PR? |
@humaneguy since Redis isn't a direct database engine but a key/value store, I'd rather not mix up things in this PR. |
@driesvints Ok, great. |
This is also missing |
@taylorotwell added |
I've adjusted the bindings to be back on the query builder. Please note that this now sets A final alternative could be that we check the language option inside the query builder but then it could conflict with other grammars in the future. |
@driesvints @taylorotwell A common querying pattern with fulltext indexes is to use the e.g. as stated within https://www.cloudsavvyit.com/10172/how-to-use-full-text-searches-in-mysql/ .. "When using MATCH ... AGAINST in a SELECT statement, you don’t need to repeat it in the WHERE clause. You could manually filter the results to include only records with a non-zero relevance score."
Is there any possibility of somehow making methods to create that kind of query a part of what's built-in to Eloquent? I think otherwise for many uses-cases where query results need to be ordered by relevance, we'd end up still doing something like:
Some like an |
@jonnott I think it's best that you attempt a PR for that. |
@jonnott you could start experimenting on a |
@tpetry I have a wip commit here https://github.com/jonnott/framework/commits/add-fulltext-select which could turn into a draft PR for this. I've added selectFullText() and addSelectFullText() methods. I have no clue on the PostGres side of things though.. |
Great addition, but what can be sent in the |
Look at the changes of the MySQL grammar. My enhanced PostgreSQL driver also uses the options to add some PG specific stuff. |
@tpetry Thanks So: It would be great if that could be added to the PHPDoc on the |
This PR implements natural language Full-Text Searches for MySQL and PostgreSQL. The columns that are searched in the
MATCH
part always need to exist as afulltext
index.More info:
Thanks to @tpetry for also implementing PostgreSQL support! #40229