We use fulltext search on a french CMS ( SPIP ). The resultat of a search with a minus word doesn't seems correct. We tried the sql request generated by the CMS in phpMyAdmin :
SELECT t.id_zotspip, t.titre, t.resume,
MATCH(t.`titre`) AGAINST ('+corrosion -bacteria' IN BOOLEAN MODE) * 10
+ MATCH(t.`titre`,t.`resume`) AGAINST ('+corrosion -bacteria' IN BOOLEAN MODE) * 2.2 AS score
FROM `spip_zotero311`.spip_zitems AS t
WHERE ((MATCH(t.`titre`) AGAINST ('+corrosion -bacteria' IN BOOLEAN MODE))
OR (MATCH(t.`titre`,t.`resume`) AGAINST ('+corrosion -bacteria' IN BOOLEAN MODE)))
GROUP BY t.id_zotspip ORDER BY score DESC LIMIT 0,500
We get results with bacteria in the resume...
The type of the table is MyISAM but the type of the base is InnoDB.
Any suggestions ?
Thank you.
The problem is in OR clause inside where. You should replace OR inside WHERE clause with AND.
Related
I am creating a search service using mysql's fulltext-index.
I use it by setting innodb_ft_min_token_size = 1. (Support 1 character search)
The reason for the change from ngram is that ngram=1 takes too much load because there is a lot of data.
Here's a question.
If the name is 'ABCDEF' and the search keyword is 'ABC'
SELECT * FROM SEARCH_TABLE WHERE MATCH(NAME) AGAINST('+*ABC*' IN BOOLEAN MODE);
The above query finds 'ABCDEF' normally.
SELECT * FROM SEARCH_TABLE WHERE MATCH(NAME) AGAINST('+*ABC* +*DEF*' IN BOOLEAN MODE);
But this query doesn't find 'ABCDEF'.
What could be the reason and how can I fix this?
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.
I want relevancy for exact "production house in goa". it also results anything that contain Goa.
SELECT * FROM `app_search` WHERE MATCH (`keywords`) AGAINST
("production house in goa" in boolean mode)
order by MATCH (`keywords`) AGAINST ("production house in goa" in boolean mode)
desc, rank desc;
Thanks
Deleting old table and recreating with fulltext index on keywords and below query solve the problem.
SELECT *, MATCH (`keywords`) AGAINST
('software development in florida'
IN BOOLEAN MODE) AS score
FROM `ftextsearch` WHERE MATCH (keywords) AGAINST
('software development in florid'
IN BOOLEAN MODE) order by score desc,rank desc
Query also return relevancy of search in score.
Is it possible to use full test search in InnoDB engine with AND operator for natural language mode? I mean query like below but with all words as required:
SELECT *, MATCH (body) AGAINST ('mysql database') AS score FROM post ORDER BY score DESC;
For this query i want return all records which match both words:'mysql' AND 'database'. I know i can use + and BOOLEAN mode, but it causes another problems like other operators which i want to ignore (*,-,"'..)
Add a WHERE clause that tests for each word separately:
SELECT *, MATCH (body) AGAINST ('mysql database') AS score
FROM post
WHERE MATCH(body) AGAINST ('mysql') AND MATCH(body) AGAINST('database')
ORDER BY score DESC;
This example shows that only one fulltext index is needed. http://www.vionblog.com/mysql-full-text-search-with-multiple-words/
Here's the example:
ALTER TABLE products ADD FULLTEXT(title, sdescription, ldescription)
SELECT *,
MATCH(`title`) AGAINST ('+iphone +case +4s' IN BOOLEAN MODE) * 10 as rel1,
MATCH(`sdescription`) AGAINST ('+iphone +case +4s' IN BOOLEAN MODE) * 3 as rel2,
MATCH(`ldescription`) AGAINST ('+iphone +case +4s' IN BOOLEAN MODE) as rel3,
FROM products
WHERE MATCH (title, sdescription, ldescription)
AGAINST ('+iphone +case +4s' IN BOOLEAN MODE)
ORDER BY (rel1)+(rel2)+(rel3) DESC;
And this answer suggests that three fulltext indexes are needed to do the same. How can I manipulate MySQL fulltext search relevance to make one field more 'valuable' than another?
I want to make one column more valuable than others like it's been done in the above query. I'm confused how many indexes are needed for that, one or three?