|
| Udvikling af site search engine - ide Fra : Tommy Ipsen |
Dato : 26-08-04 13:25 |
|
Hej alle
I forbindelse med udvikling af et CMS system, kunne jeg godt tænke mig
at tilføje en søge-mulighed. Alle sider på sitet genereres vha. en
index.php fil, som vha. GET eller POST variable bestemmer, hvad der skal
"serveres for gæsten".
Da systemet benytter sig af templates (Smarty) vil der på et tidspunkt i
processen blive kompileret en ny template, hvis der har været ændringer
af indholdet på websitet som har indflydelse på den ønskede side -
ellers serveres den færdig-kompilerede template fra cachen.
Det jeg tænkte som løsning, var en indeksering af inholdsiderne i en
søgetabel - altså fjern alt overflødigt og skær det ned til ren tekst,
som gemmes i en tabel. Derudover så lave en ord-tabel og en url-tabel og
så linke alle disse sammen på en fornuftig måde.
Det vil i praksis være rimelig sjældent at templates rekompileres, så i
forbindelse med at dette sker, kunne man forestille sig at den aktuelle
side ved samme lejlighed blev reindekseret - dvs. et ekstra tidsforbrug
som går ud over den tilfældige besøgende på den side, men noget der vil
ske rimelig sjældent og ikke tage synderlig lang tid - det synes jeg
godt kan forsvares.
Der er så 3 delproblemer jeg godt kunne tænke mig, at have lidt bedre
styr på inden jeg går i gang med kodningen:
1. Når en template kompileres har jeg indholdet (inkl. div. html-tags,
scripts osv) i en streng - hvis denne skal renses for alt andet end
tekst er det så regulære expressions jeg skal ud i eller er der andre
hurtigere metoder og er der nogle ting jeg skal være opmærksom på i
dette led?
2. Indekseringen af siden i nogle søge-tabeller - hvordan skal
opbygningen af disse være for at få en fornuftig og rimelig fleksibel,
men samtidig hurtig tabelstruktur?
3. I selve søgningen vil jeg gerne understøtte boolske operatorer, så
det er muligt at søge på flere ord osv - jeg går næsten udfra, at punkt.
2 - altså selve opbygningen af tabelstrukturen nærmest giver mig
opbygningen af punkt 3.
Hvis I har nogle forslag, gode links til lidt dybere/avanceret
litteratur på nettet eller andre kommentarer, hører jeg dem gerne.
NB: Jeg er ikke interesseret i færdige scripts, søgeprogrammer der kan
installeres på serveren, eksterne services osv - jeg laver det selv i
php - jeg mangler "bare" en bedre forståelse af processen og problemerne
inden jeg kaster mig over programmeringen.
Mvh Tommy
| |
Thomas Lindgaard (27-08-2004)
| Kommentar Fra : Thomas Lindgaard |
Dato : 27-08-04 09:51 |
|
On Thu, 26 Aug 2004 14:25:22 +0200, Tommy Ipsen wrote:
[snip]
> 1. Når en template kompileres har jeg indholdet (inkl. div. html-tags,
> scripts osv) i en streng - hvis denne skal renses for alt andet end
> tekst er det så regulære expressions jeg skal ud i eller er der andre
> hurtigere metoder og er der nogle ting jeg skal være opmærksom på i
> dette led?
Kig på strip_tags(). F.eks.
$words = preg_split('_\s_', strtolower(strip_tags($html)));
Først fjernes tags, så konverteres til lowercase og til sidst splittes
strengen op efter whitespace.
Brugen af preg_split() er nok for simpel, da man så vil få en masse
"støj" i form af punktummer, kommaer, mv. Det kan man undgå ved at bruge
preg_match_all() - det kræver så bare et regulært udtryk, som fanger
det ønskede (dvs. dimser bestående af a-z, 0-9, danske tegn, ?).
En eller anden form for normalisering af ordene er heller ikke at foragte
- altså noget med at fjerne specielle karakterer (é, ö, ...) og andet.
> 2. Indekseringen af siden i nogle søge-tabeller - hvordan skal
> opbygningen af disse være for at få en fornuftig og rimelig fleksibel,
> men samtidig hurtig tabelstruktur?
Jeg lavede engang noget tilsvarende:
table Pages
id int
url text
table Words
id int
word text
table WordsInPage
word_id int
page_id int
Så kan du med en simpel forespørgsel finde alle de sider hvori et givent
ord forekommer:
SELECT page_id FROM WordsInPage LEFT JOIN Words ON
Words.id=WordsInPage.word_id WHERE Words.word='hejsa'
Man kan evt. krydre med en angivelse af hvor mange gange ordet forekommer
på den enkelte side og så rangordne sine søgesvar derefter.
Ovenstående giver en meget simpel søgning, men den finder siderne.
Alternativt kunne man være interesseret i at kunne søge på strenge som
f.eks. "hej med dig" - det vil så yderligere kræve at man har noteret
sig de enkelte ords "nummer", så man kan afgøre om de forekommer efter
hinanden på en given side.
> 3. I selve søgningen vil jeg gerne understøtte boolske operatorer, så
> det er muligt at søge på flere ord osv - jeg går næsten udfra, at
> punkt. 2 - altså selve opbygningen af tabelstrukturen nærmest giver
> mig opbygningen af punkt 3.
Mjaeh øhh - god fornøjelse :)
PS. SQL'en skal nok tages med et gran salt - den er skrevet frit fra
leveren og har aldrig hørt ordet "test".
--
Mvh.
/Thomas
| |
Tommy Ipsen (29-08-2004)
| Kommentar Fra : Tommy Ipsen |
Dato : 29-08-04 13:20 |
|
Thomas Lindgaard wrote:
>>1. Når en template kompileres har jeg indholdet (inkl. div. html-tags,
>>scripts osv) i en streng - hvis denne skal renses for alt andet end
>>tekst er det så regulære expressions jeg skal ud i eller er der andre
>>hurtigere metoder og er der nogle ting jeg skal være opmærksom på i
>>dette led?
>
> Kig på strip_tags(). F.eks.
>
> $words = preg_split('_\s_', strtolower(strip_tags($html)));
>
> Først fjernes tags, så konverteres til lowercase og til sidst splittes
> strengen op efter whitespace.
Den med whitespace er sød nok - dén kendte jeg ikke!
> Brugen af preg_split() er nok for simpel, da man så vil få en masse
> "støj" i form af punktummer, kommaer, mv. Det kan man undgå ved at bruge
> preg_match_all() - det kræver så bare et regulært udtryk, som fanger
> det ønskede (dvs. dimser bestående af a-z, 0-9, danske tegn, ?).
Ja - denne del skal man nok tænke lidt over, så man ikke sorterer for
meget væk!
> En eller anden form for normalisering af ordene er heller ikke at foragte
> - altså noget med at fjerne specielle karakterer (é, ö, ...) og andet.
Tjahh - her er jeg rimelig blank med hvordan jeg gør dét!
>>2. Indekseringen af siden i nogle søge-tabeller - hvordan skal
>>opbygningen af disse være for at få en fornuftig og rimelig fleksibel,
>>men samtidig hurtig tabelstruktur?
>
> Jeg lavede engang noget tilsvarende:
>
> table Pages
> id int
> url text
>
> table Words
> id int
> word text
>
> table WordsInPage
> word_id int
> page_id int
>
> Så kan du med en simpel forespørgsel finde alle de sider hvori et givent
> ord forekommer:
>
> SELECT page_id FROM WordsInPage LEFT JOIN Words ON
> Words.id=WordsInPage.word_id WHERE Words.word='hejsa'
>
> Man kan evt. krydre med en angivelse af hvor mange gange ordet forekommer
> på den enkelte side og så rangordne sine søgesvar derefter.
Fandt en tilsvarende opbygning på et af php-websites'ene - og den er
fornuftig så længe der søges på enkeltord!
> Ovenstående giver en meget simpel søgning, men den finder siderne.
> Alternativt kunne man være interesseret i at kunne søge på strenge som
> f.eks. "hej med dig" - det vil så yderligere kræve at man har noteret
> sig de enkelte ords "nummer", så man kan afgøre om de forekommer efter
> hinanden på en given side.
Ja - kan godt se det bliver mere bøvlet - overvejer også lidt om man
måske skulle kigge få fuldttekst søgning i mysql - det var måske heller
ikke dumt!
>>3. I selve søgningen vil jeg gerne understøtte boolske operatorer, så
>>det er muligt at søge på flere ord osv - jeg går næsten udfra, at
>>punkt. 2 - altså selve opbygningen af tabelstrukturen nærmest giver
>>mig opbygningen af punkt 3.
>
> Mjaeh øhh - god fornøjelse :)
Tror lidt jeg har noget af funktionaliteten vha. den opsplitning der er
lavet - det vil jeg lige undersøge.
> PS. SQL'en skal nok tages med et gran salt - den er skrevet frit fra
> leveren og har aldrig hørt ordet "test".
Det er fint - jeg skal nok finde ud af rette den til, hvis det er
nødvendigt.
| |
|
|