How to search text using MATCH...AGAINST query? - mysql

Table
id name
--- ------
1 chinu
2 sanjib
3 chinmay
My MYSQL Query
SELECT * FROM users WHERE MATCH (name) AGAINST ('chi' IN BOOLEAN MODE)
In above query i am getting 0 record.
My output will be coming
1 chinu
3 chinmay
How to get my actual record using MATCH...AGAINST query?
EDIT - If i am searching chinu instead of chi i am getting 1 record.

You need to add an asterisk to the 'chi' to indicate that the query should match against all that contain the string and not just the string itself. Just using the string 'chi' will only match exactly 'chi' for example.
change your query to read
SELECT * FROM users WHERE MATCH (name) AGAINST ('chi*' IN BOOLEAN MODE)
and you should get the results you expect.

I think you forgot the + sign:
SELECT * FROM users WHERE MATCH (name) AGAINST ('+chi' IN BOOLEAN MODE)
Or if it is an exact phrase, use double quotes to surround the string:
SELECT * FROM users WHERE MATCH (name) AGAINST ('"chi"' IN BOOLEAN MODE)

I am the first to admit that this is not easy to find. MySQL full text search uses a system variable called ft_min_word_length. The default value is 4, as shown here.
Because you are searching for a 3-character word, it is not being indexed. Hence it is not found.
More information is available in the documentation on fine tuning the search. But the basic idea is that you need to change the value of the parameter and rebuild the index.
For your particular query, though, you just need to include wildcards, as explained in other answers.

Related

Find exactly text which contain column's value in Mysql?

id text_1 text_2
1 おはよう おはよ
2 こんにちは ちわー
3 大丈夫 さよなら
4 でんわしたい でんわしよう
I have DB same above.
I want to search with input: おはよう大丈夫?
Expect result will match: id = 1 and id = 3.
Please help me how to query search in Mysql? Thanks you.
The following SQL query will fetch your 2 ids for exact string matching
select id from TABLENAME where text_1 in ('おはよう','大丈夫');
You can also use like operator with % to fetch approximately strings id.
You might face encoding issue (文字化け)depending on your DB settings, so you might have to convert SJIS <-> UTF-8
https://dev.mysql.com/doc/refman/5.7/en/faqs-cjk.html#faq-cjk-what-cjk-avail
Last but not least, if you want to use the full string as a comparison criteria to select the rows, then you can reuse the following code:
how to compute similarity between two strings in MYSQL
select id from TABLENAME where text_1 REGEXP "おはよう大丈夫"

MySQL wildcard Like query with multiple words

I have a mysql query as follows.
$query="SELECT name,activity FROM appid
where result > 5 AND name LIKE :term ORDER BY name ASC LIMIT 0,40";
$result = $pdo->prepare($query);
$result->bindvalue(':term','%'.$_GET["q"].'%',PDO::PARAM_STR);
$result->execute();
What i want to do is this.
I have and entry like this that i want to find
'News & Weather'
However when i type
'news weather'
it of course will not find it. How can i be able to type that and retrieve that entry?
Regular expressions can do the trick:
select *
from appid
where name rlike 'news|weather' -- Matches 'news' or 'weather'
Another example:
select *
from appid
where name rlike 'news.*weather' -- Matches 'news' and 'wether'
-- with any characters in-between or none at all
-- (ordered)
Just one more:
select *
from appid
where name rlike '^news.{1,}weather$' -- Matches any text that starts with 'news'
-- and has at least one character before
-- ending with 'weather'
Regular espressions can be used to create very complicated filters on text fields. Read the link above for more information.
If you can add a full-text index to your table, Full-text search might be the better way to go with this. Specifically, a boolean Full-Text search:
select *
from appid
where match(name) against (+news +weather)
I believe the only way possible are through code:
Option A: Replace the spaces in your query parameter with '%' in code, but that of course will make the multiple words ordered
Option B: Split your parameter on spaces and dynamically construct your query with as many LIKEs as needed, adding additional ":termN" parameters for each one.

MySQL Match Against In Boolean Mode returns nothing on middle word

I've got a problem using Match Against in my MySQL database, and I'm hoping someone can help.
This is the examples of the data in my database:
id name
1 really bitter chocolate
2 soft cheese
When I run this query:
SELECT * FROM food WHERE (name) LIKE "%bitter%"
This bring back the first result:
1 really bitter chocolate
However its part of a much larger query, and when I run the Match Against code, I don't get anything returned from either of these queries:
SELECT * FROM food WHERE MATCH (name) AGAINST ("bitter")
SELECT * FROM food WHERE MATCH (name) AGAINST ("bitter", IN BOOLEAN MODE)
I have full text searches turned on, and it works when I search the start of the name:
SELECT * FROM food WHERE MATCH (name) AGAINST ("really")
SELECT * FROM food WHERE MATCH (name) AGAINST ("really", IN BOOLEAN MODE)
Both of which returns:
1 really bitter chocolate
I've read through this for solutions: http://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html
And I've looked here: mysql WHERE MATCH AGAINST
Can someone please see where I am going wrong or point me in the right direction?
Thanks!
EDIT
Ok as per Woot4Moo great answer below I've changed my code to remove the comma which shouldn't have been there. I've also added in the + and putting it in single quotes but still no luck.
My current query now looks like this:
SELECT * FROM food WHERE MATCH (name) AGAINST ('+bitter' IN BOOLEAN MODE)
But it's returning no results in query browser, and not returning any errors or warnings.
If this are the only two rows in your table then you have in 50% of the records the searched string and it will be ignored.
SELECT * FROM food WHERE MATCH (name) AGAINST ("bitter", IN BOOLEAN MODE)
looks like it should be:
SELECT * FROM food WHERE MATCH (name) AGAINST ('+bitter' IN BOOLEAN MODE)
notice how mine has the plus sign + and NO comma ,
Basing it off of the example here
MySQL can perform boolean full-text searches using the IN BOOLEAN
MODE modifier. With this modifier, certain characters have special
meaning at the beginning or end of words in the search string. In the
following query, the + and - operators indicate that a word is
required to be present or absent, respectively, for a match to occur.
Thus, the query retrieves all the rows that contain the word “MySQL”
but that do not contain the word “YourSQL”:
mysql> SELECT * FROM articles WHERE MATCH (title,body)
-> AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);

ORDER BY in MySql based on LIKE condition

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.

Why does this search query return nothing?

I have this table under user_name='high'
function_description :
akram is in a date
test
akram is studying
test4
kheith is male
test3
I want a query that returns results of field that have at least an 'akram'
SELECT *
FROM functions
WHERE 'isEnabled'=1
AND 'isPrivate'=1
AND user_name='high'
AND function_description LIKE '%akram%'
and this returns absolutely nothing!
Why?
You are listing the column names as if they are strings. This is why it returns nothing.
Try this:
SELECT *
FROM functions
WHERE user_name='high'
AND function_description LIKE '%akram%'
edit: After trying to re-read your question... are isEnabled and isPrivate columns in this table?
edit2: updated.. remove those unknown columns.
You are comparing strings 'isEnabled' with integer 1, which likely leads to the integer being converted to a string, and the comparison then fails. (The alternative is that the string is converted to an integer 0 and the comparison still fails.)
In MySQL, you use back-quotes, not single quotes, to quote column and table names:
SELECT *
FROM `functions`
WHERE `isEnabled` = 1
AND `isPrivate` = 1
AND `user_name` = 'high'
AND `function_description` LIKE '%akram%'
In standard SQL, you use double quotes to create a 'delimited identifier'; in Microsoft SQL Server, you use square brackets around the names.
Please show the schema more carefully (column names, sample values, types if need be) next time.