2016-04-01 9 views
1

Ich versuche, die folgende LIKE Abfrage mit einer Volltextsuche auf JSON Daten zu replizieren;MySQL Volltextsuche auf JSON-Daten

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

In meiner Datenbank die obige Abfrage gibt 28 Zeilen

Dies ist mein Versuch:

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

Doch diese gibt mehr als 4.500 Zeilen (das gleiche wie die erste Abfrage ausgeführt werden nur für die prod_id ~ 1.900 Zeilen, wenn die erste Abfrage nur auf das Datum ausgeführt wird)

Es war mein Verständnis, dass +"text here" würde ein erforderliches Wort anzeigen, und das literale doppelte Anführungszeichen (vorhanden in den JSON Daten) sollte maskiert werden, und das , würde eine Trennung zwischen den zwei Zeichenfolgen anzeigen, die ich suche. Was verstehe ich nicht richtig? Ist es sinnvoll, dies als Volltextabfrage auszuführen?

+2

fand ich denke, dass Sie die [IN BOOLEAN MODE] hinzuzufügen vergessen (https://dev.mysql.com/doc/refman /5.5/de/fulltext-boolean.html) Modifikator, um diese booleschen Operatoren zu aktivieren. Der Standardmodifikator ist [IN NATURAL LANGUAGE MODE] (http://dev.mysql.com/doc/refman/5.7/en/fulltext-natural-language.html), der nicht Ihren Anforderungen entspricht. – Sevle

+1

Dank @Sevle, das war sicherlich das halbe Problem - der Rest meiner erforderlichen Verbesserungen sind unten. – Novocaine

Antwort

1

Dank @Sevle habe ich meine Abfrage so optimiert, und es gibt die richtigen Ergebnisse zurück;

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

Das Komma hilft nicht, und ich war die falschen Zeichen zu entkommen, und natürlich habe ich IN BOOLEAN MODE hinzugefügt werden müssen. Schließlich entfernte ich die doppelten Anführungszeichen, nach denen ich in der Zeichenfolge JSON suchte.

Es kann auch erwähnenswert sein, dass, da ich PHP PDO verwende, um diese Abfrage auszuführen, musste ich auch die folgenden Verbesserungen vornehmen.

Anstatt die Abfrage so zu erstellen, versuche ich, die Variablen wie normalerweise zu binden;

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

Ich hatte dies zu tun, wie ich I could not bind variables in full test searches

$sql_against = $db->quote('...AGAINST('+\"prod_id: foo\" +\"start_date: 2016-07-13\"'); 
$query = $db->prepare("...AGAINST($sql_against IN BOOLEAN MODE)")