2

I'm trying to replicate the following LIKE query using a full text search on JSON data;

SELECT * FROM table
  WHERE response LIKE '%"prod_id": "foo"%'
  AND response LIKE '%"start_date": "2016-07-13"%'

In my database the above query returns 28 rows

This is my attempt:

SELECT * FROM table
  WHERE MATCH(response)
    AGAINST('+"\"prod_id\": \"foo\"",+"\"start_date\": \"2016-07-13\""')

However this returns over 4,500 rows (the same as running the first query for only the prod_id ~1,900 rows when running the first query on just the date)

It was my understanding that +"text here" would indicate a required word, and that literal double quotes (present in the JSON data) should be escaped, and that , would indicate a split between the two strings I'm looking for. What am I not understanding correctly? Is there any point in running this as a full text query anyway?

3
  • 2
    I think that you forgot to add the IN BOOLEAN MODE modifier to activate those boolean operators. The default modifier is IN NATURAL LANGUAGE MODE which doesn't suit your needs. Commented Apr 1, 2016 at 11:58
  • 1
    Thanks @Sevle that was certainly half the problem - the rest of my required tweaks are below. Commented Apr 1, 2016 at 14:32
  • This is not 5.7 JSON column! It's just a TEXT column where JSON stored as plain text. Commented Aug 13, 2018 at 4:10

1 Answer 1

3

Thanks to @Sevle I've tweaked my query like so, and it's returning the correct results;

SELECT * FROM table
  WHERE MATCH(response)
    AGAINST('+\"prod_id: foo\" +\"start_date: 2016-07-13\"' IN BOOLEAN MODE)

The comma was not helping and I was escaping the wrong characters, and of course I did need IN BOOLEAN MODE to be added. Finally, I removed the double quotes I was searching for in the JSON string.

It may also be worth noting that as I'm using PHP PDO to run this query I also had to make the following tweaks.

Instead of constructing the query like so trying to bind the variables like I normally would;

$query = $db->prepare('...AGAINST('+\"prod_id: :prod_id\" +\"start_date: :start_date\"');
$query->execute(array('prod_id' => 'foo', 'start_date' => '2016-07-13'));

I had to do this, as I found I could not bind variables in full text searches

$sql_against = $db->quote('...AGAINST('+\"prod_id: foo\" +\"start_date: 2016-07-13\"');
$query = $db->prepare("...AGAINST($sql_against IN BOOLEAN MODE)")
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.