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
Related
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
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.
I write script for full-text search by descriptions of some objects. But I did not satisfied with default full-text search algorithm in boolean mode, so I try to modify it some way. I want to combine 3 several searches into one. First query I search for "exact phrase", second - all words of phrase present, third - at least one of words is present. And then return it by priority. I must do something like this:
SELECT
description,
MATCH(description) AGAINST ('"my search"' in boolean mode) FROM search
WHERE MATCH(description) AGAINST ('"my search"' in boolean mode)
UNION DISTINCT
SELECT
description,
MATCH(description) AGAINST ('+my +search' in boolean mode) FROM search
WHERE MATCH(description) AGAINST ('+my +search' in boolean mode)
UNION
SELECT
description,
MATCH(description) AGAINST ('my* search*' in boolean mode) FROM search
WHERE MATCH(description) AGAINST ('my* search*' in boolean mode)
As you can see, first block of rows will contain the most relevant results - exact phrase. Second block will contain less relevant rows, and third will contain all the rest.
But this query returns duplicated rows, in other words, row that exists in first block, can repeat again in second block, or third, even if I use UNION DISTINCT. But I want get global distinct set of rows for all three sub-selects. If row appears in first block, then it must not exist in seconds and third. How can I do this? Or may be you can give me more elegant solution for such kind of search?
OK re-read problem. Union all will give you all resutls, union should give you distinct results
Or you could just use
`Select distinct * from
(SELECT
description,
MATCH(description) AGAINST ('"my search"' in boolean mode) FROM search
WHERE MATCH(description) AGAINST ('"my search"' in boolean mode)
UNION DISTINCT
SELECT
description,
MATCH(description) AGAINST ('+my +search' in boolean mode) FROM search
WHERE MATCH(description) AGAINST ('+my +search' in boolean mode)
UNION
SELECT
description,
MATCH(description) AGAINST ('my* search*' in boolean mode) FROM search
WHERE MATCH(description) AGAINST ('my* search*' in boolean mode)) B`
I've heared alot of similar discussion but I havent seen a direct solution.
SELECT * FROM patient_db WHERE
MATCH ( Name, id_number ) AGAINST ('%$term%' IN BOOLEAN MODE);
Isn't there something simple around my '%$term%' I need to do to enable multiple-word searching?
Unfortunately, there is no way to directly say, "I want one of these n words" in a MySQL fulltext query. Your only real option is
SELECT * FROM patient_db WHERE
MATCH ( Name, id_number ) AGAINST ('%$term%' IN BOOLEAN MODE)
OR MATCH ( Name, id_number ) AGAINST ('%$term2%' IN BOOLEAN MODE)
OR MATCH ( Name, id_number ) AGAINST ('%$term3%' IN BOOLEAN MODE)
;
Just curious, but why are you searching a column named id_number for text?