PHP/MySQL: match / against escaping stopword - php

Here's my query:
SELECT * from description WHERE (match(description) AGAINST ( '+will +smith' in boolean mode))
I'm aware that will is a stopword that's why i'm getting an empty result.
How would it work that i can still use both words for this query? Do i need to escape it in somekind of way?

There isn't a way to "escape" a stopword for a given search. Think of it this way: when creating the fulltext index, it skips indexing words if they are stopwords. That is, the words are not stored in the fulltext index. So you can't subsequently escape the word in a given search and have a word magically appear in the fulltext index since that wasn't included when the index was created.
Assuming you are using fulltext search with InnoDB, the solution is apparently to define your own table storing stopwords. Then you can put a customized set of words into the table, and use the configuration variable innodb_ft_server_stopword_table to make your instance of MySQL use your custom table before creating your fulltext index. This way, the word you want to be indexed will be included as it builds the fulltext index.
See https://dev.mysql.com/doc/refman/8.0/en/fulltext-stopwords.html
But this is a global variable, so it will affect all fulltext index creation on all tables on that MySQL instance. I suppose you could set the innodb_ft_server_stopword_table to your custom table, build your fulltext index, and then set the option back to its usual value. But that would be tricky, because anytime you rebuild your fulltext index (for instance during an alter table or optimize table), it would revert to the default stopwords.

Related

PDOException' with message 'SQLSTATE[HY000]: General error:1191 [duplicate]

I'm working with fulltext, I executed an command to add the fulltext index to multiple comments, and returned no errors, then I did:
SELECT * FROM products WHERE MATCH(`brand`) AGAINST('Skoda');
Which is in the brand column - but I get following:
Can't find FULLTEXT index matching the column list
Eventho, when my table looks like this:
FULLTEXT KEY `name` (`name`,`breadcrumb`,`description`,`brand`,`price`,`year`,`km`,`usage`,`type`)
Is it because I should use the name instead? to do the search? Or what can be wrong.
Assuming you are using MyISAM engine, Execute:
ALTER TABLE products ADD FULLTEXT(brand);
The fulltext index should contain exactly the same number of columns, in same order as mentioned in MATCH clause.
If you don't feel like having the columns in the same order as in the match clause( or the same number), you can always use 'OR' that is:
ALTER TABLE products ADD FULLTEXT(brand);
ALTER TABLE products ADD FULLTEXT(product_name);
SELECT * FROM products WHERE MATCH(brand) AGAINST('+Skoda*' IN BOOLEAN MODE) OR MATCH(product_name) AGAINST('+productName*' IN BOOLEAN MODE)
When everything was right and still got this error I found that the KEYS were disabled. A simple error that is sometimes overlooked:
Make sure you have enabled the keys on that table.
It didn't work for me when I had disabled the keys. But when I enabled the keys ALTER TABLE table name ENABLE KEYS; it worked fine
I found I also needed to do this on my instance as the index was not visible. It was a checkbox while exploring MySQL Workbench. While invisible the index is not reachable by a query.
ALTER TABLE products ALTER INDEX brand VISIBLE;
Make sure the table engine is set to MyISAM.

MySql - how can you create a unique constraint on a combination of two values in two columns

I have a problem with creating index described in answer for this question: sql unique constraint on a 2 columns combination
I am using MySql, and I received syntax error, my version of this query is as follows:
CREATE UNIQUE INDEX ON friends (LEAST(userID, friendID), GREATEST(userID, friendID));
LEAST and GREATEST functions are available in MySql, but maybe the syntax should be different?
I tried to make an ALTER TABLE version, but it does not worked as well.
In MySQL, you can't use functions as the values for indexes.
The documentation does not explicitly state this, however, it is a basic characteristic of an index to only support "fixed" data:
Indexes are used to find rows with specific column values quickly. Without an index, MySQL must begin with the first row and then read through the entire table to find the relevant rows.
Generally, this "fixed" data is an individual column/field; with string-fields (such as varchar or text) you can have a prefix-index and not the entire column. Check out CREATE INDEX for more info on that.
The unique index that you're trying to create in you example will have a single record ever; that's not really a beneficial index since it doesn't help for searching the entire table. However, if you index your table on userID, friendID, using the LEAST() and GREATEST() functions in a SELECT statement will be optimized thanks to the index itself, so it may be what you're after in this case.

finding words in mysql huge database

So, i've never worked with a database this huge. We are talking about 200.000.000++ words that i want to be able to search through. How should i approach this? using the normal "where" statement would take 10+++ minutes, should i split up the database or something?
Any help would be great!
MySQL FULLTEXT indexes are quite useful when searching for words. You have to define the fields which contain the relevant text/character strings as indexes. Then you can use
SELECT * FROM table WHERE MATCH (text_index_field) AGAINST ('what you need to look for');
You should use MySql FULLTEXT indexing.
Use AlTER TABLE for create a FULLTEXT index on your desire column.
and from http://dev.mysql.com/doc/refman/5.1/en/alter-table.html
Full-text indexes can be used only with MyISAM tables. (In MySQL 5.6 and up, they can also be used with InnoDB tables.) Full-text indexes can be created only for CHAR, VARCHAR, or TEXT columns.

Can't find FULLTEXT index matching the column list (indexes is set)

I'm working with fulltext, I executed an command to add the fulltext index to multiple comments, and returned no errors, then I did:
SELECT * FROM products WHERE MATCH(`brand`) AGAINST('Skoda');
Which is in the brand column - but I get following:
Can't find FULLTEXT index matching the column list
Eventho, when my table looks like this:
FULLTEXT KEY `name` (`name`,`breadcrumb`,`description`,`brand`,`price`,`year`,`km`,`usage`,`type`)
Is it because I should use the name instead? to do the search? Or what can be wrong.
Assuming you are using MyISAM engine, Execute:
ALTER TABLE products ADD FULLTEXT(brand);
The fulltext index should contain exactly the same number of columns, in same order as mentioned in MATCH clause.
If you don't feel like having the columns in the same order as in the match clause( or the same number), you can always use 'OR' that is:
ALTER TABLE products ADD FULLTEXT(brand);
ALTER TABLE products ADD FULLTEXT(product_name);
SELECT * FROM products WHERE MATCH(brand) AGAINST('+Skoda*' IN BOOLEAN MODE) OR MATCH(product_name) AGAINST('+productName*' IN BOOLEAN MODE)
When everything was right and still got this error I found that the KEYS were disabled. A simple error that is sometimes overlooked:
Make sure you have enabled the keys on that table.
It didn't work for me when I had disabled the keys. But when I enabled the keys ALTER TABLE table name ENABLE KEYS; it worked fine
I found I also needed to do this on my instance as the index was not visible. It was a checkbox while exploring MySQL Workbench. While invisible the index is not reachable by a query.
ALTER TABLE products ALTER INDEX brand VISIBLE;
Make sure the table engine is set to MyISAM.

MySql using primary index instead of multiple column one!

Ok so I've a SQL query here:
SELECT a.id,... FROM article AS a WHERE a.type=1 AND a.id=3765 ORDER BY a.datetime DESC LIMIT 1
I wanted to get exact article by country and id and created for that index with two columns type and id. Id is also primary key.
I used the EXPLAIN keyword to see which index is used and instead of the multiple column index it used primary key index, but I did set the where stuff exactly in order as the index is created.
Does MySQL use the primary key index instead of the multiple column index because the primary one is faster? Or should I force MySql to use the multiple column index?
P.S. Just noticed it was stupid to use order when there is 1 result row. Haha. It increased the search time for 0.0001 seconds. :P
I don'e KNOW, but I would THINK that the primary key index would be the fastest available. And if it is, there's not much use using any other index. You're either going to have a article with an id of 3765 or you're not. Scanning that single row to determine if the type matches is trivial.
If you're only returning one row, there's no point to your ORDER BY clause. And the only point to the a.type=1 is to reject an article with the right id if the type is not correct.
MySQL allows for up to 32 indexes for each table, and each index can incorporate up to 16 columns. A multiple-column / composite index is considered a sorted array containing values that are created by concatenating the values of the indexed columns. MySQL uses multiple-column indexes in such a way that queries are fast when you specify a known quantity for the first column of the index in a WHERE clause, even if you do not specify values for the other columns.
If you look very carefully in how MySQL uses indexes, you will find that indexes are used to find rows with specific column values quickly. Without an index, MySQL must begin with the first row and then read through the entire table to find the relevant rows.
In MySQL, a primary key column is automatically indexed for efficiency, as they use the in-built AUTO_INCREMENT feature of MySQL. On the other hand, one should not go overboard with indexing. While it does improve the speed of reading from databases, it slows down the process of altering data in a database (because the changes need to be recorded in the index). Indexes are best used on columns:-
that are frequently used in the WHERE part of a query
that are frequently used in an ORDER BY part of a query
that have many different values (columns with numerous repeating values ought not to be indexed).
So I try to use the primary key if my queries can suffice its use. When & only when it is required for more such indexing & fastness of fetching records, do I use the composite indexes.
Hope it helps.
The primary key is unique, so there's no need for MySQL to check any other index. a.id=3765 guarantees that there will be no more than one row returned. If a.type=1 is false for that row, then nothing will be returned.

Categories