Want better search result in Mysql - mysql

I want to make my search result better, so for this i want that substring should also be matched.
For example..
In Mysql query when i search bag in product_name column as an output it give me 50 results but when i search bags in product_name it give me 20 results. But i want 50 results in second case also.
Select * from table where product_name like %bag%
Select * from table where product_name like %bags%
May be my question is duplicate but i didn't find any solution yet.

if you need to return all result whether the user enter plural or singular you can remove s or es from the keyword before search, but this way not accurate and you should make a complex function to loop all plural words rules. the best way to resolve this to help user enter 1 type in insertion process and display autocomplete if this entered before and avoid enter the same word you want to be the same twice into your database.

Related

MySQL query to check if this is same product

I'm working on price comparision program for 3 website. Each website can have same product with other websites but product name is not exactly same (EX: "Asus X553MA-XX102H Intel Celeron N2930 4GB 1TB DVDRW 15.6 Windows 8.1" and "Asus X553MA 15.6 Inch Intel Celeron 4GB 1TB Laptop" is one product but the name is not exactly same).
I was crawled data from 3 website to mysql table called crawledproduct(which has 3 columns: sourceurl, productname, price).
Please help me write a MySQL query command to find all same product by product name.
EX: Select * from crawledproduct where [Similar with 'Asus X553MA 15.6 Inch Intel Celeron 4GB 1TB Laptop']
Thanks for any help.
I am assuming that the name of the product is given as an input by the user itself or you know the product name which you wanna compare.
You need the 'LIKE' clause in your query. Suppose you want to search by the word 'axus':
Select name from crawledproduct
where productName like '%axus%'
% is called a wildcard. It tells the DBMS that you want to search for this pattern. Suppose you want to search for "axus" in each row in column A:
like '%axus' //This means give the rows which have entries in column A ending with axus
like 'axus%' //This means give the rows which have entries in column A starting with axus
like '%axus%' //This means give the rows which have entries in column A which contain the word axus.
Ofcourse, you need to enter the search term properly in order to get all the products. If a same product does not have the keyword that you specified, then it won't be displayed in your output. There are several other ways to search for a pattern in your database table.
You might wanna do a bit of a research on that, because I am a beginner and I don't have much knowledge yet.
Good luck!
Kudos! :)
If have a standard set of criteria that know will always appear in similar product names, you could use a like query to get what you need.
For instance, given your example a above, you can get it like this
Select name from crawledproduct
where name like '%X553MA%'
This would work. Note if you have a lot of data, this can result in very long queries, so you might want to take advantage of MySQL's fulltext searching which runs much faster. You would need to index name as a fulltext field, and then run a query like this:
SELECT name FROM crawledproduct MATCH(name) AGAINST ('X553MA')
Edit:
Note, both of these queries assume that X553MA will appear in all product names. You'd have to be careful about how you chose your search term.
Edit:
If you do not know the keyword, you could create a form which would search all three sites. The user could put in the keyword into this form.
For instance, using the like as mentioned, you could have each website's information stored in a database (assuming you have access to do so) each on a different table.
and search like so:
Select tableA.name
FROM TableA
JOIN TableB
ON TableB.name = TableA.name
JOIN TableC
ON TableC.name = TableA.name
WHERE name like '%$search_term%'
and you would have $search_term come from the user.
However if you are looking to actually crawl the site, then SQL is not the tool you want.

Count the number of times keywords (in a table) appear in a field in another table

I will simplify my problem in order to explain it.
I have a table which contains text messages posted by users and another table which contains keywords.
I want to display, for each user, the number of times keywords are found in text messages.
I don't want the result to display a keyword if it's not found in text messages.
I wan't it to be case INSENSITIVE. All keywords are lowered but in messages, you can find lower & upper chars.
Because I'm not sure that my explanation is clear enough, here comes the SQLFiddle.
http://sqlfiddle.com/#!2/c402a
Hope anyone can help me.
I found what I was looking for. It wasn't easy for me but here is my query :
SELECT t_msg.msg_usr,
t_list.list_word,
count(t_list.list_word),
t_msg.msg_text
FROM t_msg
INNER JOIN t_list
ON LOWER(t_msg.msg_text) LIKE CONCAT("%", t_list.list_word, "%")
GROUP BY t_msg.msg_usr, t_list.list_word;
The SQLFiddle is there : http://sqlfiddle.com/#!2/ba052/8
The recommendation would be to not try solving this with a query. It's possible to write a query that will do it, such query will scan the messages table for each keyword separately, and produce a count (or a row that you can group by), but this won't scale, or be reliable in sense of language search.
Here is what you might want to do:
Create a table to map (user_id, keyword_id) to a count of this keyword in messages of this user. Let's call it t_keyword_count.
Each time you receive a message, before you save the message into the database, search it for all the keywords you care about (using whatever good text search libraries that account for misspellings, etc.). You should know the (user_id) for this message.
You will, at that point, be ready to add the message to the database, and will have an array of (keyword_id) with keywords that this message will have.
In a transaction, insert the message into the t_msg table, and run update/insert for (user_id,keyword_id) to have value=value+1 (or +n, if you need to count the same keyword more than once in the same message) for the t_keyword_count table.
If you are trying to solve the problem of having to do the above on existing data, you can do this manually, just to build up that t_keyword_count table first (depends on how many keywords you have in total, but even if there are a lot, this can be scripted). But you should change (or mirror) the t_msg.msg_text field to be a field suitable for text search, and use SQL text search functionality to find the keywords.

MYSQL search fields method

Please help, I'm very confused about my situation.
I'm beginning to create a search function but I'm not sure the best way to go about it.
On the front-end users will be able to enter words in a text-field, then these will search the MYSQL database, something like below:
so they search for 'Adult' and every item_id (Primary Key) with 'Adult' in column 'name' is listed. Or they enter 'black' and every item_id with 'black' in 'colors' is listed. or they enter 'Adult Blue' and every item with either 'Adult' or Blue would come up. I'm sure you get the idea.
I've read up on multiple methods, but I can't figure out which is best:
Using a MANY TO ONE table: This seems like it would work, but there are over 500 unique items, so that would be thousands and thousands of rows. For item_id 1 I would have to make a row for 'Adult', a row for 'Denim', a row for 'Pants', a row for 'black', a row for 'red', a row for 'blue'. I might as well just hard code everything.
Using FIND_IN_SET: Is this going to work? Would I have to store the values with commas like Adult,Denim,Pants and also EXPLODE to separate the values? I was going to try this method but I keep reading that storing multiple values in a field is very bad practice.
Or are Regular Expressions what I'm looking for?
What is the best way to store the values, and what is the best way to retrieve them? I'm not asking for exact code, just the methods to use. Any advice is appreciated!
So, if we suppose that columns name and colors are the only columns we need to search through, I'd do the following (naive solution but will work fine if your DB doesn't have millions of rows and you don't have thousands of customers searching at once).
First, create a view
CREATE VIEW SearchHere AS
SELECT item_id, CONCAT(name, ' ', colors) AS FullDescription
FROM table
I don't know the name of the table in your screenshot, so I used table as its name.
Now, if a user searches for adult red pants you could issue a query
SELECT item_id
FROM SearchHere
WHERE FullDescription LIKE '%adult%'
AND FullDescription LIKE '%red%'
AND FullDescription LIKE '%pants%'
Of course, you'd need to generate the query on the fly but that's not an issue. You could play with using AND or OR and placing spaces in between the wildcrad symbol % and the search term. Probably you would also want to do the view in a more sophisticated way, e.g., do more tha just CONCAT.
A straightforward solution is to use
name REGEXP 'the|search|terms'
OR colors REGEXP 'the|search|terms'
You should explain what you mean by best, though -- fastest performance? easiest to maintain? other?

How to search a word in MySQL table? MATCH AGAINST or LIKE?

I have a table for some companies that may have many branches in different countries. These countries are inserted in countries field.
Now, I have to make a searching system that allows users to find companies that have any branch in a specific country.
My question is: Which one do I have to use ? MATCH AGAINST or LIKE ? The query must search all records to find complete matched items.
attention: Records may have different country name separated with a comma.
MATCH AGAINST clause is used in Full Text Search.
for this you need to create a full text index on search column countries.
full text index search is much faster than LIKE '%country%' serach.
I would change the implementation: having a field that contains multiple values is a bad idea, for example, it's difficult to maintain - how will you implement remove a country from a company ?.
I believe that a better approach would be to have a separate table companies_countries which will have two columns: company_id and country_id, and could have multiple lines per company.
You should use LIKE . Because as #Omesh mentioned MATCH AGAINST clause is used for Full Text Search.. And Full Text Search need entire column for search.

Ranking search keywords

Question is: How to rank keywords that have been used in search queries in my web application based on time and number of search?
A user types his search query in the text box. Via AJAX I need to return some suggestions to the user. These suggestions are based on number of search done for that keyword, and should be sorted by most recently searched.
For example if a user enters the search term as "hang" the suggestions should be in this order: "hangover part 2", "hangover".
How should I design the database to store the search queries?How should I write the sql query to get the suggestions?
For query suggestion a good way is to count the number of occurrences of each search query (it is probably better to not count repeated queries made by the same user). You'll have a file/table/something (query, count) like this:
"britney spears" 12
"kelly clarkson" 5
"billy joel" 27
"query abcdef" 2
"lady gaga" 39
...
Then you can sort by descending order of occurrence:
"lady gaga" 39
"billy joel" 27
"britney spears" 12
"lady xyz" 5
"query abcdef" 2
...
Then when someone is searching "lady", for example, do a prefix search on all strings from the top of the file/table/something to the bottom. If you only want K suggestions you'll go only until you find the Top-K suggestions.
You could implement this using a simple file, or you can also have a counting query table and do a query similar to:
SELECT q.query from (SELECT * from search_queries order by query_count DESC) as q where q.query LIKE "prefix%" LIMIT 0,K
Two notes:
There are better (and more difficult) ways of doing this. Amazon, for example, has a pretty nice query suggestion.
The provided solution will only suggest queries that starts with the user query. Like:
"lady" => ["lady gaga", "lady xyz"]
Query "lady" won't match "gaga lady". For them to match you will need query indexing, through the Full-Text Search support of your database or an external library such as Lucene.
Ideally, you'd sort on something like the following:
order by sum(# of searches / (how long ago that search was performed + 1))
This would have to be modified so that how long ago would be base on an appropriate base time. For example, if you want searches to count as half after a week, you'd make a week = 1.
This will clearly be inefficient, because calculating how long ago each search was performed for all search results will be time consuming. Thus, you might want to keep a running total for each search and multiply the totals by a certain value each time period. For example, if you want searches to count as half after a week, you would add one to that column for every search. Then, you would have a process that multiplies the search column by .5 every week. Then you just sort on that column.
Do you need something like autosuggestion? There is an JQuery plugin called autocomplete which only looks for similar words as soon as the user types in the letters. However, if you want to get the suggestions based on the number of times that keyword is searched by user, then you need to store the keywords in a separate table and then fetch it later for other user?