mysql multiple OR NOT LIKES - mysql

I have a wordpress plugin that essentially creates a mysql query and returns the results to wordpress.
It is user driven and so can end up in large queries with multiple NOT LIKEs which results in a very slow query.
Any suggestions that I could use to improve:
SELECT field1,field2,field3,field4
from datatable
WHERE (title NOT LIKE '%word%' AND title NOT LIKE '%word2%'
AND title NOT LIKE '%word3%' AND title NOT LIKE '%word4%'
AND title NOT LIKE '%word5%' AND title NOT LIKE '%word6%'
AND title NOT LIKE '%word7%' AND title NOT LIKE '%word8%'
AND title NOT LIKE '%word9%')
AND MATCH (title) AGAINST ("\"brandname\" " IN BOOLEAN MODE)
ORDER BY total ASC LIMIT 0,60
The customer is adding a lot of negative keywords to the wordpress plugin which results in larger queries than the one above.

This is most easily done with REGEXP. For multiple words, use a group like (one|two|three)
SELECT
field1,
field2,
field3,
field4
from datatable
WHERE
title NOT REGEXP '(word1|word2|word3|word4|word5...|word9)'
AND MATCH (title) AGAINST ("\"brandname\" " IN BOOLEAN MODE)
ORDER BY total ASC
LIMIT 0,60

You can use a REGEXP operation to compare all the patterns at once.
Your query will be something like:
SELECT field1,field2,field3,field4
FROM data table
WHERE title NOT REGEXP '^word[0-9]?$'
AND MATCH(title) ("\"brandname\" " IN BOOLEAN MODE)
ORDER BY total ASC LIMIT 0,60

Related

query that returns rows that do not contain a word in MySql

I am trying to make a query where I select all the rows that do not contain a specific word, for this I have a fulltext type index in this column, try the following bolt works:
SELECT *
FROM products
WHERE MATCH(title) AGAINST(' -Dolo' IN BOOLEAN MODE)
So how can I perform this search?
If I have understood you correctly you want to find all the rows from the table that do not contain a word'Dolo'.
Well you can use NOT operator for that.
SELECT *
FROM products
WHERE NOT MATCH(title) AGAINST('Dolo');
Here is a DEMO.
Also, you can use it like this(because as the OP has asked: "if the whole word is "dolorem", would this query work?"):
SELECT title as Title
, MATCH(title) AGAINST('Dolo*' IN BOOLEAN MODE) as Score
FROM products
WHERE MATCH(title) AGAINST('Dolo*' IN BOOLEAN MODE) = 0;
* is a wildcard.
Other signs are described here: https://dev.mysql.com/doc/refman/8.0/en/fulltext-boolean.html
Here is the DEMO for the second example.

How to use the result of GROUP_CONCAT in an RLIKE query?

Given a table keywords which contains some keywords for searching, and another table titles of which title to search. I tried GROUP_CONCAT all words in keyword and fed the result ('w1|w2|w3|w4') in a RLIKE query as following:
select title from titles where title rlike
(select group_concat(distinct word separator '|') from keywords) as keyword;
But the statement violated the SQL syntax. How could I fix the statement (assuming full-text search is unavailable)?
That seems like a very odd thing to do. Why not just use exists?
select t.title
from titles t
where exists (select 1
from keywords kw
where t.title rlike kw.word
);

match against, sort by relevance

My Query
$query = selectQuery('SELECT * FROM page_info WHERE MATCH(content)
AGAINST("reactie klanten" WITH QUERY EXPANSION)');
how can I sort by relevance? i get back about 10 rows, but the row that actually contains the words 'reactie' and 'klanten' is somewhere in the middle. the rest of the results is somehow relevant with the words :S
MySQL documentation about 'WITH QUERY EXPANSION'
EDIT
changed by query to:
SELECT *, MATCH(content) AGAINST("reactie klanten") AS relevance FROM page_info WHERE MATCH(content) AGAINST("reactie klanten" WITH QUERY EXPANSION) ORDER BY relevance DESC
this seems promising, because now the field is on top of the list.
still how are the others related?
example:
$text = This page is being tested by our tester
how is $text relevant to reactie klanten?

MySQL: How to do basic search by relevance?

I read the official page: http://dev.mysql.com/doc/refman/5.5/en/fulltext-search.html
but it's not providing an example
I have 1 col named "mycol", and suppose user input is "keyword1 keyword2". I want to display results ordered by relevance. I tried something like this:
select id,mycol,match(mycol) against('keyword1 keyword2' in boolean mode) as relevance from mytable
It's returning all records relevance is 0. What am I doing wrong?
try
select id,mycol,match(mycol) against('keyword1 keyword2') as relevance from mytable order by relevance desc

Matching first char in string to digit or non-standard character

I need to allow users to browse a table, with >1 million entries, by the first letter in the title.
I want them to be able to browse by every letter from A-Z, 0-9 in a list together and all other characters together.
Since it's a big database and it is to be displayed on a website, I need it to be efficient. Regex does not use index, so that would be too slow.
Is this possible or will I have to rethink the design?
Thanks in advance
As long as there's an index on the "Title", you should be able to use a SQL like
select *
from myTable
where Title like 'A%'
(or 'B%', 'C%'...)
Create links representing every letter and number. Clicking these links will provide the users with the results from the database that begin with the selected character.
SELECT title FROM table
WHERE LEFT(title,1) = ?Char
ORDER BY title ASC;
Consider paginating these result pages into appropriate chunks. MySQL will let you do this with LIMIT
This command will select the first 100 records from the desired character group:
SELECT title FROM table
WHERE LEFT(title,1) = ?Char
ORDER BY title ASC
LIMIT 0, 100;
This command will select the second 100 records from the desired character group:
SELECT title FROM table
WHERE LEFT(title,1) = ?Char
ORDER BY title ASC
LIMIT 100, 100;
Per your comments, if you want to combine characters 0-9 without using regex, you will need to combine several OR statements:
SELECT title FROM table
WHERE (
LEFT(title,1) = '0'
OR LEFT(title,1) = '1'
...
)
ORDER BY title ASC;