PHP/MYSQL match against query - mysql

I am trying to run a match against query and it is not working. I created a full text index on the two fields. But am getting sql error right before word 'relationship". Here is sql:
"SELECT * FROM pages WHERE MATCH (shdescript,ldescript) AGAINST (romance, relationship)";
I have also tried just searching against shdescript and just searching against ldescript but get same error. Also I've tried searchstring without spaces. As far as I know, you are supposed to have the words of the searchstring separated by commas in parentheses. What am I doing wrong? Thanks.

Add quotes around your search string.

"SELECT * FROM pages WHERE MATCH (shdescript,ldescript) AGAINST ('romance', 'relationship')";
Also make sure you protect yourself against the nasty SQL injection threat, read more here.

Try quoting your string (i.e 'romance' and 'relationship')
SELECT * FROM pages WHERE MATCH (shdescript,ldescript) AGAINST ('romance', 'relationship')

I believe your AGAINST must be in quotes. From:
http://dev.mysql.com/doc/refman/4.1/en/fulltext-search.html#function_match
AGAINST takes a string to search for, and an optional modifier that
indicates what type of search to perform. The search string must be a
literal string, not a variable or a column name.

Related

SQL replace function with MATCH() AGAINST()

I would like to use the replace function inside a match function, to remove \n characters before it searches matching rows. Otherwise, for example, if the text is FULLTEXT\nsearch, and the search is search, it will not match.
Here is my query (simplified) :
SELECT * FROM messages WHERE MATCH(REPLACE(body,'\\n',' ')) AGAINST ('mysearch' IN BOOLEAN MODE)
But it throws an error...
[EDIT]
After #Shadow 's answer, I tried this :
SELECT * FROM (SELECT REPLACE(body,'\\n',' ') AS rb FROM messages) AS rbody WHERE MATCH(rb) AGAINST ('mysearch');
I think the idea is correct, but I get an error ERROR 1210 (HY000): Incorrect arguments to MATCH. I think this is because I didn't index the column rb (FULLTEXT INDEX (rb)), so the MATCH () AGAINST () operation won't work.
So I update my question : How can one index a column of a subquery
The answer is that you cannot dynamically remove \n character sequence within a match() call. As MySQL manual on match() says:
MATCH() takes a comma-separated list that names the columns to be searched.
You either have to store \n differently, not as a character sequence or you need to have a separate field in which these characters are already filtered out and this additional field is used for fulltext searches.
Actually, waiting for a better solution, I will just add a column raw_body to my table, where I will store the exact body (I won't escape it with real_sacpe_string, I will just manually replace " and ' by \" and \'), and I will prepare the query and bind the params. However, I don't know if it is secure enough against sqlinjection.
[UPDATE]
Actually I found out that I didn't even needed to manually escape quotes, since the prepared statement is enough to prevent sqli. So I think I will just keep this solution for the moment

search the inbetween string using sql query

In wp_postmeta table meta_value contains the value http/google.co.in/
If the user searches for http/google.co.in/testing, then the resultset should contain http/google.co.in/
I tried with following query:
SELECT * FROM wp_postmeta WHERE meta_value LIKE '%http/google.co.in/testing%'
but it did not return the expected result.
How can i get the desired result? How can I use regular expressions to get this result?
if you use sql: .....LIKE '%http/google.co.in/testing%', then DB will look for any string containing "http/google.co.in/testing". Note that your desired result does not contain "testing" inside.
Let's try:
SELECT * FROM wp_postmeta WHERE meta_value LIKE CONCAT('%', SUBSTR('http/google.co.in/testing', 1, 18), '%')
this '%http/google.co.in/testing%' means you are looking for any string that contains 'http/google.co.in/testing' so 'http/google.co.in/' won't return any result because it doesn't contain the string you are looking for.
You can use SUBSTR() to search for a part your string.
As others have pointed out, LIKE searches for strings containing the entire search string (plus any other strings where the %s are), not strings containing a substring of your string. I don't know if there is such a command.
You suggested perhaps regex is your answer. MySQL does in fact have a regex command, which a quick Google search would show you the documentation for here: http://dev.mysql.com/doc/refman/5.7/en/regexp.html
Do you need further help determining your regex, or is this enough?
If you want further help, you'll have to clarify exactly what regex would be searching for, because you'd have to understand the components of your search string to know what will be constant and what will be variable.

Mysql, dealing with String Regex

I'm developing a Java desktop application that connects with a database, and I would like to know the next. It results that as far as I know, Prepared Statements avoid SQL injections while you don't make a direct concatenation with user data, but today I figured out that it doesn't escape String regex (like '%' from the LIKE operator,) due that it just escapes characters that could break up the String itself and alter the query. So, if user does:
Search = "%Dogs"; // User input
Query = "SELECT * FROM Table WHERE Field LIKE ?";
blah.setString(1, Search);
It will return all the rows that contains 'Dogs' at the beginning by injection.
Now I ask:
1-) Is this something bad / dangerous viewing from a global point?
2-) Is there a full list of Regex that Mysql could use from inside a String? if so, can you please share it with me?
Thank you.
If the user uses such meta characters in their search, the results may or may not be catastrophic, but a search for %% could be bad. A valid search for %Dogs may also not return the results the user was expecting which affects their experience.
LIKE only offers two meta characters, so you can escape them both on your own when acquired from users (simply using something akin to Search = Search.replaceAll("%", "\\\\%")).

Using MySQL LIKE operator for fields encoded in JSON

I've been trying to get a table row with this query:
SELECT * FROM `table` WHERE `field` LIKE "%\u0435\u0442\u043e\u0442%"
Field itself:
Field
--------------------------------------------------------------------
\u0435\u0442\u043e\u0442 \u0442\u0435\u043a\u0441\u0442 \u043d\u0430
Although I can't seem to get it working properly.
I've already tried experimenting with the backslash character:
LIKE "%\\u0435\\u0442\\u043e\\u0442%"
LIKE "%\\\\u0435\\\\u0442\\\\u043e\\\\u0442%"
But none of them seems to work, as well.
I'd appreciate if someone could give a hint as to what I'm doing wrong.
Thanks in advance!
EDIT
Problem solved.
Solution: even after correcting the syntax of the query, it didn't return any results. After making the field BINARY the query started working.
As documented under String Comparison Functions:
Note
Because MySQL uses C escape syntax in strings (for example, “\n” to represent a newline character), you must double any “\” that you use in LIKE strings. For example, to search for “\n”, specify it as “\\n”. To search for “\”, specify it as “\\\\”; this is because the backslashes are stripped once by the parser and again when the pattern match is made, leaving a single backslash to be matched against.
Therefore:
SELECT * FROM `table` WHERE `field` LIKE '%\\\\u0435\\\\u0442\\\\u043e\\\\u0442%'
See it on sqlfiddle.
it can be useful for those who use PHP, and it works for me
$where[] = 'organizer_info LIKE(CONCAT("%", :organizer, "%"))';
$bind['organizer'] = str_replace('"', '', quotemeta(json_encode($orgNameString)));

Regexp MySql- Only strings containing two words

I have table with rows of strings.
I'd like to search for those strings that consists of only
two words.
I tried few ways with [[:space:]] etc but mysql was returning
three, four word strings also
try this:
select * from yourTable WHERE field REGEXP('^[[:alnum:]]+[[:blank:]]+[[:alnum:]]+$');
more details in link :
http://dev.mysql.com/doc/refman/5.1/en/regexp.html
^\w+\s\w+$ should do well.
Note; what I experience more often in the last days is that close to nobody uses the ^$-operators.
They are absolutely needed if you want to tell if a string starts or ends with something or want to match the string exactly, word for word, as you. "Normal" strings, like you used (I assume you used something like \w[:space]\w match in the string, what means that they also match if the condition is true anywhere within the string!
Keep that in mind and Regex will serve you well :)
REGEXP ('^[a-z0-9]*[[:space:]][a-z0-9]*$')