Vraag & Antwoord

Webprogrammeren & scripting

[MySQL] Exacte fulltext search in MySQL

13 antwoorden
  • Hoi, ik maak gebruik van een FULLTEXT search in MySQL. Op zich werkt dat prima, alleen zoekt hij ook naar strings die enigzins overeenkomen (dat is ook vrij logisch eigenlijk). Als je bijvoorbeeld Noord-Holland als zoekterm gebruikt, selecteert MySQL ook Zuid-Holland. Maar wat ik nodig heb is een [b:76b526ce0c]exacte[/b:76b526ce0c] match. Dus als je op Noord-Holland zoekt, dat de database alléén die rijen selecteert die Noord-Holland bevatten. Dit is het voornaamste probleem. Verder heb ik nog een vraag met betrekking tot de FULLTEXT zoekfunctie: In mijn zoekformulier kan je meerdere velden invullen als zoekterm, en er zijn dus meerdere variabelen die worden doorgegeven. Met [code:1:76b526ce0c] (...) AGAINST('$trefwoord $plaats $provincie $opleiding' IN BOOLEAN MODE)"; [/code:1:76b526ce0c] werkt dat op zich goed, alleen maakt het niet uit of je in <INPUT type="text" name="[b:76b526ce0c]plaats[/b:76b526ce0c]"> een provincie invoert, je krijgt resultaten terug alsof je op provincie gezocht hebt. Hij zoekt dus op alle velden. Ik had liever gezien dat als je op plaats zoekt, dat hij in de database dan ook alleen in het veld 'plaats' zoekt, en dus niet in andere velden waar de zoekterm ook kan voorkomen. Maar hoe moet ik de query dan in elkaar zetten? En kan ik de resultaten dan ook nog beperken in tijd, met bijvoorbeeld BETWEEN NOW() AND '01-01-2005'? Ik hoop dat mijn vraagstelling een beetje duidelijk is zo, ik heb het idee dat het vrij moeilijk uit te leggen is wat ik bedoel :(
  • Niemand? :cry:
  • Ik heb nog nooit met de fulltext search van MySQL gebruikt, maar misschien dat ik je toch wat kan helpen. Allereerst: als je een exacte term van een input wil vergelijken met enkel en alleen één kolom in je tabel, waarom gebruik je dan een fulltext search en geen gewone select? Dit ontgaat me even... Ten tweede: helpt het misschien als je de variabelen die je meegeeft aan "AGAINST" ieder apart tussen aanhalingstekens zet? Zoals ik al zei, ik ken het verder niet, dus geen garanties bij dit "advies". ;) - Bas
  • [quote:8d997ef975="BasHamar"] Allereerst: als je een exacte term van een input wil vergelijken met enkel en alleen één kolom in je tabel, waarom gebruik je dan een fulltext search en geen gewone select? Dit ontgaat me even... [/quote:8d997ef975] Het is voor mij ook de eerste keer dat ik met fulltext werk. Maar in de tabel zijn ook kolommen waarop met minder exacte termen gezocht kan worden en waarbij de meest relevante termen bovenaan de zoekresultaten moeten komen. Fulltext leek me - na diverse websites geraadpleegd te hebben - hiervoor de meest geschikte oplossing [quote:8d997ef975="BasHamar"] Ten tweede: helpt het misschien als je de variabelen die je meegeeft aan "AGAINST" ieder apart tussen aanhalingstekens zet? [/quote:8d997ef975] Dat heb ik dacht ik al geprobeerd, maar dat maakte of geen verschil, of ik kreeg een foutmelding. Maar ik zal het nogmaals proberen :) In ieder geval erg bedankt voor je reactie! Overigens: voor een voorbeeld van het zoekscherm zie de [url=http://www.jobspoint.nl/2.0/index.php?page=search]website[/url] waarop hij moet komen. Edit: ik bedenk me nu net, is het misschien ook mogelijk om te combineren in de query, zodat je iets krijgt als: SELECT * FROM tabel WHERE MATCH(kolom) AGAINST ('zoekterm(en)' IN BOOLEAN MODE) AND WHERE provincie = 'provincie' AND WHERE plaats = 'plaats' Ik heb nu even heel weinig tijd, maar dat zal ik straks eens proberen :)
  • [quote:8f61762704="psychonetics"]ik maak gebruik van een FULLTEXT search in MySQL. Op zich werkt dat prima, alleen zoekt hij ook naar strings die enigzins overeenkomen (dat is ook vrij logisch eigenlijk). Als je bijvoorbeeld Noord-Holland als zoekterm gebruikt, selecteert MySQL ook Zuid-Holland. Maar wat ik nodig heb is een [b:8f61762704]exacte[/b:8f61762704] match. Dus als je op Noord-Holland zoekt, dat de database alléén die rijen selecteert die Noord-Holland bevatten. [/quote:8f61762704] Ik ben niet bekend met de FULLTEXT search van MySQL, dus ik heb even in de [url=http://dev.mysql.com/doc/mysql/en/fulltext-search.html]documentatie[/url] gekeken en daar kwam ik de volgende tekst tegen bij de user comments: [quote:8f61762704] Hyphen '-' characters break literals at the moment. A search for something like "GATA-D22S690" finds all entries containing GATA and not the full hyphenated text. The '-' character is treated as a word stop even within literals. The same is true if any of the special text search modifiers are used (eg +, -, ~) so that hyphenated literals are not correctly found with full text searches. [/quote:8f61762704] Dus het lijkt er op dat dat de oorzaak van je probleem is. Maar (gedachtespinsel ;)), je zou kunnen proberen om te zoeken op een phrase: [code:1:8f61762704]MATCH(...) AGAINST ('"noord-holland"' IN BOOLEAN MODE)[/code:1:8f61762704] [quote:8f61762704="psychonetics"]In mijn zoekformulier kan je meerdere velden invullen als zoekterm, en er zijn dus meerdere variabelen die worden doorgegeven. [...knip...] Ik had liever gezien dat als je op plaats zoekt, dat hij in de database dan ook alleen in het veld 'plaats' zoekt, en dus niet in andere velden waar de zoekterm ook kan voorkomen. Maar hoe moet ik de query dan in elkaar zetten? [/quote:8f61762704] Is het niet mogelijk om meerdere WHERE clauses aan elkaar te koppelen? [code:1:8f61762704] WHERE MATCH(a) AGAINST ('term1' IN BOOLEAN MODE) AND MATCH(b) AGAINST ('term2' IN BOOLEAN MODE) AND MATCH(c) AGAINST ('term3' IN BOOLEAN MODE) [/code:1:8f61762704] [quote:8f61762704="psychonetics"]En kan ik de resultaten dan ook nog beperken in tijd, met bijvoorbeeld BETWEEN NOW() AND '01-01-2005'?[/quote:8f61762704] Zie hierboven
  • Ik heb nu deze query geprobeerd: $sql = "SELECT * FROM `vacatures` WHERE MATCH(`naam`, `omschrijving`, `type`, `extra`) AGAINST ('$trefwoord' IN BOOLEAN MODE) AND MATCH(`functie`) AGAINST ('$functie' IN BOOLEAN MODE) AND MATCH(`plaats`) AGAINST ('$plaats' IN BOOLEAN MODE) AND MATCH(`opleiding`) AGAINST ('$opleiding' IN BOOLEAN MODE) AND `provincie` LIKE '$provincie_totaal' AND `branche` LIKE '$branche_totaal'"; Maar dan krijg ik nooit resultaten :S Ik was nog even vergeten te vertellen dat je meerdere provincies en branches kan selecteren, terwijl in de database maar 1 branche en 1 provincie staat. Maar als je Noord-Holland selecteert, dan moeten wel alleen díe resultaten worden opgehaald waarin Noord-Holland in de kolom staat en dus niet Zuid-Holland. :oops: Enig idee hoe ik dat kan oplossen?
  • [code:1:fe3a881ad0]$sql = "SELECT * FROM `vacatures` WHERE MATCH(`naam`, `omschrijving`, `type`, `extra`) AGAINST ('$trefwoord' IN BOOLEAN MODE) AND MATCH(`functie`) AGAINST ('$functie' IN BOOLEAN MODE) AND MATCH(`plaats`) AGAINST ('$plaats' IN BOOLEAN MODE) AND MATCH(`opleiding`) AGAINST ('$opleiding' IN BOOLEAN MODE) AND `provincie` IN '$provincie_totaal' AND `branche` IN'$branche_totaal'";[/code:1:fe3a881ad0]Het enige dat ik nu heb veranderd is "LIKE" vervangen door "IN". Na in komt altijd een lijst met toegestane waarden, gescheiden door een komma. Bij geavanceerde databases kan er ook nog een geneste query staan, maar volgens mij ondersteunt MySQL dat nog niet. - Bas
  • IN werkte ook niet, dan krijg ik een error. Ik probeer het nu zo te doen: [code:1:1c5f0ff6f9] if(!empty($provincie)) { $i = 0; foreach($provincie as $provincies) { if($i == 0) $sql_prov = "WHERE `provincie` = '" . $provincies . "'"; else $sql_prov .= "OR `provincie` = '" . $provincies . "'"; $i++; } } if(!empty($branche)) { $j = 0; foreach($branche as $branches) { if($j == 0) $sql_branche = "WHERE `branche` = '" . $branches . "'"; else $sql_branche .= "OR `branche` = '" . $branches . "'"; $j++; } } include_once('database.inc.php'); $obj = new database; $obj->connect(); $sql = "SELECT id FROM `vacatures` WHERE MATCH(`naam`, `omschrijving`, `type`, `extra`) AGAINST ('$trefwoord' IN BOOLEAN MODE) AND MATCH(`functie`) AGAINST ('$functie' IN BOOLEAN MODE) AND MATCH(`plaats`) AGAINST ('$plaats' IN BOOLEAN MODE) AND MATCH(`opleiding`) AGAINST ('$opleiding' IN BOOLEAN MODE) AND " . $sql_prov . " AND " . $sql_branche;[/code:1:1c5f0ff6f9] Ik denk dat dat er meer op lijkt. Als je meerdere provincies of branches zoekt, wordt je query dan AND WHERE kolomnaam = waarde 1 OR waarde 2 Neemt niet weg dat ik met bovenstaande code ook nog een error krijg ("You have an error in your SQL syntax...") :cry:
  • [code:1:d006a9106f]$sql = "SELECT * FROM 'vacatures' WHERE 'provincie' IN ('Zuid-Holland','Utrecht');"; [/code:1:d006a9106f]Werkt dit naar behoren, oftewel, Krijg je nu alle vacatures in Zuid-Holland en Utrecht? Anders moet ik toch mijn query-kennis gaan bijspijkeren... - Bas
  • [quote:6e59f86a63="BasHamar"][code:1:6e59f86a63]$sql = "SELECT * FROM 'vacatures' WHERE 'provincie' IN ('Zuid-Holland','Utrecht');"; [/code:1:6e59f86a63]Werkt dit naar behoren, oftewel, Krijg je nu alle vacatures in Zuid-Holland en Utrecht? Anders moet ik toch mijn query-kennis gaan bijspijkeren... [/quote:6e59f86a63] Met enige wijziging werkt dat wel (` ipv ', wordt dus: SELECT * FROM `vacatures` WHERE `provincie` IN ('Zuid-Holland','Utrecht'); ) Maar hoe kan ik dat dan inpassen als provincie een array is? De code die ik net gaf met $sql_prov en $sql_branche werkt nu enigzins (dat MATCH heb ik tijdelijk weggelaten, dat is als dit werkt), maar alleen als je én een provincie én een branche selecteert. Het moet ook mogelijk zijn om alleen een of meerdere provincies te selecteren of een of meerdere branches alleen. [b:6e59f86a63]EDIT:[/b:6e59f86a63] Mijn SQL-statement is nu zo: $sql = "SELECT * FROM `vacatures` WHERE " . $sql_prov. " AND " . $sql_branche; Die tellers voor $sql_prov en $sql_branche zijn niet gewijzigd. Hoe kan ik deze zo maken dat als er niks in wordt gevuld dat de AND wordt overgeslagen? En als je bij provincie niks invult, dat dan de sql wordt: SELECT * FROM `vacatures WHERE " . $sql_branche; Want zo te zien accepteert MySQL geen lege waarden voor WHERE `provincie` = ''
  • Uit het blote bolletje en in geen tijden iets met php gedaan, dus met een grote kans dat het niet werkt ;) [code:1:c63abc9b12] $sql = "SELECT a FROM b WHERE 1=1"; if (is_array($provincie)) { $sql .= " AND provincie IN ('" . join($provincie, "','") . "')"; } // enz.. [/code:1:c63abc9b12]
  • Dat werkt ook niet, Annie :-? Heb het geprobeerd hier en daar aan te passen, maar geen resultaat (enkel errors). Btw, wat betekent WHERE 1 = 1 in jouw syntax, of is dat gewoon een voorbeeldsyntax? Heb het namelijk wel vaker voorbij zien komen...
  • Tip: schrijf de gegenereerde query eens naar je scherm, ipv deze uit te voeren op de database. Daarmee kan je vaak zelf de syntax fouten eruit halen. "WHERE 1=1" betekent: voor alle gevallen waarin 1 gelijk is aan 1. Altijd dus :D . Een truukje om ervoor te zorgen dat alle andere, conditionele, uitbreidingen op de query met " AND" kunnen starten.

Beantwoord deze vraag

Weet jij het antwoord op deze vraag? Registreer of meld je aan met je account

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.