I'm building a search on my site and I noticed it doesn't work when you enter more than one word into the search. Here's the gist of the query:
SELECT * FROM `blog` WHERE `content` LIKE '%$keyword%' OR `title` LIKE '%$keyword%' ORDER BY `id` DESC
The weird things is that when I test the query in phpMyAdmin it returns the expected results. On my website however, no results are found.
I tried replacing spaces in the keyword with %s, but that didn't change anything.
The problem is that LIKE does pattern matching rather than actually search for keywords. You should create a fulltext Index on your database columns and use WHERE MATCH keywords AGAINST column. That will properly search for all keywords in any order and be a lot faster anyway.
I just tried this in my database and using LIKE in the query is more than 66 times as fast than using MATCH with fulltext index. I'm using two tables which are "connected" to each other. One is tags and the other one is products.
So what I did was that I added a fulltext index to the tag column in the tags table and performed the match against that column. The query than joins the products and then spits out some data about the item. That took about 4 seconds with ~3000 products & ~3000 tags.
I then tried it by first exploding the search string by whitespaces, and then imploding the result with %' OR tags.tag LIKE '%. This took about 0,06 seconds with the same amount of products and tags.
Related
I am querying a MySQL table, and want it only to output items that match the word but can have other words as well. I am sort of looking for the equivalence of in MySql.
strpos ( string $haystack , string $needle)
PHP myAdmin TABLE Here is an image of my phpMyAdmin table. I am trying to search the table if the rightmost column, the archetype column. I am trying to find all results that match one word like Voltron, but the problem is that for example item #11, also has the word 'Keyword' in that column so it won't show.
Image I'm Searching By This is an example of what I want to search by. The last column, the archetype column is the variable. I want to query MySQL for all items that were Archetype like Tribal, or like Voltron, but can contain other 'Archetypes' as well.
When I query by this card, item number 3,9,10,11, and 15 should be outputted.
$aType = explode(" ", $aType);
$array_in_strings = join(", ",$aType);
//This Decides the Cards.
$query_all_items = mysqli_query($connect, "SELECT * FROM `edh__cardDatabase` WHERE `name` NOT LIKE '$name' AND (`archetype`) IN ('$array_in_strings') ORDER BY `name` ASC;");
And finally, this is what I have as the code.
Implode your words list to CSV string then use a query similar to
SELECT *
FROM {tablename}
WHERE FIND_IN_SET({columnname}, 'CSV,words,list')
AND {another conditions}
Pay attention - if you put a space between a comma and the next word then this space will be treated as a part of a word. I.e. 'word' will be found in 'this,is,a,word' but not found in 'this, is, a, word'.
Hello everyone as the topic says I am looking for alternative or advanced using of "LIKE".
I have column which contains a row of words p.e. "keyword1,keyword2,another_keyword" and when I use
$sql = mysql_query("SELECT * FROM table WHERE `column` LIKE '%keyword1%' ");
It hardly find it p.e. this example works but when i try to find shorter strings it has problems and sometimes it does not find anything.
I tried put a whitespace after comas and it helped but if there is a way where I can search for match with this specification of column I would be happy.
You may move keywords into individual table.
Or you can use SET field type, if the list of your keywords don't change.
Storing comma separated list of your words is a bad idea example using like in your scenario is hard to find the exact work in comma separated list instead you can add new table which relates to your current table and store each the word in a new row with the associated identity like
table1
id title
1 test1
2 test2
kewords_table
table1_id word
1 word1
1 word2
1 word3
and query will be
select t.*
from table1 t
join kewords_table k
on(t.id = k.table1_id)
where k.word = 'your_keyword'
If you can't alter your structure you can use find_in_set()
SELECT * FROM table WHERE find_in_set('your_keyword',`column`) > 0
try something like this:
SELECT * FROM tablename
WHERE column LIKE '%keyword1%'
OR column LIKE '%keyword2%';
for more info see here:Using SQL LIKE and IN together
MySQL allows you to perform a full-text search based on very complex queries in the Boolean mode along with Boolean operators. This is why the full-text search in Boolean mode is suitable for experienced users.
First You have to add FULLTEXT index to that perticuler column :
ALTER TABLE table_name ADD search_column TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, ADD FULLTEXT search_column (search_column);
Run following query for searching :
SELECT * FROM table WHERE MATCH(search_column) AGAINST("keyword1")
for more info see here : https://dev.mysql.com/doc/refman/8.0/en/fulltext-boolean.html
I have a table that contains 3 text fields, and an ID one.
The table exists solely to get collection of ID's of posts based on relevance of a user search.
Problem is I lack the Einsteinian intellect necessary to warp the SQL continuum to get the desired results -
SELECT `id` FROM `wp_ss_images` WHERE `keywords` LIKE '%cute%' OR `title` LIKE '%cute%' OR `content` LIKE '%cute%'
Is this really enough to get a relevant-to-least-relevant list, or is there a better way?
Minding of course databases could be up to 20k rows, I want to keep it efficient.
Here is an update - I've gone the fulltext route -
EXAMPLE:
SELECT `id` FROM `wp_ss_images` WHERE MATCH (`keywords`,`title`,`content`) AGAINST ('+cute +dog' IN BOOLEAN MODE);
However it seems to be just grabbing all entries with any of the words. How can I refine this to show relevance by occurances?
To get a list of results based on the relevance of the number of occurrences of keywords in each field (meaning cute appears in all three fields first, then in 2 of the fields, etc.), you could do something like this:
SELECT id
FROM (
SELECT id,
(keywords LIKE '%cute%') + (title LIKE '%cute%') + (content LIKE '%cute%') total
FROM wp_ss_images
) t
WHERE total > 0
ORDER BY total DESC
SQL Fiddle Demo
You could concatenate the fields which will be better than searching them individually
SELECT `id` FROM `wp_ss_images` WHERE CONCAT(`keywords`,`title`,`content`) LIKE '%cute%'
This doesn't help with the 'greatest to least' part of your question though.
Like when the user writes the article title in the input field, I want to search existing articles to see if there are similar ones.
For eg.
SQL search query like stackoverflow
I want to find the most relevant articles related to this title.
I know it's something like:
WHERE article_title LIKE 'word'
but how do I handle multiple keywords?
Use a fulltext index, which'd be something like:
SELECT ... FROM ... WHERE MATCH (fieldname) AGAINST ('keyword keyword keyword');
Or hack up the query to look like
SELECT ... FROM ... WHERE (fieldname LIKE '%keyword%' OR fieldname LIKE '%keyword%' etc...)
Of the two, the fulltext version will be faster, as it can use an index. The 'LIKE %...% version will be very expensive, as wildcard search of that sort cannot use indexes at all. The downside is that fulltext indexes are only available on MyISAM tables, and will probably never be available for InnoDB tables.
You need to have full text search for that.
Make sure you are using MyISAM as the engine for the table you want to search on.
Have the following table
Table articles
--------------
id integer autoincrement PK
title varchar(255) with fulltext index
contents textblob with fulltext index
And use a query like:
SELECT id
, MATCH(title, contents) AGAINST ('$title_of_article_thats_being_edited')
as relevance
FROM articles
WHERE MATCH(title, contents) AGAINST ('$title_of_article_thats_being_edited')
ORDER BY relevance
Note that SO refines the list when you enter tags.
WHERE article_title LIKE '%word1%word2%'
will return all rows in which article_title contains 'word1' and 'word2' in this particular order
What should I use, to search for a keyword with mysql ?
I have a word and in the query I have
wordless
something word something
someword some
else
other
wordother
thingword
I want to output everything that has the word inside it, but the output to be like first outputed rows to be that rows with word as first letter on them, for example
wordless - will be the first because word are first characters of the word wordless
and the wordother to be outputed to to the first outputed rows, then after them to output something word something and etc, every word that contains the name word, but again to output first that rows that have the word at the first characters.
EDIT:
SELECT *,MATCH(add_songName) AGAINST('d' IN BOOLEAN MODE) asscoreFROM songs WHERE MATCH(add_songName) AGAINST('d') ORDER BYscoreDESC , Here i'm searching for d but it gives me an error -
Can't find FULLTEXT index matching the column list SELECT *,MATCH(add_songName) AGAINST('d' IN BOOLEAN MODE) as `score` FROM songs WHERE MATCH(add_songName) AGAINST('d') ORDER BY `score` DESC
Try to use Levenshtein algorithm in MySQL.
Levenshtein matching is a metric for measuring the amount of difference between two sequence, here it is strings. By default MySQL does not have this function, but you can write and add one.
Please take a look at the code here and add that code as a system function in MySQL, please see the example below on how to get the similarity of two strings.
Please see: https://github.com/rakesh-sankar/Tools/blob/master/MySQL/Levenshtein.txt
Example:
SELECT column1, LEVENSHTEIN(column1, 'matchme') AS perfectmatch FROM sometable ORDER BY perfectmatch DESC