MYSQL match keyword list Comma Delimited Text Field - php

I have a list of keywords in a field called 'keywords' in a MYSQL database For example the keywords field in the record contains 3 sample records
KEYWORD LIST 1: tree,apple,banana,cherry,flower,red apple,pink cherry,cat,mouse
KEYWORD LIST 2: cat,mouse,apple,red apple,flower,red appleberry
KEYWORD LIST 3: apple, red appleberry, flower
The keyword list is NOT an array - just a text field in a mysql database that has a lot of other fields.
When I run a MYSQL SELECT query from what I've seen 'so far' there are two ways: a) like %% b) match against
Let's say I want to run a query against the word 'apple'
SELECT * where keywords like '%apple%' from table
This would bring up the records that contain the word 'apple' including the record above but it wouldn't necessarily give me any sequence of higher or lower. I'd have to do do the filtering of the results post query.
Supposing I was more detailed in my query, and chose 'red apple' it would still show a match, but I wouldn't necessarily get have KEYWORD LIST 1 be more relevant than 2 or 3.
Someone suggested using the Match Against instead
SELECT *, MATCH(Keywords) AGAINST('apple') AS Score
FROM table
WHERE Keywords like '%red apple%'
ORDER BY score DESC;
This is certainly heading in the right direction - however will it won't sort the results by an exact match being found as more relevant. The relevancy would be based on how many repetitions of the word 'apple' appeared in the keyword list (this is the age old reason why all the search engines chose to ignore keywords altogether) - do you see where I'm going with this?
What I'm looking for is do process most of the logic in the MYSQL instead of reading it into an array and processing it in PHP as others have suggested. Hence this simplistic example.
Here's what the query ought to how it should be:
1) if my query is 'apple' Keyword list 1 should show up first
2) if my query is 'red apple' then Keyword list 2 should show up First because the word 'red apple' is CLOSER to the FRONT of the keyword list - closer to the beginning of the string.
BUT because of the LIKE %%
Keyword List 3 would show up even though the match was 'red appleberry' instead of 'red apple'
(It would be simplest if MySQL had some kind of 'explode' function that you could specify the comma (',') as the delimiter in the match but I don't know of any such method, do you? Of course you'd have to read the entire list of results into an array and then explode them in PHP.
3) Suppose I search for 'red apple' and here's the bug: I'd still have a match on 'red appleberry' (record 3) - I don't want that. Record 2 should show up and then Record 1 and not even show record 3.
This is a discussion and an inquiry. Anyone have any suggestions?
My OWN ANSWER:
include the comma in the query
instead of searching for 'red apple' search for 'red apple,'
but what if the user put a space between - or if its at the tail end of the list of keywords?
QUESTION:
How can we search for specific SCORE in a comma delimited text field in MYSQL that uses the exact word (not a fragment) to come up with an ORDERED list of results.
Every attempt on this so far will still have Keyword List 3 show up higher than 2 even though red appleberry and red apple are two different phrases separated by commas.
Thanks! Let's discuss!

For small project, you can do something like this
SELECT *,
case when keyword like '%red apple%' then 1 else 0 end exact_match,
MATCH(Keywords) AGAINST('apple') AS Score
FROM table
where keywords like '%apple%'
ORDER BY exact_match DESC, score DESC;

Related

PHP SQL Search query matching

I have a search page in PHP which uses the following query to fetch content from the database.
SELECT * FROM linkBase WHERE (`title` LIKE '%".$s."%') OR (`descr` LIKE '%".$s."%')
Here is how my DB looks like :
id |title |descr
-----------------------------------------
1 |Hello World |This is a hello world description
2 |PiedPiper |The silicon valley company PiedPiper
3 |StackOverflow |Ask questions on programming
Now, for example, if I run this query with the value of $s = "silicon valley", Then it fetches the row 2. This is fine. But what if the user enters the search term as silicon PiedPiper. It returns no results with the above SQL query. How can I modify the query in such a way that it will return row 2 with the second search term too.
Question summery :
How can I do a search query using PHP and SQL in such a way that a result will be returned even if the the user enters two words which are not placed consequent to each other in the DB
If you need to support an arbitrary order of the words in the search I suggest using the REGEXP MySQL function with a simple "or" regular expression like
SELECT * FROM linkBase WHERE (`title` REGEXP 'silicon|PiedPiper') OR (`descr` REGEXP 'silicon|PiedPiper')
so you can replace the whitespace with PHP and replace them with a pipe symbol (|) and the order of the words don't matter anymore.
This will select all rows that contain at least one of the words, if you need to match all words in the list another regular expression might be necessary.
LIKE '%{".$s."}%' or to be old school INSTR(title, '{'.$s.'}') > 0

Fetch more than one word in a column using the first letter only

Please I need a simple answer, thank you.
MY DATABASE -- I have a column with the name keywords. Inside I have a list of words that are keywords from a title (see example below)
column (title) --- all red apples / column (keywords) --- apple red tree
column (title) --- the apple fell / column (keywords) --- red leaf fell
So the title column has (the apple fell)
the keywords column has red leaf fell
- my first question is in mysql database, I need to know when entering more than one word inside a column do I need a comma or a space?
This answer will help me code correctly and I can go into my database and set it up correctly!
PHP CODING QUESTION - what I need to know is how to retrieve a word or words from my column keywords that start with the letter a inside those rows.
I would like all the words that start with the letter a from each keywords row to appear.
I can pull the first word apple using WHERE keywords LIKE('a%'), however I cannot get the second or other words after the first word listed under my keywords column.
SO EXAMPLE KEYWORDS ARE
keywords column row one ---- bell ring apple
keywords column row two ---- art words leaf
keywords column row three ---- books all read
I need all the words that start with the letter a from all three columns. Can anyone please give me a code that works with the WHERE clause on how to fetch the words starting with the letter a in all rows under the keywords column.
Thank you very much.
P.S. I have attached a picture on my keywords column. The keywords are different then listed here, but the request is still the same. keywords picture from my database
For get the word in keywords column use
SELECT * from <table> WHERE keywords LIKE ? ORDER BY keywords ASC
So if change ? with %A% give you a complete list with all the keywords that start with A.
this is an example with prepared statement
$term_sql = $conn->prepare(" SELECT * from table WHERE keywords LIKE ? ORDER BY keywords ASC");
$term_sql->bind_param('s', $key);

Find rows where column value is contained in input string

I have prepared a spreadsheet containing several entries, and each row of entry provides two columns of information. One is a product name, and another one is the price of the product. An Example is shown as follows:
Product (Column A) Price (Column B)
1. Watch $100
2. Mousepad $50
3. Notebook $1000
I am trying to create a web-based database with PHP and MYSQL. The basic searching function is that when I enter a sentence in a search box, such as "I have a watch and a notebook", those entries in my database matching some of the words in the sentence would be given (i.e. row 1 "Watch" and row 3 "Notebook"). Does MySQL support this kind of search, and how can I write the query to do so?
Writing an SQL query to do that would not be hard. All you need is to write a WHERE clause that searches for the column value inside your string. MySQL has a LOCATE() function you can use to search for substrings. In your example, you may have:
SELECT *
FROM myTable
WHERE LOCATE(product, 'I have a watch and a notebook.') <> 0;
It is important to note, as you'll see in the link, locate returns 0 if the substring is not found.
Here is an SQL Fiddle example.

Full text search to match multiple words in a string mysql

I am using fulltext search for search query. when i search two words i want exact two words match results. here problem is i am getting one word match results also. the data contains polish language characters.
My code is
$qry="select * from tbl_jobs where MATCH(job_title) AGAINST('+Młodszy +Konsultant' IN BOOLEAN MODE)";
I am getting results as
1. [job_title] => młodszy konsultant ds. sprzedaży
2. [job_title] => Młodszy Konsultant
3. [job_title] => Konsultant ds. sprzedaży młodszy
4. [job_title] => Telefoniczny konsultant
I have the following indexes
Here first 3 results are correct but 4th result is wrong. the job_title contains only one matching word results. I want two search words mandatory results set.
query is also correct i am using utf8_general. Where is exact problem please help me
If you have two words say abc and xyz to match and you want to match both then you can use wildcard % it will match just like regular expression matching
select * from mytable where job_title like '%abc%xyz%' or job_title like '%abc%xyz%'
It will give you the only records where job title contains both words abc and xyz
For full text searching, you can have a full detailed video here. Plus a tip for you
don't use " * " unless you want to retrieve the whole columns in a
table. Instead use the column qualified name like if there is a table
of students having a roll no then,
SELECT students.roll_no FROM students
Link for the tutorial btw!

PHP / MySQL sort item first if "word" is present, then the rest ASC?

I have a food database and I'm trying to implement a simple search that would put first items that are "raw" or "least processed".
For example, when I'm searching for "carrot", I really don't want to have to sort through all the processed food (carrot cake, etc), fast food (Wendy's carrot big mac, etc). I want the first items to be "carrots, raw", "carrot, boiled", "carrot frozen", "carrot, canned", etc.
Is there a way to do that in MYSQL so that I sort my items by "presence of keyword" first (let's say : "raw", "fresh", "boiled", "frozen"...) and then all other occurrences after?
Note :
the keyword may or may not be present
the keyword may be anywhere
I must also find the search keyword alone, in this example "carrot" so that "carrot cake" is still in my results.
Thanks a lot!
Joel
This might work for you:
SELECT * FROM foods
WHERE foods.title LIKE '%carrot%'
ORDER BY foods.title LIKE '%raw%' DESC, foods.title
The reason it's DESC is because that will return 0 or 1, and you want the results that returned 1 to be sorted first.
A natural word search returns records in order according to relevancy, so if you added a FULLTEXT index to the foods.title column, you could simply perform a search like this:
SELECT *
FROM foods
WHERE MATCH (title) AGAINST ('carrot raw fresh frozen canned')
AND title LIKE 'carrot%'
The additional LIKE criteria filters out results that don't have the word carrot at the beginning like 'fish, canned'.
FULLTEXT indexes can only be used with MyISAM tables currently, though soon (v5.6+) you can use them with InnoDB also.
Why not have and additional field called "processed" that stores a 1 if the food is processed. then just sort by processed and name.

Categories