I am working on the search feature on my website and would like to improve it a little bit.
My website is a tube website.
I used to work with mysql 'LIKE' statement but realized MATCH() AGAINST() was way more performant.
But I still have a problem with small and partial word.
Let's say there is a title in the video database called: 'Funny video about monkeys - Asia - lol'
There are the different select query with what would be returned (using phpmyadmin to avoid error that would be related by wrong php code)
SELECT video.*, MATCH (title) AGAINST ('lol' IN BOOLEAN MODE) AS relevance FROM video WHERE active = '1' AND MATCH (title) AGAINST ('lol' IN BOOLEAN MODE) ORDER BY relevance DESC LIMIT 18
returns
nothing
SELECT video.*, MATCH (title) AGAINST ('monkey' IN BOOLEAN MODE) AS relevance FROM video WHERE active = '1' AND MATCH (title) AGAINST ('monkey' IN BOOLEAN MODE) ORDER BY relevance DESC LIMIT 18
returns
nothing
SELECT video.*, MATCH (title) AGAINST ('asia' IN BOOLEAN MODE) AS relevance FROM video WHERE active = '1' AND MATCH (title) AGAINST ('asia' IN BOOLEAN MODE) ORDER BY relevance DESC LIMIT 18
returns
the video in the database
SELECT video.*, MATCH (title) AGAINST ('asian monkey' IN BOOLEAN MODE) AS relevance FROM video WHERE active = '1' AND MATCH (title) AGAINST ('asian monkey' IN BOOLEAN MODE) ORDER BY relevance DESC LIMIT 18
returns
nothing
So if I am right, the video is returned only if it contains the exact word, and if the word is at least 4 chars.
But the strange thing is that 'ft min word len' is set to 2 so event the query 'lol' should return the video. Also, the query states 'IN BOOLEAN MODE' so I guess it should return even commons words.
As from the partial word like 'monkey' instead of 'monkeys', I have no idea how to go around this as using 'LIKE %...% OR LIKE %...%' won't be a solution because I need to get the relevance.
Well thank you for reading and helping me.
Related
SELECT * FROM people
WHERE
university='2'
AND MATCH (lname,fname) AGAINST ('+massive' IN BOOLEAN MODE)
OR (fname LIKE '%box%' OR lname LIKE '%box%')
This query is allowing results to filter through other than those of university='2' how would I update this so it strictly only shows results where university = 2
The reason I have combined fulltext search with LIKE is because of the minimum letter count that full text search has and because I am on a shared hosting plan I am unable to modify the settings. As a result I have combined both full text and LIKE in order to accommodate
Fix your parentheses
SELECT * FROM people
WHERE
university='2'
AND (MATCH (lname,fname) AGAINST ('+massive' IN BOOLEAN MODE)
OR fname LIKE '%box%'
OR lname LIKE '%box%')
AND has higher precedence than OR, so university = '2' was only being combined with MATCH, not with the fname/lname tests.
I've built an internal DB / Search Engine for art creatives. I'm trying to create a search criterion where you can query one column in the database and also search several columns in the database for a phrase search using FullText Search. The example of a search query might be: November {and} Black Friday. November would search for creatives matching the created_for column and the black friday would search headline, subheadline and additional_text columns with a fulltext search. Any ideas of how to accomplish this would be really helpful!
SELECT
(SELECT * FROM headlines WHERE created_for = '$searchString' AND image_slug <> '')
(SELECT *, MATCH(headline) AGAINST('$fullText' IN BOOLEAN MODE) AS MultiScore, MATCH(subheadline, additional_text) AGAINST('$fullText' IN BOOLEAN MODE) AS MultiSecondScore
FROM `headlines`
WHERE MATCH(headline, subheadline, additional_text) AGAINST('$fullText' IN BOOLEAN MODE))
I've tried adding a UNION statement before the second Select statement, but I get an error message saying the columns don't match. Not sure what I've got wrong here, but thanks in advance for your help!
Use AND in the WHERE clause.
SELECT *, MATCH(headline) AGAINST('$fullText' IN BOOLEAN MODE) AS MultiScore, MATCH(subheadline, additional_text) AGAINST('$fullText' IN BOOLEAN MODE) AS MultiSecondScore
FROM headlines
WHERE created_for = '$searchString'
AND image_slug <> ''
AND MATCH(headline, subheadline, additional_text) AGAINST('$fullText' IN BOOLEAN MODE)
UNION would get results that match either of the criteria, not both of them. And when you use UNION, both subqueries have to return the same number of columns -- you would have to add extra columns to the first query to match the MultiScore and MultiSecondScore columns of the first query.
I have already searched online but not find any use full link Fulltext search only returns exact matches
I have column posttitle with row values
shiva
goodshiva
goodshiva
goodshivagood
Query:
SELECT * FROM `jobs` WHERE match(posttitle) against('shiva' in boolean mode)
and
SELECT * FROM `jobs` WHERE match(posttitle) against('*shiva*' in boolean mode)
doesn't return any value
SELECT * FROM `jobs` WHERE match(posttitle) against('shiva*' in boolean mode)
and
SELECT * FROM `jobs` WHERE match(posttitle) against('+shiva*' in boolean mode)
shows only shivagood and shiva
using natural language mode shows only exact match.
Is there any way without using like?
You have found a limitation to mysql full text search.
There is no equivalent syntax to
LIKE '%something%'
While MySQL itself will return a result for that type of query, no index can be used, so the table involved will be "table scanned"
The full text match syntax of +shiva* will only match when a word starts with shiva. It will not match for words that contain shiva but do not start with shiva.
*shiva*
Is not supported.
Due to this limitation and other issues with full text search, many websites utilize an external search engine like sphinx or solr. Sphinx for example, does allow for
'*shiva*'.
I would like to ask if anybody can help me with this query
SELECT count(MATCH(product_text) AGAINST('lorem*' in boolean mode)) AS score FROM table_products WHERE MATCH (text) AGAINST ('lorem*' in boolean mode) limit 0,50000
There is fulltext index on column text. A.m. query return sum of rows as score.
What I wont is to count fulltext search results. If the number of results(rows)
is higher than 50000, than count-sum 50000 will be returned, otherwise the exact count of
of results is returned.
Problem is that it is not fast on table width 1,5 million rows if user try to find for example word "lorem" and this word appears in table f.e. more than 500 000 x.
I tried also
SELECT id,name,product_text,price, MATCH(product_text) AGAINST('lorem*' in boolean mode) AS score FROM table_products WHERE MATCH(product_text) AGAINST('lorem*' in boolean mode) and show_product='1' limit 0,50000
... width php mysql_num_rows
Another problem is that in following query mysql use fulltext index only
and sort by another column or by score is than slow
SELECT id,name,product_text,price, MATCH(product_text) AGAINST('lorem*' in boolean mode) AS score FROM table_products WHERE MATCH(product_text) AGAINST('lorem*' in boolean mode) and show_product='1' order by score desc limit 0,50000
resp. (..order by name, order by price)
Is there another better and faster way?
Many thanks for any help.
I'm using PDO to execute a MATCH AGAINST query.
The following returns nothing:
SELECT title, author, isbn, MATCH(title, isbn) AGAINST (:term) AS score
FROM books
WHERE MATCH(title, isbn) AGAINST (:term)
ORDER BY score DESC LIMIT 0,10
Where as this returns perfectly:
SELECT title, author, isbn, MATCH(title, isbn) AGAINST (:term) AS score
FROM books
WHERE MATCH(title, isbn) AGAINST (:term IN BOOLEAN MODE)
ORDER BY score DESC LIMIT 0,10
Could anyone tell me why IN BOOLEAN MODE is making such a difference, and whether or not I should be using it in my query?
The second query is running as a "natural language search" as that is the default when no natural language search type is specified. This type of search filters additionally filters out words that are present in 50% or more of the rows automatically.
"IN BOOLEAN MODE" does do this additional filtering, and thus, may return matches if you are searching on a common term.
Whether or not you should be using a boolean search depends on what the specifics of your situation and cannot be determined without more information. However, some considerations may include, size of the input data set vs how large of a matching dataset you want returned and whether you want to return results for words that occur frequently.
(Ref: http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html)