Avatar billede -thomas- Nybegynder
30. november 2003 - 21:50 Der er 31 kommentarer og
1 løsning

Full-text search og danske tegn

Er det muligt at bruge full-text search til at søge på ord, der indeholder danske tegn skrevet som ø osv.?

Hvis jeg søger på fx. ordet "sætte" finder den ikke noget, og hvis jeg replacer æ med æ i søgestrengen finder den en masse som ikke indeholder ordet. Er det nogen løsning på dette?
Avatar billede detox Nybegynder
30. november 2003 - 22:04 #1
Det bedste var jo nok at have de danske tegn stående i tabellen og så bruge htmlentities() på udtrækket.
Avatar billede -thomas- Nybegynder
30. november 2003 - 22:09 #2
Jeg har desværre ikke den mulighed at ændre på, hvad der står i tabellen - det står som æ, æ og å og ikke som æ, ø og å.

Jeg bruger i øvrigt asp - ikke php og henter ikke hele indholdet af tabellen ind, så søgningen skulle meget gerne udføres på mysql-nivaeu.
Avatar billede detox Nybegynder
30. november 2003 - 22:22 #3
Jeg har lige testet lidt og jeg har ikke problemer med at bruge fx: 'sætte' i en fulltext search. Men fulltext search finder jo ikke kun 100% matches, men også ord der ligner. Måske skal du bruge LIKE i stedet. Det virker også hos mig.
Avatar billede detox Nybegynder
30. november 2003 - 22:24 #4
altså: ...WHERE tekst LIKE '%sætte%'
Avatar billede -thomas- Nybegynder
01. december 2003 - 09:05 #5
Det virker også med æ osv. men den finder alt for mange sider, som slet ikke indeholder ordet, og det duer jo ikke. Kan du ikke prøve, om din gør det samme, hvis du har en tabel med mange record med data i?

Jeg ved godt, at jeg kan bruge LIKE '%sætte%', men så har jeg ikke de samme muligheder som med MATCH-funktionen i full-text search.
Avatar billede detox Nybegynder
01. december 2003 - 11:49 #6
Jeg har lige testet på en tabel med 215 records, hvor jeg lavede en testtabel med de samme data (blot med htmlentities). Når jeg eksempelvis søger på henholdsvis 'færreste' og 'færreste' i fulltext mode, får jeg 6 resultater i begge tilfælde (og de indeholder søgeordet). Så jeg kan ikke genskabe dit scenarie.
Avatar billede detox Nybegynder
01. december 2003 - 11:55 #7
Har du ændret nogle af fulltext parametrene i MySQL?
Avatar billede -thomas- Nybegynder
01. december 2003 - 12:23 #8
Indeholder dine felter æ, ø og å eller æ, æ og å når du tester?

Jeg har prøvet med LIKE og det virker som det skal. Hvis jeg søger på 'færreste' med full-text search, finder den 25 records, selvom ingen felter indeholder ordet. Med LIKE finder den ingenting.
Avatar billede detox Nybegynder
01. december 2003 - 12:28 #9
Ja, den ene tabel indeholder: æ, æ og å, den anden: æ, ø og å og både fulltext og LIKE virker i begge tilfælde. Hvordan ser din querystring ud?
Avatar billede -thomas- Nybegynder
01. december 2003 - 12:39 #10
Jeg har lige prøvet at lave en helt simpel søgning på formen direkte i MySQL Front:

SELECT id,MATCH (body) AGAINST ('færreste') FROM tabel;

Her finder den 25 records ud af 195, selvom ingen af dem indeholder hverken 'færreste' eller 'færreste'.

Hvordan kan det være?
Avatar billede -thomas- Nybegynder
01. december 2003 - 12:42 #11
Noget tyder på, at det er mit full-text index, den er gal med. Har lige prøvet at kopiere nogle af felterne, som blev fundet over i en anden tabel og her finder den ikke noget.
Jeg kigger lige nærmere på det...
Avatar billede detox Nybegynder
01. december 2003 - 12:42 #12
Måske du skal lave det sådan:

SELECT id, body FROM tabel WHERE MATCH body AGAINST ('færreste');
Avatar billede detox Nybegynder
01. december 2003 - 12:46 #13
Eller på den her måde:

SELECT id,MATCH (body) AGAINST ('færreste') FROM tabel WHERE MATCH body AGAINST ('færreste');
Avatar billede detox Nybegynder
01. december 2003 - 12:47 #14
Hvis den er gal med dit index, kan du prøve med:

REPAIR TABLE tabel QUICK;
Avatar billede detox Nybegynder
01. december 2003 - 12:51 #15
Jeg vil hvert fald mene du skal bruge en WHERE betingelse, hvis du vil begrænse dit udtræk til de relevante records.
Avatar billede -thomas- Nybegynder
01. december 2003 - 13:34 #16
Jeg har nu prøvet at indsnævre problemet, men er ikke rigtig blevet meget klogere... prøv følgende:

- Opret tabellen 'tabel': id (auto) og content (text)
- Opret et full-text index på content-feltet
- Opret tre records: 2 hvor content er blank og 1 hvor content er 'ø  æ'
- Kør 'SELECT id,MATCH (content) AGAINST ('færreste') FROM tabel;'

Det giver resultatet:
***********************
ID - content
1 - 0,67756324121582
2 - 0
3 - 0
***********************

Problemet er, at den finder feltet med 'ø  æ' selvom det ikke indeholder 'færreste'.

Hvad kan det skyldes?
Avatar billede -thomas- Nybegynder
01. december 2003 - 13:39 #17
12:42:22, 12:46:04, 12:51:17:
Jeg har også en WHERE på, når jeg laver selve søgningen.

Det jeg mente med "Her finder den 25 records ud af 195..." var, at i 25 ud af 195 records, gav MATCH (body) AGAINST ('færreste') et tal der var større end nul (= søgeordet fundet i record'en)´ og det er jo ikke meningen.
Avatar billede detox Nybegynder
01. december 2003 - 13:40 #18
Jeg vil umiddelbart tro at problemet skyldes at fulltext som default har en grænseværdi på 50% og 'æ' er netop 50% af 'færreste'.
Avatar billede detox Nybegynder
01. december 2003 - 13:44 #19
Læg også mærke til den lave værdi i 'content'. Når jeg søger på 'færreste' i min tabel får jeg:

id  Sand 
127 - 1.6463594782393
99  - 1.6040020052446
87  - 1.5587632509502
8  - 1.5505208576761
207 - 1.5412316383782
98  - 1.4595744026406
Avatar billede detox Nybegynder
01. december 2003 - 13:47 #20
Måske mine parametre er forskellige fra dine. Iflg. en "SHOW VARIABLES" forespørgsel viser mine ft-parametre:

ft_boolean_syntax + -><()~*:""&|
ft_min_word_len 4
ft_max_word_len 254
ft_max_word_len_for_sort 20
ft_stopword_file (built-in)
Avatar billede detox Nybegynder
01. december 2003 - 13:55 #21
Dit eksempel giver ganske vidst nøjagtigt det samme resultat hos mig:

1 0.67756324121582
2 0
3 0
Avatar billede detox Nybegynder
01. december 2003 - 14:16 #22
Du kan måske prøve at eksperimentere med BOOLEAN MODE. Fx:

SELECT id, MATCH(content) AGAINST('"f&aelig;rreste"' IN BOOLEAN MODE) FROM tabel

Vil kun matche eksakte resultater.
Avatar billede -thomas- Nybegynder
01. december 2003 - 14:48 #23
"Jeg vil umiddelbart tro at problemet skyldes at fulltext som default har en grænseværdi på 50% og '&aelig;' er netop 50% af 'f&aelig;rreste'.":
Er 50%-grænsen ikke hvis søgekriterierne er opfyldt i mere end 50% af records i tabellen. Det er de jo ikke her. Du kan også sagtens skrive en masse tekst i feltet og den vil søge forkert.´

"Læg også mærke til den lave værdi i 'content'":
Hvis jeg opretter tre nye tomme records, stiger resultatet til 1,573253125842.

"Måske mine parametre er forskellige fra dine."
Jeg har i samme værdier i SHOW VARIABLES som dig.

"Du kan måske prøve at eksperimentere med BOOLEAN MODE. "
Jeg brugte BOOLEAN MODE til at starte med - den giver også forkert resultat i samme eksempel: 1 istedet for 0.

Øv øv, andre ideer til hvad der går galt? Det virker fint hvis jeg skriver "færreste" i et af felterne og søger på 'færreste'.
Avatar billede detox Nybegynder
01. december 2003 - 14:55 #24
Jo, ved nærmere eftertanke har du ret i antagelsen omkring 50% af rækkerne.
Jeg testede dit eksempel med BOOLEAN MODE og det virker faktisk, men du skal huske enkelte og dobbelte anførselstegn, som mit eks.: 14:16:28.
Avatar billede -thomas- Nybegynder
01. december 2003 - 15:03 #25
Det er sgu lidt pinligt hvis fejlen skyldes en apostrof...

Men det ser umiddelbart ud til at virke fint med:
SELECT id, MATCH(content) AGAINST('"f&aelig;rreste"' IN BOOLEAN MODE) FROM tabel

til gengæld virker det så ikke med:

SELECT id, MATCH(content) AGAINST('"*f&aelig;rreste*"' IN BOOLEAN MODE) FROM tabel

hvis man kun søger på den del af et ord?
Avatar billede -thomas- Nybegynder
01. december 2003 - 15:09 #26
Men hvis jeg bruger dobbelte anførselstegn, vil jeg heller ikke kunne søge på flere ord, som ikke er skrevet i forlængelse af hinanden. Og jeg kan formentlig heller ikke kombinere det med *, + og - operatorerne m.v. Så er jeg vel egentlig helt tilbage til lige så godt kunne bruge LIKE, eller hvad?
Avatar billede detox Nybegynder
01. december 2003 - 15:16 #27
Ja, personligt bruger jeg LIKE i mine søgninger, fordi den kan tilrettes mere præcist til mine behov og så er den hurtigere og mindre resourcekrævende. Måske bliver fulltext bedre i kommende versioner af MySQL, men som den er nu foretrækker jeg LIKE.
Avatar billede -thomas- Nybegynder
01. december 2003 - 15:20 #28
Ja, konklusionen må jo så være, at det faktisk ikke kan lave sig gøre... Så må jeg jo bruge LIKE istedet og undvære full-text-funktionerne. Så hvis en bruger søger på mere end ét ord, bliver din sql;

"SELECT id FROM tabel WHERE body LIKE '%" & ord1 & "%' OR '%" & ord2 & "%' osv.?
Avatar billede detox Nybegynder
01. december 2003 - 15:30 #29
Nok nærmere:

"SELECT id FROM tabel WHERE body LIKE '%" & ord1 & "%' OR body LIKE '%" & ord2 & "%' osv...

Selve query'en vil jeg nok opbygge med en løkke, der i hvert gennemløb tilføjer de enkelte 'OR felt LIKE '% ord %'.
Avatar billede -thomas- Nybegynder
01. december 2003 - 15:52 #30
Ok, det prøver jeg at gøre istedet, når du det andet ikke kan lade sig gøre... smid lige et svar, så du kan få dine point. Tak for hjælpen.
Avatar billede detox Nybegynder
01. december 2003 - 15:56 #31
Ja ok, velbekommen. Ærgeligt jeg ikke kunne hjælpe mere.
Avatar billede -thomas- Nybegynder
01. december 2003 - 16:02 #32
Ja, synes nu det er mærkeligt, at de ikke har lavet noget, der kan klare dette - de må da have samme problem i sverige? Men tak for forsøget.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester