Full text search to match multiple words in a string mysql - php

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!

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

MySql check for numbers

I'm struggling to write a SQL statement - Im basically trying to distinguish between postcodes by checking if there is a number after the first letter.
For example i could have records with BL1 as postcode or B12, and when i enter in the search 'B' i only want it to select the records that have a numerical value after it - then if i search BL obviously that would just be a 'BL%' select.
With it being var char as well i'm struggling with this one, also its MySql.
Is it possible to convert then check the second char then condition it in mySql?
Thanks
You can use a Regular Expression
SELECT *
FROM tableName
WHERE col REGEXP '^B[0-9]';
This matches only those values which start with B and have a digit next to it. If you want to expand the regex to also include alpha characters on second position you could do
WHERE col REGEXP '^B[0-9A-Za-z]';
Fiddle

MYSQL match keyword list Comma Delimited Text Field

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;

How MySQL does the fulltext search if I need to find two words that are not close each other

If I am using MySQL fulltext search to find term " ford fiesta ", and I am searching from the field that looks like this: "cars ford engines fiesta".
Is MySQL going to give me a result ? I do not want it to only find " ford fiesta " if these words are next to each other in the field that I am searching from, for example " cars ford fiesta engines ".
If MySQL is not going to give me a result by default, can I configure it to do so ( to match words if they are appearing anywhere in the text that I am searching from ), or is there any other way to achieve this ?
Thanks
Use REGEXP:
SELECT * FROM `table` where `field` REGEXP 'ford.*fiesta' = 1
It will return those records whose field field contains string that has words ford and fiesta with any string between them. REGEXP returns 1 on match and 0 if not matched.
Use like and then add wildcard parameters.
as such
SELECT * FROM table WHERE field LIKE '%ford fiesta%'
Maybe completely unrelated, but when I started to create a bit more complex search engines I started using a special Database for it.
Take a look at elasticSearch, once you get it up and running it is crazy simple to specify needs like yours.
Specially the query_string from ElasticSearch would fit your needs. You can even specify what fields you want to run the query on.
As I said, once you want to get over from a simple search to advanced search, MYSQL ain't the right one to do the job.
Cheers

PDO search query

PDO, I want to use a search query. I tried to use like query, using % on both front and end of search variable. but it search in between the words.
like if in database there is name Jhon Anderson and if i use search variable using LIKE %erson%, The query will get me the row which contains the above name.
But what i want is query should only search with starting alphabets so i tried the LIKE query with Jhon%, i got the desired result, but using this % in the end only works if search variable matches the starting of first word, but what about the word after the space?
I mean if i try Anderson% or Ander%, The query will not get me the result of this row as Anderson is the second word in the field Jhon Anderson after space.
So my question is how to search in the words after spaces, that if there starting alphabets match the search query.
I don't know if such kind of query exist or not, but i think it might be possible with some looping after using like query with wildcard '%'.$variable.'%' and after getting all the results unset the arrays or rows where search variable do not match with the first alphabet of the result.
Any ideas how to implement such kind of search.
Query right now i am using,
$stmt = $conn->prepare("SELECT ROOM, GUEST_NAME, GUEST_FIRST_NAME, CONFIRMATION_NO, DEPARTURE, PWD FROM RESERVATION_GENERAL_2 WHERE LOWER(GUEST_FIRST_NAME) LIKE ? OR LOWER(GUEST_NAME) LIKE ?");
$stmt->execute(array('%'.strtolower($searchFilter).'%','%'.strtolower($searchFilter).'%' ));
A bit dirty, but simple solution is to include the space in the search:
WHERE ' ' || Name LIKE '% Anderson%'
You see I added a space in front of Name, so it will also find the word if it is at the beginning of the string.
Alternatively, you can use REGEXP_LIKE, but then it is still a bit awkward, since Oracle doesn't have a word boundary expression in its regex engine. For a solution, see this answer

Categories