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;
Related
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.
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.
I am facing difficulty in sorting the result based on field in mysql. Say for example I am searching the word "Terms" then I should get the results which starts with 'Terms' first and then 'Terms and' as next and then 'Terms and conditions' and so on.
Any one please help out who to fetch the search result based on my requirements in efficient manner using mysql query.
SELECT * FROM your_table WHERE your_column LIKE "Terms%" ORDER BY your_column;
Based on the storage engine and mysql version you probably can use the full text search capabilities of MySQL. For example:
SELECT *, MATCH (your_column) AGAINST ('Terms' IN BOOLEAN MODE) AS relevance
FROM your_table
WHERE MATCH (your_column) AGAINST ('Terms' IN BOOLEAN MODE)
ORDER BY relevance
You can find more info here: http://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html
Or if you don't want FTS another possible solution where ordering is strictly based on the length (difference) of the strings.
SELECT * FROM your_table WHERE your_column LIKE "Terms%" ORDER BY ABS(LENGTH(your_column) - LENGTH('Terms'));
You are looking for fulltext search. Below a very simple example
SELECT id,name MATCH (name) AGAINST ('string' > 'string*' IN BOOLEAN MODE) AS score
FROM tablename WHERE MATCH (name) AGAINST ('string' > 'string*' IN BOOLEAN MODE)
ORDER BY score DESC
The advantage of this is that you can control the value of words. This is very basic, you can 'up' some matches or words (or 'down' them)
In my example an exact match ('string') would get a higher score than the string with something attached ('string*'). The following line is even one step broader:
'string' > 'string*' > '*string*'
This documentation about fulltextsearch explains allot. It's a long read, but worth it and complete.
Don't use fulltext index if you search for prefix string!
Using LIKE "Term%" the optimizer will be able to use a potential index on your_column:
SELECT * FROM your_table
WHERE your_column LIKE "Terms%"
ORDER BY CHAR_LENGTH(your_column),your_column
Note the ORDER BY clause: it first sorts by string length, and only use alphabetcal order to sort strings of equal length.
And please, use CHAR_LENGTH and not LENGTH as the first count the number of characters, whereas the later count number of bytes. Using a variable length encoding such as utf8, this would made a difference.
I have a problem or rather an understanding problem with a hyphenated searchstring which is quoted.
In my Table there is a table with a column 'company'.
One of the entries in that column is: A-Z Electro
The following examples are simplified a lot (though the real query is much more complex) - but the effect is still the same.
When I do the following search, I don't get the row with the above mentioned company:
SELECT i.*
FROM my_table i
WHERE MATCH (i.company) AGAINST ('+\"A-Z\" +Electro*' IN BOOLEAN MODE)
GROUP BY i.uid ORDER BY i.company ASC LIMIT 0, 40;
If I do the following search, get the row with the above mentioned company (notice only changed the - to a + before "A-Z":
SELECT i.*
FROM my_table i
WHERE MATCH (i.company) AGAINST ('-\"A-Z\" +Electro*' IN BOOLEAN MODE)
GROUP BY i.uid ORDER BY i.company ASC LIMIT 0, 40;
I also get the row, if I remove the operator completely:
SELECT i.*
FROM my_table i
WHERE MATCH (i.company) AGAINST ('\"A-Z\" +Electro*' IN BOOLEAN MODE)
GROUP BY i.uid ORDER BY i.company ASC LIMIT 0, 40;
Can anyone explain to me this behaviour? Because I would expect, when searching with a +, I should get the result too...
I just checked the table index with myisam_ftdump.
Two-Character-Words are indexed properly as there are entries like
14f2e8 0.7908264 ab
3a164 0.8613265 dv
There is also an entry:
de340 0.6801047 az
I suppose this should be the entry for A-Z - so the search should find this entry, shouldn't it?
The default value of ft_min_word_len is 4. See this link for information on that. In short, your system isn't indexing words of less than 4 characters.
Why is this important? Well:
A-Z is less than 4 characters long
...therefore it's not in the index
...but your first query +"A-Z" states it must be in the index in order for the match to succeed
The other two (match if it's not in the index, match if either this or that is in the index) work because it's not in the index.
The hyphen is a red herring - the reason is because "A-Z" is three characters long and your FT index ignores it.
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