MYSQL LIKE,CONTAINS vraagje
Ik wil graag kunnen zoeken op de bedrijfsnaam op basis wat de eindgebruiker invoert.
IK heb een bedrijf genaamd Emtek Ergonomics.
Als ik zoek op Emtek vind die dit bedrijf wel maar als ik zoek op bijv: emtek-test of koekie-emtek vind die helemaal niets.
Welke functie zoekt gewoon op alles zodat die altijd kijkt of akarakters voorkomen in de hele string in de klom?
Toevoeging op 18/10/2017 13:31:40:
Hier vind ook niets op:
SELECT * FROM bedrijven WHERE LOCATE('emtek-ergonomics---bureaustoel-op-maat',bedrijfsnaam)
Maar dit vind die wel:
SELECT * FROM bedrijven WHERE LOCATE('emtek',bedrijfsnaam)
Quote:
Welke functie zoekt gewoon op alles zodat die altijd kijkt of akarakters voorkomen in de hele string in de klom?
De functie die je zelf schrijft ;-)
Hak je hele zoek-string in stukken ("woorden"), bijvoorbeeld met preg_split('/\\W+/',$search)
Vervolgens zoek je alle bedrijven die op tenminste van een van deze woorden een LIKE match heeft. Degene met de meeste matches (woorden) toon je bovenaan.
Wat je zou kunnen doen:
- volg de suggestie van @Rob op
- gebruik fulltext searches, dit houdt wel in dat je goed nadenkt over hoe je indexeert en hoe je dit opzet
- maak gebruik van externe oplossingen om text te indexeren
- verander de manier waarop je zoekt, introduceer bijvoorbeeld keywords/tags, en laat je zoekfunctionaliteit hier mee werken, of maak gebruik van een soort van Faceted Search waarbij je een collectie data steeds specifieker filtert
Rob Doemaarwat op 18/10/2017 14:09:07:
De functie die je zelf schrijft ;-)
Hak je hele zoek-string in stukken ("woorden"), bijvoorbeeld met preg_split('/\\W+/',$search)
Vervolgens zoek je alle bedrijven die op tenminste van een van deze woorden een LIKE match heeft. Degene met de meeste matches (woorden) toon je bovenaan.
Quote:
Welke functie zoekt gewoon op alles zodat die altijd kijkt of akarakters voorkomen in de hele string in de klom?
De functie die je zelf schrijft ;-)
Hak je hele zoek-string in stukken ("woorden"), bijvoorbeeld met preg_split('/\\W+/',$search)
Vervolgens zoek je alle bedrijven die op tenminste van een van deze woorden een LIKE match heeft. Degene met de meeste matches (woorden) toon je bovenaan.
Kan je hier een voorbeeld voor geven in code?
$input = "emtek-ergonomics---bureaustoel-op-maat"
Als iemand zoekt op iets wat spaties heb vervang ik deze al door "-" dus hier kan ik de woorden op splitten vermoed ik.
Hoe gaat dit er dan in de sql query uitzien?
Code (php)
1
2
3
2
3
select * from bedrijven
where bedrijfsnaam like "%foo%" or bedrijfsnaam like "%bar%"
order by if(bedrijfsnaam like "%foo%",0,1) + if(bedrijfsnaam like "%bar%",0,1)
where bedrijfsnaam like "%foo%" or bedrijfsnaam like "%bar%"
order by if(bedrijfsnaam like "%foo%",0,1) + if(bedrijfsnaam like "%bar%",0,1)
(je sorteert dus eigenlijk op de bedrijfsnaam met de laagste score = meeste matches)
Hoe hak ik mijn string netjes in stukken en kan ik deze eenvoudig in sql vergelijken.
Stel ik heb een lange string van: woord1-woord2-woord3-woord4 etc...
Ik kan natuurlijk niet in mijn mysql query 10x OR like zetten?
str_replace("-"," ",$string) geeft mij alle woorden los van elkaar maar hoe dan verder?
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
$where = $order = [];
foreach(preg_split('/\\W+/',$string) as $word){
$where[] = ...
$order[] = ...
}
$sql = '
select * from ...
where ' . implode(' or ',$where) . '
order by ' . implode('+',$order);
foreach(preg_split('/\\W+/',$string) as $word){
$where[] = ...
$order[] = ...
}
$sql = '
select * from ...
where ' . implode(' or ',$where) . '
order by ' . implode('+',$order);
Toevoeging op 18/10/2017 18:12:19:
Ter info: die preg_split('/\\W+/',$string) splitst de $string op karakters die *niet* "in een woord" zitten (let op: hoofdletter W). Met karakters die "in een woord" zitten bedoelt een regex a-z, A-Z, 0-9, en "_" (http://www.regular-expressions.info/shorthand.html). De $string zal dus in een array gebroken worden op alle tekens (1 of meer) die daar niet in zitten. Met $string = "bla-bla bla----bla * * bla" levert dit dus een array op met 5x "bla".
Gewijzigd op 18/10/2017 18:15:10 door Rob Doemaarwat
Bedankt voor de code, ik heb hem even getest maar denk dat ik wat fout doe:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</php
$where = $order = [];
foreach(preg_split('/\\W+/',$input) as $word)
{
$where[] = $word;
$order[] = $input;
}
$q = '
select * from bedrijven
where ' . implode(' or ',$where) . '
order by ' . implode('+',$order);
echo $q;
?>
$where = $order = [];
foreach(preg_split('/\\W+/',$input) as $word)
{
$where[] = $word;
$order[] = $input;
}
$q = '
select * from bedrijven
where ' . implode(' or ',$where) . '
order by ' . implode('+',$order);
echo $q;
?>
Resultaat: select * from bedrijven where emtek or ergonomics or bureaustoel or op or maat order by emtek-ergonomics---bureaustoel-op-maat+emtek-ergonomics---bureaustoel-op-maat+emtek-ergonomics---bureaustoel-op-maat+emtek-ergonomics---bureaustoel-op-maat+emtek-ergonomics---bureaustoel-op-maatUnknown column 'emtek' in 'where clause'
Is het bovenstaande niet precies wat fulltext searches doen, maar dan geïndexeerd? :p
Moet je als je full text search wilt gebruiken elke keer de tabel updaten of kan je eenmalig zeggen: ALTER TABLE bedrijven
ADD FULLTEXT(bedrijfsnaam)
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
if(
bedrijfsnaam LIKE "% foo %" OR
bedrijfsnaam LIKE "foo %" OR
bedrijfsnaam LIKE "% foo",
10,
if(bedrijfsnaam LIKE "%foo%",1,0)
)
bedrijfsnaam LIKE "% foo %" OR
bedrijfsnaam LIKE "foo %" OR
bedrijfsnaam LIKE "% foo",
10,
if(bedrijfsnaam LIKE "%foo%",1,0)
)
Gewijzigd op 19/10/2017 21:50:23 door Rob Doemaarwat