Kom ihåg mig?
Home Menu

Menu


Avancerad MySQL-sökning

Ämnesverktyg Visningsalternativ
Oläst 2007-12-20, 15:30 #1
oddholst oddholst är inte uppkopplad
Medlem
 
Reg.datum: Aug 2007
Inlägg: 127
oddholst oddholst är inte uppkopplad
Medlem
 
Reg.datum: Aug 2007
Inlägg: 127
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?
oddholst är inte uppkopplad   Svara med citatSvara med citat
Oläst 2007-12-20, 15:59 #2
grazzy grazzy är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Mar 2004
Inlägg: 3 471
grazzy grazzy är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Mar 2004
Inlägg: 3 471
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.
grazzy är inte uppkopplad   Svara med citatSvara med citat
Oläst 2007-12-20, 16:34 #3
oddholst oddholst är inte uppkopplad
Medlem
 
Reg.datum: Aug 2007
Inlägg: 127
oddholst oddholst är inte uppkopplad
Medlem
 
Reg.datum: Aug 2007
Inlägg: 127
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...
oddholst är inte uppkopplad   Svara med citatSvara med citat
Oläst 2007-12-20, 16:42 #4
WizKid WizKid är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Apr 2004
Inlägg: 618
WizKid WizKid är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Apr 2004
Inlägg: 618
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.
WizKid är inte uppkopplad   Svara med citatSvara med citat
Oläst 2007-12-20, 16:51 #5
grazzy grazzy är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Mar 2004
Inlägg: 3 471
grazzy grazzy är inte uppkopplad
Klarade millennium-buggen
 
Reg.datum: Mar 2004
Inlägg: 3 471
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.
grazzy är inte uppkopplad   Svara med citatSvara med citat
Oläst 2007-12-20, 20:04 #6
Frejs avatar
Frej Frej är inte uppkopplad
Flitig postare
 
Reg.datum: Jul 2004
Inlägg: 463
Frej Frej är inte uppkopplad
Flitig postare
Frejs avatar
 
Reg.datum: Jul 2004
Inlägg: 463
Fulltextindexering som gäller. Som tidigare sagts.
Frej är inte uppkopplad   Svara med citatSvara med citat
Oläst 2007-12-21, 13:46 #7
fabbe fabbe är inte uppkopplad
Nykomling
 
Reg.datum: Oct 2007
Inlägg: 5
fabbe fabbe är inte uppkopplad
Nykomling
 
Reg.datum: Oct 2007
Inlägg: 5
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
fabbe är inte uppkopplad   Svara med citatSvara med citat
Oläst 2007-12-21, 15:33 #8
martines avatar
martine martine är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Mar 2005
Inlägg: 767
martine martine är inte uppkopplad
Mycket flitig postare
martines avatar
 
Reg.datum: Mar 2005
Inlägg: 767
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.
martine är inte uppkopplad   Svara med citatSvara med citat
Oläst 2007-12-23, 08:36 #9
oddholst oddholst är inte uppkopplad
Medlem
 
Reg.datum: Aug 2007
Inlägg: 127
oddholst oddholst är inte uppkopplad
Medlem
 
Reg.datum: Aug 2007
Inlägg: 127
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...
oddholst är inte uppkopplad   Svara med citatSvara med citat
Svara


Aktiva användare som för närvarande tittar på det här ämnet: 1 (0 medlemmar och 1 gäster)
 

Regler för att posta
Du får inte posta nya ämnen
Du får inte posta svar
Du får inte posta bifogade filer
Du får inte redigera dina inlägg

BB-kod är
Smilies är
[IMG]-kod är
HTML-kod är av

Forumhopp


Alla tider är GMT +2. Klockan är nu 16:03.

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