MySQL fulltext with score by columns - mysql

I created an index like this:
ALTER TABLE `blog_posts`
ADD FULLTEXT `title_description_content` (`title`, `description`, `content`);
I can search with:
SELECT * FROM `blog_posts`
WHERE MATCH(title, content, description)
AGAINST("lorem ipsum" IN NATURAL LANGUAGE MODE)
LIMIT 12
But I want to score by column. For example, that the title column is worth 3 points, that the description is worth 2 and the content is worth 1. So that words found in the title have a higher score.
I know this is possible because I already did it once, but I lost the source and I couldn't find any example on Google.
Thanks!

You can use multiple indexes for your problem
SELECT *,
MATCH (title) AGAINST ("lorem ipsum" IN NATURAL LANGUAGE MODE) AS rel1,
MATCH (content) AGAINST ("lorem ipsum" IN NATURAL LANGUAGE MODE) AS rel2,
MATCH (description) AGAINST ("lorem ipsum" IN NATURAL LANGUAGE MODE) AS rel3
FROM `blog_posts`
WHERE MATCH(title, content, description) AGAINST("lorem ipsum" IN NATURAL LANGUAGE MODE)
ORDER BY (rel1 * 3)+(rel2 * 2)+(rel3 * 1) DESC
LIMIT 12
The weight multiplications can be finetuned

Related

How to order SQL results in Full Text Searches

I am trying to use full text search in my project. When I use Natural Language Full-Text Searches
with more than word, it works fine for me. Here are some examples of my code:
SELECT * FROM table WHERE MATCH (title, title_ar, title_en) AGAINST ('some exemple' IN NATURAL LANGUAGE MODE);
I can also do this to get score and order it by score:
SELECT *,
MATCH (title, title_ar, title_en) AGAINST ('some exemple' IN NATURAL LANGUAGE MODE) as scor
FROM table
WHERE MATCH (title, title_ar, title_en) AGAINST ('some exemple' IN NATURAL LANGUAGE MODE);
The problem is when I use one word for my search like this:
SELECT *,
MATCH (title, title_ar, title_en) AGAINST ('exemple' IN NATURAL LANGUAGE MODE) as scor
FROM table
WHERE MATCH (title, title_ar, title_en) AGAINST ('exemple' IN NATURAL LANGUAGE MODE);
It gives me more results with same scores sorted in ascending. For me, I want to order it by id DESC, but I can't do that.
Basically, you want to order the results by scor and id in the case of ties. Untested code that will hopefully solve this for you:
SELECT *,
MATCH (title, title_ar, title_en) AGAINST ('exemple' IN NATURAL LANGUAGE MODE) as scor
FROM table
WHERE MATCH (title, title_ar, title_en) AGAINST ('exemple' IN NATURAL LANGUAGE MODE)
ORDER score DESC, id

Irrelevant results in mysql full text search

I have a Mysql table set up for full text search across both the title and the content (body) columns.
I'm trying to bring the most relevant results to the top but I get a lot of garbage.
I have 3 full text indexes, one for the title, one for the body and one for both the title and the body so I can execute the following query:
SELECT id, url, title, body, earliestCapture, responseYear, urlScore,
MATCH (title) AGAINST ("jurassic park" IN BOOLEAN MODE) AS titleScore,
MATCH (body) AGAINST ("jurassic park" IN BOOLEAN MODE) AS bodyScore,
(SELECT (titleScore * 100 + bodyScore)) AS finalscore
FROM Entries
WHERE MATCH (title,body) AGAINST ("jurassic park" IN BOOLEAN MODE)
ORDER BY finalScore DESC LIMIT 0,1000;
I'm trying to multiply the score of the title by 100 to bring instances where the term is in the title to the top.
This does help, but if the body has the word park repeated many times even without the word Jurassic appearing a single time, that row is propelled to the top of the search results.
A great example of that is when I search for "intel pentium". There are a few rows with bodies that use the word intel in the context of intelligence/information and not the company name, that word is repeated hundreds of times and even though there are no instances of the word pentium, those pages are always on the top.
I'm getting really annoyed by this. Does anyone know how to improve the search results?
Thank you!
you ahev to add a + to both search terms so that only results are shown that have both see manual
SELECT id, url, title, body, earliestCapture, responseYear, urlScore,
MATCH (title) AGAINST ("+jurassic +park" IN BOOLEAN MODE) AS titleScore,
MATCH (body) AGAINST ("+jurassic +park" IN BOOLEAN MODE) AS bodyScore,
(SELECT (titleScore * 100 + bodyScore)) AS finalscore
FROM Entries
WHERE MATCH (title,body) AGAINST ("+jurassic +park" IN BOOLEAN MODE)
ORDER BY finalScore DESC LIMIT 0,1000;

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 get relevant search in mysql full text search?

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.

MYSQL fulltext - What's the right way to get the relevance from one column?

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?