WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   Avancerad MySQL-sökning (https://www.wn.se/forum/showthread.php?t=25795)

oddholst 2007-12-20 15:30

Hej.

Jag håller på att skriva ett php-script som gör en sökning i en MySQL-databas.

Saken är att sökningen skall ske i flera fält och kan ske med flera sökord samtidigt.

Exempel:
Tabellen medlemmar:
Kod:

mnr  förnamn efternamn  adress      tfn
----------------------------------------------------------------
1    | Anders | Olsson  | Kufgränd 4  | 012345678
2    | Gustaf  | Andersson | Rusbacken 2A| 0701010101

- Om jag nu gör en sökning på ordet "anders" så kommer båda posterna att returneras.
- Om jag gör en sökning på "anders olsson" så returneras ingen post, fast det till fullo stämmer överens med mnr 1.

Som jag har gjort nu så gör jag så här:
- Delar upp söksträngen i alla sökorden.
- För varje sökord ställer jag en fråga med WHERE-villkoret "LIKE '%säkordet%'" för varje fält i medlemstabellen.
- Varje träff lägger jag in i en temporär tabell innehållandes mnr & träffar.
- Lista sedan endast de rader som har flest antal träffar.

Det är lite omständigt tycker jag, men finns det något lättare sätt att utföra denna operation på?
Kanske direkt i MySQL?
Förslag på metoder?

grazzy 2007-12-20 15:59

Det går nog att lösa med ett fulltext index med lite varierande resultat. Ett fulltext-index kan ligga över flera fält.

En alternativ lösning är ju att skriva en indexerare som tar alla ord (splitta på space, punkter etc) och spara i en separat tabell med rad-id + ordet. Sedan kan du köra jämförelse-sökningar i den tabellen med någon form av UNION-syntax tex.

Tänk på att du pajar din prestanda el grandioso genom att ha % innan keywordet i LIKE-sökningar (index kan inte användas alls). Att ha det i slutet går däremot bättre.

oddholst 2007-12-20 16:34

Citat:

Originally posted by grazzy@Dec 20 2007, 16:59

Tänk på att du pajar din prestanda el grandioso genom att ha % innan keywordet i LIKE-sökningar (index kan inte användas alls). Att ha det i slutet går däremot bättre.

Ojdå.. förklara gärna...

WizKid 2007-12-20 16:42

Finns en del att läsa på http://blog.c0la.se/blog/108

Försök tex leta upp alla i telefonkatalogen som har "son" i sitt efternamn. Det är omöjligt utan att kolla igenom alla namn. Däremot att hitta alla har ett efternamn som börjar med "son" är väldigt mycket lättare eftersom alla efternamn står i bokstavsordning.

grazzy 2007-12-20 16:51

Vet inte riktigt vad jag skall säga om den där blogglänken... men kortfattat kan man säga att det har med index att göra. Ett index klumpar ihop en tabell till ett hanterbart antal grupper (tex, om du har en namnlista så skulle man kunna ha 25 grupper, en för varje första bokstav i namnet).

Detta gör att när man söker efter ett namn kan man snabbt identifiera det första tecknet i sökningen och hitta motsvarande grupp, sedan gör man en "full" sökning i gruppen. Normalt sett så har ett index många sådana grupper eller flera nivåer, det beror på hur det är gjort. Som Wizkid säger så fungerar det då inte att söka på nånting i mitten eller slutet av ordet. Det är de första teckena som är de viktigaste.

Frej 2007-12-20 20:04

Fulltextindexering som gäller. Som tidigare sagts.

fabbe 2007-12-21 13:46

WHERE concat(förnamn,efternamn) LIKE '%säkordet%'"

borde lösa det, fast du får fundera om på om du vill ha procent med som de andra säger ;)

Edit: Eventuellt får du greja lite med några OR också, om det inte löser sig helt

martine 2007-12-21 15:33

Citat:

Originally posted by oddholst@Dec 20 2007, 16:30
- Om jag nu gör en sökning på ordet "anders" så kommer båda posterna att returneras.
- Om jag gör en sökning på "anders olsson" så returneras ingen post, fast det till fullo stämmer överens med mnr 1.

Varför kan du inte bara göra en sökning med

WHERE förnamn='Anders' AND efternamn='Olsson'

(alternativt via php bara på förnamnet om bara ett förnamn anges)?

Det ger en effektiv sökning utan LIKE, funktioner och onödiga fulltext-index… Ett enkelt index räcker då och de flesta anger sitt namn exakt som de tidigare sparat det ('Karl-Axel','von Greif', osv.) – ett fulltext-index lagrar ju bara annars en massa "von" osv.

oddholst 2007-12-23 08:36

Citat:

Originally posted by martine@Dec 21 2007, 16:33
Varför kan du inte bara göra en sökning med

WHERE förnamn='Anders' AND efternamn='Olsson'

(alternativt via php bara på förnamnet om bara ett förnamn anges)?

Det ger en effektiv sökning utan LIKE, funktioner och onödiga fulltext-index… Ett enkelt index räcker då och de flesta anger sitt namn exakt som de tidigare sparat det ('Karl-Axel','von Greif', osv.) – ett fulltext-index lagrar ju bara annars en massa "von" osv.

Det är ett antal fält sökningen skall göras i, fler än bara namnet, exempelvis adressfälten, telefonnummer, e-postadressen etc.

Den som gör sökningen vet kanske inte riktigt vad personen heter, utan vet kanske att han heter karlsson och bor i karlstad... då skall man kunna skriva "karlsson karlstad" och ändå kunna hitta.

Registret består av ca 2000 poster f n.

Det tycks råda delade meningar här om hurvida man skall använda fulltextsökningar eller inte... men om man inte skall använda min metod (temporär tabell) och inte skall använda fulltextsökning, så kommer sql-strängen att bli väldigt omfattande, där man måste kombinera de olika enskilda sökorden med sökning i samtliga fält...


Alla tider är GMT +2. Klockan är nu 06:21.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson